openyida 2026.9.21 → 2026.9.22-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/README.md +14 -20
  2. package/bin/yida.js +6 -11
  3. package/lib/app/app-list.js +3 -7
  4. package/lib/app/canvas-compile.js +12 -22
  5. package/lib/app/check-prd-completeness.js +0 -7
  6. package/lib/app/create-app.js +1 -4
  7. package/lib/app/create-form/args.js +12 -37
  8. package/lib/app/create-form/batch.js +11 -86
  9. package/lib/app/create-form.js +86 -193
  10. package/lib/app/create-page.js +17 -84
  11. package/lib/app/custom-theme.js +0 -11
  12. package/lib/app/form-field-validator.js +41 -26
  13. package/lib/app/form-open-guard.js +10 -97
  14. package/lib/app/get-form-config.js +0 -1
  15. package/lib/app/inline-css-guard.js +31 -1
  16. package/lib/app/services/form-compiler.js +4 -2
  17. package/lib/app/theme-from-design.js +41 -144
  18. package/lib/app/theme-presets.js +1 -1
  19. package/lib/app/update-app.js +13 -63
  20. package/lib/asset/ai-image.js +9 -59
  21. package/lib/asset/asset-cmd.js +7 -18
  22. package/lib/asset/asset-plan.js +9 -102
  23. package/lib/asset/asset-resolve.js +10 -55
  24. package/lib/asset/asset-status.js +4 -5
  25. package/lib/asset/host-capabilities.js +2 -11
  26. package/lib/asset/url-verify.js +4 -19
  27. package/lib/auth/dws-sync.js +148 -0
  28. package/lib/auth/token-auth.js +73 -9
  29. package/lib/auth/token-store.js +50 -0
  30. package/lib/connector/connector-test.js +5 -19
  31. package/lib/connector/contract.js +1 -3
  32. package/lib/core/agent-capabilities.js +16 -19
  33. package/lib/core/command-manifest.js +40 -329
  34. package/lib/core/locales/en.js +17 -74
  35. package/lib/core/locales/zh.js +16 -73
  36. package/lib/core/redact.js +10 -15
  37. package/lib/core/sample.js +30 -72
  38. package/lib/core/utils.js +4 -0
  39. package/lib/design-plan/design-plan.js +4 -51
  40. package/lib/design-plan/init.js +26 -121
  41. package/lib/design-plan/materialize.js +348 -451
  42. package/lib/design-plan/normalize.js +29 -74
  43. package/lib/design-plan/parallel.js +16 -71
  44. package/lib/design-plan/patch.js +16 -63
  45. package/lib/design-plan/preview.js +8 -6
  46. package/lib/design-plan/validate.js +11 -71
  47. package/lib/process/create-process.js +50 -84
  48. package/lib/samples/openyida-scaffold/canvas-form-drawer.canvas.jsx +90 -20
  49. package/lib/samples/openyida-scaffold/canvas-nav/content.jsx +13 -93
  50. package/lib/samples/openyida-scaffold/canvas-nav/data.jsx +18 -100
  51. package/lib/samples/openyida-scaffold/canvas-nav/mixed.jsx +4 -6
  52. package/lib/samples/openyida-scaffold/canvas-nav/shared.jsx +5 -5
  53. package/lib/samples/openyida-scaffold/canvas-nav/side.jsx +2 -1
  54. package/lib/samples/openyida-scaffold/canvas-nav/sidebar.jsx +1 -1
  55. package/lib/samples/openyida-scaffold/canvas-nav/top.jsx +9 -15
  56. package/lib/samples/yida-canvas-table-form/table-form-batch-submit.canvas.jsx +83 -9
  57. package/lib/samples/yida-rechart/trend-combo.canvas.jsx +87 -14
  58. package/package.json +1 -3
  59. package/scripts/postinstall.js +3 -3
  60. package/yida-skills/SKILL.md +16 -19
  61. package/yida-skills/references/official-example-schema-patterns.md +1 -1
  62. package/yida-skills/references/yida-api.md +0 -4
  63. package/yida-skills/skills/yida-app/SKILL.md +23 -46
  64. package/yida-skills/skills/yida-app/workflow/parallel-work.md +6 -15
  65. package/yida-skills/skills/yida-app/workflow/plan/step-1-understand.md +1 -1
  66. package/yida-skills/skills/yida-app/workflow/plan/step-2-confirm.md +1 -1
  67. package/yida-skills/skills/yida-app/workflow/plan/step-4-deliver.md +15 -29
  68. package/yida-skills/skills/yida-app/workflow/plan/workflow.md +11 -29
  69. package/yida-skills/skills/yida-app/workflow/step-1-resource-context.md +2 -4
  70. package/yida-skills/skills/yida-app/workflow/step-2-design.md +9 -23
  71. package/yida-skills/skills/yida-app/workflow/step-3-create-or-reuse-app.md +4 -6
  72. package/yida-skills/skills/yida-app/workflow/step-4-forms-processes.md +4 -15
  73. package/yida-skills/skills/yida-app/workflow/step-6-main-page.md +4 -6
  74. package/yida-skills/skills/yida-app/workflow/step-7-page-code.md +9 -15
  75. package/yida-skills/skills/yida-app/workflow/step-8-publish-navigation.md +11 -25
  76. package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +28 -68
  77. package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +43 -42
  78. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-style-implementation-guide.md +44 -60
  79. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-theme-provider.md +50 -72
  80. package/yida-skills/skills/yida-canvas-custom-page/references/component-library-guide.md +1 -13
  81. package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +1 -140
  82. package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +72 -101
  83. package/yida-skills/skills/yida-canvas-custom-page/references/page-generation-guide.md +32 -35
  84. package/yida-skills/skills/yida-canvas-custom-page/scripts/build-canvas-theme.js +3 -29
  85. package/yida-skills/skills/yida-canvas-custom-page/scripts/canvas-theme-provider.template.jsx +6 -69
  86. package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +0 -26
  87. package/yida-skills/skills/yida-create-app/SKILL.md +0 -2
  88. package/yida-skills/skills/yida-create-form-page/SKILL.md +58 -72
  89. package/yida-skills/skills/yida-create-form-page/references/advanced-form-modes.md +5 -5
  90. package/yida-skills/skills/yida-create-form-page/references/association-form-field.md +4 -4
  91. package/yida-skills/skills/yida-create-form-page/references/batch-forms.md +5 -6
  92. package/yida-skills/skills/yida-create-form-page/references/field-definition-guide.md +19 -7
  93. package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +44 -62
  94. package/yida-skills/skills/yida-create-page/SKILL.md +6 -14
  95. package/yida-skills/skills/yida-create-process/SKILL.md +2 -13
  96. package/yida-skills/skills/yida-custom-page/SKILL.md +0 -2
  97. package/yida-skills/skills/yida-custom-page/references/design-system.md +1 -1
  98. package/yida-skills/skills/yida-dashboard/SKILL.md +4 -5
  99. package/yida-skills/skills/yida-data-management/SKILL.md +2 -4
  100. package/yida-skills/skills/yida-data-management/references/data-format-guide.md +4 -4
  101. package/yida-skills/skills/yida-design/SKILL.md +14 -29
  102. package/yida-skills/skills/yida-design/references/app/blueprint.md +70 -0
  103. package/yida-skills/skills/yida-design/references/app/navigation-patterns.md +43 -0
  104. package/yida-skills/skills/yida-design/references/app/role-journey.md +30 -0
  105. package/yida-skills/skills/yida-design/references/ask-human-interaction-contract.md +42 -67
  106. package/yida-skills/skills/yida-design/references/asset-workflow.md +2 -6
  107. package/yida-skills/skills/yida-design/references/design-mode.md +4 -4
  108. package/yida-skills/skills/yida-design/references/page-quality-gates.md +38 -26
  109. package/yida-skills/skills/yida-design/references/style-design-selection.md +137 -0
  110. package/yida-skills/skills/yida-design/references/style-designs/_design-md-template.md +185 -0
  111. package/yida-skills/skills/yida-design/references/style-designs/aqua-service-progress-dashboard.md +242 -0
  112. package/yida-skills/skills/yida-design/references/style-designs/blue-insight-operations-dashboard.md +243 -0
  113. package/yida-skills/skills/yida-design/references/style-designs/blue-productivity-insight-workbench.md +242 -0
  114. package/yida-skills/skills/yida-design/references/style-designs/command-filter-card-console.md +304 -0
  115. package/yida-skills/skills/yida-design/references/style-designs/contrast-command-analytics-workbench.md +261 -0
  116. package/yida-skills/skills/yida-design/references/style-designs/dark-stage-analytic-dashboard.md +369 -0
  117. package/yida-skills/skills/yida-design/references/style-designs/filterable-card-catalog.md +354 -0
  118. package/yida-skills/skills/yida-design/references/style-designs/green-timeline-progress-workbench.md +250 -0
  119. package/yida-skills/skills/yida-design/references/style-designs/registry.md +117 -0
  120. package/yida-skills/skills/yida-design/references/style-designs/soft-analytic-workbench.md +348 -0
  121. package/yida-skills/skills/yida-design/references/style-designs/soft-blue-grid-analytic-dashboard.md +658 -0
  122. package/yida-skills/skills/yida-design/references/style-designs/soft-bordered-analytic-workbench.md +385 -0
  123. package/yida-skills/skills/yida-design/references/style-designs/soft-curated-filter-gallery.md +300 -0
  124. package/yida-skills/skills/yida-design/references/style-designs/soft-modular-analytic-workbench.md +404 -0
  125. package/yida-skills/skills/yida-design/references/style-designs/soft-progress-analytics-workbench.md +382 -0
  126. package/yida-skills/skills/yida-design/references/style-designs/soft-timeline-analytics-workbench.md +367 -0
  127. package/yida-skills/skills/yida-design/references/style-designs/teal-rail-analytics-workbench.md +341 -0
  128. package/yida-skills/skills/yida-design/references/theme/app-custom-theme-template.css +432 -350
  129. package/yida-skills/skills/yida-design/references/visual-decision-engine.md +143 -19
  130. package/yida-skills/skills/yida-design/references/visual-scaffold-recipes.md +27 -15
  131. package/yida-skills/skills/yida-design/sub_skill/page-design/SKILL.md +0 -4
  132. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/SKILL.md +8 -22
  133. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/assets/README.md +10 -14
  134. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/assets/build-plan-template.html +4 -9
  135. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/build-plan-compact-schema.md +27 -49
  136. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/build-plan-schema.md +154 -33
  137. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-design.md +127 -48
  138. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-theme-selection.md +51 -37
  139. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/scripts/render_build_plan.py +48 -43
  140. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/scripts/validate_design_themes.py +190 -0
  141. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/README.md +98 -0
  142. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/airy-media-grid.md +339 -0
  143. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/airy-modular-clarity.md +348 -0
  144. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/airy-structured-clarity.md +344 -0
  145. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/ambient-halo-layered.md +345 -0
  146. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/dark-focus-layered.md +355 -0
  147. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/dark-luminous-modular.md +377 -0
  148. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/deep-stage-duotone.md +352 -0
  149. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/hairline-runway-clarity.md +389 -0
  150. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/high-contrast-modular.md +364 -0
  151. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/index.json +329 -0
  152. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/interlocked-vivid-modules.md +348 -0
  153. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/matrix-grid-focus.md +345 -0
  154. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/media-rail-inspector.md +379 -0
  155. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/mist-layered-signal.md +347 -0
  156. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/modular-rail-signal.md +352 -0
  157. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/mono-grid-signal.md +386 -0
  158. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/ribbon-ledger-lift.md +384 -0
  159. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/segmented-meter-clarity.md +388 -0
  160. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/split-rail-precision.md +341 -0
  161. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/templates/design-themes/status-framed-media-grid.md +361 -0
  162. package/yida-skills/skills/yida-design/workflow/output-design.md +375 -117
  163. package/yida-skills/skills/yida-design/workflow/output-prd.md +185 -0
  164. package/yida-skills/skills/yida-design/workflow/step-1-read-brief.md +1 -1
  165. package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +29 -33
  166. package/yida-skills/skills/yida-design/workflow/step-4-wireframe-interaction.md +1 -3
  167. package/yida-skills/skills/yida-design/workflow/step-5-visual-states.md +106 -22
  168. package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +22 -15
  169. package/yida-skills/skills/yida-form-permission/SKILL.md +0 -6
  170. package/yida-skills/skills/yida-image-assets/SKILL.md +50 -73
  171. package/yida-skills/skills/yida-image-assets/references/manifest-contract.md +52 -82
  172. package/yida-skills/skills/yida-image-assets/references/source-policy.md +15 -14
  173. package/yida-skills/skills/yida-integration/SKILL.md +0 -1
  174. package/yida-skills/skills/yida-login/SKILL.md +0 -2
  175. package/yida-skills/skills/yida-nav-group/SKILL.md +2 -4
  176. package/yida-skills/skills/yida-nav-shell/SKILL.md +12 -36
  177. package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +136 -79
  178. package/yida-skills/skills/yida-page-config/SKILL.md +4 -13
  179. package/yida-skills/skills/yida-prd/SKILL.md +3 -5
  180. package/yida-skills/skills/yida-prd/references/app/blueprint.md +4 -4
  181. package/yida-skills/skills/yida-prd/references/app/navigation-patterns.md +3 -6
  182. package/yida-skills/skills/yida-prd/references/app/role-journey.md +3 -5
  183. package/yida-skills/skills/yida-prd/references/plan-content.md +0 -4
  184. package/yida-skills/skills/yida-prd/workflow/output-prd.md +11 -18
  185. package/yida-skills/skills/yida-prd/workflow/plan-business.md +4 -4
  186. package/yida-skills/skills/yida-prd/workflow/step-2-information-architecture.md +8 -11
  187. package/yida-skills/skills/yida-publish-page/SKILL.md +1 -9
  188. package/yida-skills/skills/yida-requirement-analysis/SKILL.md +39 -10
  189. package/yida-skills/skills/yida-requirement-analysis/workflow/prepare-brief.md +71 -40
  190. package/yida-skills/skills-index.json +16 -36
  191. package/lib/app/application-entry-urls.js +0 -31
  192. package/lib/app/application-style.js +0 -69
  193. package/lib/app/canvas-icon-exports.json +0 -6160
  194. package/lib/app/canvas-icon-guard.js +0 -87
  195. package/lib/app/canvas-navigation-guard.js +0 -84
  196. package/lib/app/canvas-path-guard.js +0 -78
  197. package/lib/app/canvas-theme-guard.js +0 -184
  198. package/lib/app/form-data-response-guard.js +0 -57
  199. package/lib/asset/asset-execution.js +0 -79
  200. package/lib/core/css-structure.js +0 -37
  201. package/lib/design/check-design.js +0 -51
  202. package/lib/design/document.js +0 -458
  203. package/lib/design/icon-contrast.js +0 -85
  204. package/lib/design/page-content.js +0 -11
  205. package/lib/design-plan/artifact-updates.js +0 -117
  206. package/lib/design-plan/confirmation.js +0 -13
  207. package/lib/design-plan/entry-navigation.js +0 -97
  208. package/lib/design-plan/navigation-policy.js +0 -38
  209. package/lib/design-plan/rebase.js +0 -60
  210. package/lib/design-plan/themes.js +0 -101
  211. package/lib/design-plan/visual-policy.js +0 -42
  212. package/lib/samples/openyida-scaffold/canvas-admin-entry.jsx +0 -62
  213. package/lib/samples/openyida-scaffold/canvas-navigation.jsx +0 -56
  214. package/lib/samples/openyida-scaffold/canvas-view-state.jsx +0 -74
  215. package/yida-skills/skills/yida-app/references/entry-navigation.md +0 -193
  216. package/yida-skills/skills/yida-canvas-custom-page/references/view-state-recovery.md +0 -52
  217. package/yida-skills/skills/yida-canvas-data-binding/references/business-action-permissions.md +0 -31
  218. package/yida-skills/skills/yida-design/references/application-style-library.md +0 -93
  219. package/yida-skills/skills/yida-design/references/application-theme-consistency.md +0 -150
  220. package/yida-skills/skills/yida-design/references/native-form-styles.md +0 -208
  221. package/yida-skills/skills/yida-design/references/navigation-decision.md +0 -53
  222. package/yida-skills/skills/yida-design/references/page-continuity.md +0 -42
  223. package/yida-skills/skills/yida-design/references/theme/application-style-recipes.css +0 -58
  224. package/yida-skills/skills/yida-design/references/theme-selection.md +0 -67
  225. package/yida-skills/skills/yida-design/scripts/validate_design_themes.py +0 -302
  226. package/yida-skills/skills/yida-design/templates/application-styles.json +0 -398
  227. package/yida-skills/skills/yida-design/templates/design-themes/README.md +0 -73
  228. package/yida-skills/skills/yida-design/templates/design-themes/app-amber/app_theme.css +0 -748
  229. package/yida-skills/skills/yida-design/templates/design-themes/app-amber/design.md +0 -274
  230. package/yida-skills/skills/yida-design/templates/design-themes/app-amber/form-layout.json +0 -15
  231. package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/app_theme.css +0 -748
  232. package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/design.md +0 -274
  233. package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/form-layout.json +0 -14
  234. package/yida-skills/skills/yida-design/templates/design-themes/app-executive/app_theme.css +0 -748
  235. package/yida-skills/skills/yida-design/templates/design-themes/app-executive/design.md +0 -274
  236. package/yida-skills/skills/yida-design/templates/design-themes/app-executive/form-layout.json +0 -13
  237. package/yida-skills/skills/yida-design/templates/design-themes/app-finance/app_theme.css +0 -748
  238. package/yida-skills/skills/yida-design/templates/design-themes/app-finance/design.md +0 -274
  239. package/yida-skills/skills/yida-design/templates/design-themes/app-finance/form-layout.json +0 -14
  240. package/yida-skills/skills/yida-design/templates/design-themes/app-glass/app_theme.css +0 -748
  241. package/yida-skills/skills/yida-design/templates/design-themes/app-glass/design.md +0 -274
  242. package/yida-skills/skills/yida-design/templates/design-themes/app-glass/form-layout.json +0 -14
  243. package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/app_theme.css +0 -748
  244. package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/design.md +0 -274
  245. package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/form-layout.json +0 -14
  246. package/yida-skills/skills/yida-design/templates/design-themes/app-line/app_theme.css +0 -748
  247. package/yida-skills/skills/yida-design/templates/design-themes/app-line/design.md +0 -274
  248. package/yida-skills/skills/yida-design/templates/design-themes/app-line/form-layout.json +0 -13
  249. package/yida-skills/skills/yida-design/templates/design-themes/app-neon/app_theme.css +0 -748
  250. package/yida-skills/skills/yida-design/templates/design-themes/app-neon/design.md +0 -274
  251. package/yida-skills/skills/yida-design/templates/design-themes/app-neon/form-layout.json +0 -14
  252. package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/app_theme.css +0 -754
  253. package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/design.md +0 -279
  254. package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/form-layout.json +0 -13
  255. package/yida-skills/skills/yida-design/templates/design-themes/app-paper/app_theme.css +0 -748
  256. package/yida-skills/skills/yida-design/templates/design-themes/app-paper/design.md +0 -274
  257. package/yida-skills/skills/yida-design/templates/design-themes/app-paper/form-layout.json +0 -13
  258. package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/app_theme.css +0 -748
  259. package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/design.md +0 -274
  260. package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/form-layout.json +0 -14
  261. package/yida-skills/skills/yida-design/templates/design-themes/app-plum/app_theme.css +0 -748
  262. package/yida-skills/skills/yida-design/templates/design-themes/app-plum/design.md +0 -274
  263. package/yida-skills/skills/yida-design/templates/design-themes/app-plum/form-layout.json +0 -14
  264. package/yida-skills/skills/yida-design/templates/design-themes/app-pop/app_theme.css +0 -758
  265. package/yida-skills/skills/yida-design/templates/design-themes/app-pop/design.md +0 -281
  266. package/yida-skills/skills/yida-design/templates/design-themes/app-pop/form-layout.json +0 -14
  267. package/yida-skills/skills/yida-design/templates/design-themes/app-sage/app_theme.css +0 -748
  268. package/yida-skills/skills/yida-design/templates/design-themes/app-sage/design.md +0 -274
  269. package/yida-skills/skills/yida-design/templates/design-themes/app-sage/form-layout.json +0 -14
  270. package/yida-skills/skills/yida-design/templates/design-themes/app-teal/app_theme.css +0 -748
  271. package/yida-skills/skills/yida-design/templates/design-themes/app-teal/design.md +0 -274
  272. package/yida-skills/skills/yida-design/templates/design-themes/app-teal/form-layout.json +0 -14
  273. package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/app_theme.css +0 -754
  274. package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/design.md +0 -279
  275. package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/form-layout.json +0 -14
  276. package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/app_theme.css +0 -752
  277. package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/design.md +0 -278
  278. package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/form-layout.json +0 -13
  279. package/yida-skills/skills/yida-design/templates/design-themes/app-wire/app_theme.css +0 -748
  280. package/yida-skills/skills/yida-design/templates/design-themes/app-wire/design.md +0 -274
  281. package/yida-skills/skills/yida-design/templates/design-themes/app-wire/form-layout.json +0 -14
  282. package/yida-skills/skills/yida-design/templates/design-themes/basic-tokens.json +0 -118
  283. package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/app_theme.css +0 -690
  284. package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/design.md +0 -382
  285. package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/form-layout.json +0 -13
  286. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/app_theme.css +0 -691
  287. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/design.md +0 -380
  288. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/form-layout.json +0 -13
  289. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/app_theme.css +0 -696
  290. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/design.md +0 -378
  291. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/form-layout.json +0 -13
  292. package/yida-skills/skills/yida-design/templates/design-themes/free-creative/app_theme.css +0 -689
  293. package/yida-skills/skills/yida-design/templates/design-themes/free-creative/design.md +0 -238
  294. package/yida-skills/skills/yida-design/templates/design-themes/free-creative/form-layout.json +0 -13
  295. package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/app_theme.css +0 -692
  296. package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/design.md +0 -375
  297. package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/form-layout.json +0 -13
  298. package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/app_theme.css +0 -691
  299. package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/design.md +0 -362
  300. package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/form-layout.json +0 -13
  301. package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/app_theme.css +0 -691
  302. package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/design.md +0 -409
  303. package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/form-layout.json +0 -13
  304. package/yida-skills/skills/yida-design/templates/design-themes/index.json +0 -464
  305. package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/app_theme.css +0 -701
  306. package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/design.md +0 -379
  307. package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/form-layout.json +0 -13
  308. package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/app_theme.css +0 -691
  309. package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/design.md +0 -404
  310. package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/form-layout.json +0 -13
  311. package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/app_theme.css +0 -698
  312. package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/design.md +0 -389
  313. package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/form-layout.json +0 -13
  314. package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/app_theme.css +0 -691
  315. package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/design.md +0 -372
  316. package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/form-layout.json +0 -13
  317. package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/app_theme.css +0 -690
  318. package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/design.md +0 -455
  319. package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/form-layout.json +0 -13
  320. package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/app_theme.css +0 -698
  321. package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/design.md +0 -394
  322. package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/form-layout.json +0 -13
  323. package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/app_theme.css +0 -692
  324. package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/design.md +0 -391
  325. package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/form-layout.json +0 -13
  326. package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/app_theme.css +0 -711
  327. package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/design.md +0 -408
  328. package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/form-layout.json +0 -13
  329. package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/app_theme.css +0 -692
  330. package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/design.md +0 -383
  331. package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/form-layout.json +0 -13
  332. package/yida-skills/skills/yida-design/templates/navigation-styles.json +0 -769
  333. package/yida-skills/skills/yida-requirement-analysis/references/experience-groups.md +0 -79
  334. package/yida-skills/skills/yida-requirement-analysis/references/handoff.md +0 -68
@@ -76,24 +76,19 @@ function redactSensitive(value, options = {}) {
76
76
  }
77
77
  seen.add(value);
78
78
 
79
- try {
80
- if (Array.isArray(value)) {
81
- return value.map(item => redactSensitive(item, { seen }));
82
- }
79
+ if (Array.isArray(value)) {
80
+ return value.map(item => redactSensitive(item, { seen }));
81
+ }
83
82
 
84
- if (!isPlainObject(value)) {
85
- return value;
86
- }
83
+ if (!isPlainObject(value)) {
84
+ return value;
85
+ }
87
86
 
88
- const redacted = {};
89
- for (const [entryKey, entryValue] of Object.entries(value)) {
90
- redacted[entryKey] = redactSensitive(entryValue, { seen, key: entryKey });
91
- }
92
- return redacted;
93
- } finally {
94
- // Only ancestors form a cycle; siblings may share the same diagnostic object.
95
- seen.delete(value);
87
+ const redacted = {};
88
+ for (const [entryKey, entryValue] of Object.entries(value)) {
89
+ redacted[entryKey] = redactSensitive(entryValue, { seen, key: entryKey });
96
90
  }
91
+ return redacted;
97
92
  }
98
93
 
99
94
  function safeJsonStringify(value, spacing = 2) {
@@ -18,7 +18,6 @@
18
18
  const fs = require('fs');
19
19
  const path = require('path');
20
20
  const { CliError } = require('./cli-error');
21
- const { t } = require('./i18n');
22
21
 
23
22
  // ── Sample 索引表 ─────────────────────────────────────────────────────
24
23
 
@@ -52,10 +51,7 @@ const SAMPLES = {
52
51
  'canvas-form-drawer': 'canvas-form-drawer.canvas.jsx',
53
52
  'form-open-container': 'canvas-form-drawer.canvas.jsx',
54
53
  'canvas-dialog': 'canvas-dialog.canvas.jsx',
55
- 'canvas-theme': 'canvas-theme-provider.template.jsx',
56
- 'canvas-navigation': 'canvas-navigation.jsx',
57
- 'canvas-view-state': 'canvas-view-state.jsx',
58
- 'canvas-admin-entry': 'canvas-admin-entry.jsx',
54
+ 'canvas-theme': 'canvas-form-drawer.canvas.jsx',
59
55
  'canvas-nav-side': 'canvas-nav/side.jsx',
60
56
  'canvas-nav-top': 'canvas-nav/top.jsx',
61
57
  'canvas-nav-mixed': 'canvas-nav/mixed.jsx',
@@ -77,7 +73,6 @@ const SAMPLE_SOURCE_DIRECTORIES = {
77
73
  };
78
74
 
79
75
  const SAMPLE_SOURCE_FILES = {
80
- 'openyida-page-template/canvas-theme': path.join(__dirname, '../../yida-skills/skills/yida-canvas-custom-page/scripts/canvas-theme-provider.template.jsx'),
81
76
  'yida-design/app-theme': path.join(
82
77
  __dirname,
83
78
  '..',
@@ -106,13 +101,9 @@ const SAMPLE_OUTPUT_FILENAMES = {
106
101
  };
107
102
 
108
103
  const SAMPLE_HINTS = {
109
- 'openyida-page-template/canvas-admin-entry': '已包含统一跳转 helper;在 CanvasThemeProvider 内渲染 CanvasAdminWorkbenchButton,填写当前 appType 与真实 workbenchFormUuid。身份读取当前应用 loginUser.isAppAdmin,未知时隐藏;默认不跳开发后台或猜测管理首页。',
110
- 'openyida-page-template/canvas-navigation': '先从资源回读填写 appType、目标类型与页面 ID;本页 Tab 用 selectView,独立前台用 custom,管理入口用 page,表单入口接 openForm;按钮和链接共用 buildCanvasPageUrl。',
111
- 'openyida-page-template/canvas-theme': '以 CanvasThemeProvider 包住业务组件;Tabs 用于内容切换,Segmented/Radio 用于筛选,Button 用于动作。默认轻底选中态与可读文字,controls 可供自绘控件复用;避免内层固定色覆盖。保留内置加载遮罩防闪边样式;旧页面需更新 Provider 并重新发布。',
112
- 'openyida-page-template/canvas-nav-top': '顶部默认贴顶通栏;长页先合并 canvas-nav-content,CanvasNav 传 headerOnly,有首屏背景时传 overlay;悬浮外观仅显式 floating=true。',
113
- 'openyida-page-template/canvas-nav-content': '合并 CanvasNavigationContent;长页用 layout=document,CanvasNav 传 headerOnly/overlay;默认 sticky,受宿主限制时用 navigationPosition=fixed。工作区用 workspace,宿主已分配高度时传 height。',
114
- 'openyida-page-template/canvas-nav-data': '页内展示用 mode=local(key/viewKey/targetType=local),不请求平台菜单;platform 需真实资源 ID;independent 或声明 access 时必须接入真实 resolveAccess。保留 PRD 顺序与分组。',
115
- 'openyida-page-template/form-open-container': '将 import、CanvasDrawer、FormOpenContainer、useYidaFormOpen 和辅助函数合并到现有 Canvas 页面;表单按钮调用 openForm(request),页面必须渲染返回的 formOpenContainer;保留 iframe、标题栏操作、调宽和关闭刷新。普通业务内容使用 CanvasDrawer;抽屉背景使用 --pod-page-bg-color,文字使用 --color-text1-4,background 可按设计覆盖。',
104
+ 'openyida-page-template/canvas-nav-content': '合并 CanvasNavigationContent;顶部导航传 navigation,工作台传 children,原生页传 iframeSrc 和 title;宿主已分配高度时显式传 height。',
105
+ 'openyida-page-template/canvas-nav-data': '向 loadCanvasNavigation 传入 PRD 规划的 items,通常工作台在首位;接口只过滤不可见入口,保留规划顺序与分组。',
106
+ 'openyida-page-template/form-open-container': '将 import、抽屉组件和辅助函数合并到现有 Canvas 页面;表单使用 useYidaFormOpen,其他内容使用 CanvasDrawer。',
116
107
  'yida-design/app-theme': '已复制应用主题模板;请由 yida-design 按 design.md 定点修改需要变化的 token。',
117
108
  };
118
109
 
@@ -149,9 +140,6 @@ function printSampleList() {
149
140
  }
150
141
  console.log('');
151
142
  console.log(' 应用主题:openyida sample yida-design app-theme --output <app-theme.css> --design-file <design.md>');
152
- console.log(' Application style: openyida sample yida-design application-style --style-id <themeId|free-creative> --output <directory>');
153
- console.log(` ${t('sample_options.theme_help')}`);
154
- console.log(` ${t('sample_options.style_help')}`);
155
143
  }
156
144
 
157
145
  /**
@@ -166,29 +154,23 @@ function ensureDirectoryExists(filePath) {
166
154
  }
167
155
 
168
156
  /**
169
- * 解析 sample 输出路径、设计文件、主题 ID 与模板变量;拒绝未声明参数。
157
+ * 解析 --output 与 --var KEY=VALUE 参数。
170
158
  * @param {string[]} rest
171
159
  * @param {string} defaultOutputPath
172
- * @returns {{ outputPath: string, variables: Object, designFile?: string, styleId?: string }}
160
+ * @returns {{ outputPath: string, variables: Object }}
173
161
  */
174
162
  function parseOptions(rest, defaultOutputPath) {
175
163
  let outputPath = defaultOutputPath;
176
164
  let designFile;
177
- let styleId;
178
165
  const variables = {};
179
166
 
180
167
  for (let i = 0; i < rest.length; i++) {
181
168
  const arg = rest[i];
182
- const invalid = () => {throw new CliError(t('cli_argument.invalid', arg), { code: 'SAMPLE_ARGUMENT_INVALID' });};
183
- if (!['--output', '--var', '--design-file', '--style-id'].includes(arg)) {invalid();}
184
- if (!rest[i + 1] || rest[i + 1].startsWith('--')) {invalid();}
185
-
186
- if (arg === '--style-id') {
187
- styleId = rest[++i];
188
- continue;
189
- }
190
169
 
191
170
  if (arg === '--design-file') {
171
+ if (!rest[i + 1] || rest[i + 1].startsWith('--')) {
172
+ throw new CliError('--design-file 缺少 design.md 路径', { code: 'DESIGN_THEME_FILE_REQUIRED' });
173
+ }
192
174
  designFile = rest[++i];
193
175
  continue;
194
176
  }
@@ -202,15 +184,19 @@ function parseOptions(rest, defaultOutputPath) {
202
184
  if (arg === '--var' && rest[i + 1]) {
203
185
  const pair = rest[i + 1];
204
186
  const eqIndex = pair.indexOf('=');
205
- if (eqIndex <= 0 || !pair.slice(0, eqIndex).trim()) {invalid();}
206
- const key = pair.slice(0, eqIndex).trim();
207
- variables[key] = pair.slice(eqIndex + 1);
187
+ if (eqIndex > 0) {
188
+ const key = pair.slice(0, eqIndex).trim();
189
+ const value = pair.slice(eqIndex + 1);
190
+ if (key) {
191
+ variables[key] = value;
192
+ }
193
+ }
208
194
  i++;
209
195
  continue;
210
196
  }
211
197
  }
212
198
 
213
- return { outputPath, variables, designFile, styleId };
199
+ return { outputPath, variables, designFile };
214
200
  }
215
201
 
216
202
  /**
@@ -240,19 +226,6 @@ async function run(args) {
240
226
  }
241
227
 
242
228
  const [skill, name, ...rest] = args;
243
- if (skill === 'yida-design' && name === 'application-style') {
244
- const options = parseOptions(rest, path.join(process.cwd(), '.cache/samples/application-style'));
245
- if (options.designFile || Object.keys(options.variables).length) {
246
- throw new CliError(t('design_document.invalid', 'application-style', 'APPLICATION_STYLE_SAMPLE_INVALID'), { code: 'APPLICATION_STYLE_SAMPLE_INVALID' });
247
- }
248
- if (!options.styleId) {
249
- throw new CliError(t('cli_argument.invalid', '--style-id'), { code: 'APPLICATION_STYLE_REQUIRED' });
250
- }
251
- const result = require('../app/application-style').exportApplicationStyle(options.styleId, options.outputPath);
252
- console.log(JSON.stringify(result, null, 2));
253
- return result;
254
- }
255
- if (rest.includes('--style-id')) {throw new CliError(t('design_document.invalid', '--style-id', 'APPLICATION_STYLE_SAMPLE_INVALID'), { code: 'APPLICATION_STYLE_SAMPLE_INVALID' });}
256
229
 
257
230
  const { c, error: chalkError, success: chalkSuccess, hint: chalkHint } = require('./chalk');
258
231
 
@@ -283,8 +256,7 @@ async function run(args) {
283
256
  const defaultOutputPath = path.join(process.cwd(), '.cache', 'samples', outputFilename);
284
257
  const { outputPath, variables, designFile } = parseOptions(rest, defaultOutputPath);
285
258
  const isNavSample = skill === 'openyida-page-template' && name.startsWith('canvas-nav-');
286
- const prefixPath = sampleKey === 'openyida-page-template/canvas-admin-entry' ? path.join(path.dirname(sourcePath), 'canvas-navigation.jsx')
287
- : isNavSample && !['canvas-nav-tabs', 'canvas-nav-data', 'canvas-nav-content'].includes(name) ? path.join(path.dirname(sourcePath), 'shared.jsx') : null;
259
+ const prefixPath = isNavSample && !['canvas-nav-tabs', 'canvas-nav-data', 'canvas-nav-content'].includes(name) ? path.join(path.dirname(sourcePath), 'shared.jsx') : null;
288
260
  const sidebarPath = isNavSample && ['canvas-nav-side', 'canvas-nav-mixed'].includes(name) ? path.join(path.dirname(sourcePath), 'sidebar.jsx') : null;
289
261
  if ([sourcePath, prefixPath, sidebarPath, designFile].filter(Boolean).some(file => path.resolve(outputPath) === path.resolve(file))) {
290
262
  throw new CliError('输出路径不能覆盖模板或 design.md', { code: 'SAMPLE_OUTPUT_CONFLICT' });
@@ -294,25 +266,14 @@ async function run(args) {
294
266
  throw new CliError('--design-file 仅用于 yida-design app-theme', { code: 'DESIGN_THEME_SAMPLE_INVALID' });
295
267
  }
296
268
  if (sampleKey === 'yida-design/app-theme') {
297
- if (Object.keys(variables).length) {
298
- throw new CliError(t('cli_argument.invalid', '--var (yida-design app-theme: --design-file)'), { code: 'SAMPLE_ARGUMENT_INVALID' });
299
- }
300
269
  const snapshotPath = `${outputPath}.tokens.md`;
301
270
  if (designFile && path.resolve(snapshotPath) === path.resolve(designFile)) {
302
271
  throw new CliError('输出路径不能覆盖模板或 design.md', { code: 'SAMPLE_OUTPUT_CONFLICT' });
303
272
  }
304
273
  const template = fs.readFileSync(sourcePath, 'utf8');
305
- // Template-only exports must pass the same checks as generated/uploaded CSS.
306
- require('../app/custom-theme').validateThemeCssContent(template);
307
274
  if (designFile) {
308
275
  const { applyDesignTokens, readDesignTokens } = require('../app/theme-from-design');
309
276
  const markdown = fs.readFileSync(designFile, 'utf8');
310
- // Both authoring modes use the same final-document contract. Older token-
311
- // only files still support incremental theme updates without migration.
312
- const frontmatter = /^\uFEFF?---\r?\n([\s\S]*?)\r?\n---/.exec(markdown)?.[1] || '';
313
- if (/^["']?schemaVersion["']?\s*:/m.test(frontmatter)) {
314
- require('../design/document').validateDesignDocument(markdown);
315
- }
316
277
  const existing = fs.existsSync(outputPath);
317
278
  const previous = existing && fs.existsSync(snapshotPath) ? fs.readFileSync(snapshotPath, 'utf8') : undefined;
318
279
  const css = applyDesignTokens(existing ? fs.readFileSync(outputPath, 'utf8') : template, markdown, previous);
@@ -334,8 +295,12 @@ async function run(args) {
334
295
  const content = [prefixPath, sidebarPath, sourcePath].filter(Boolean).map(file => fs.readFileSync(file, 'utf8')).join('\n');
335
296
  fs.writeFileSync(outputPath, applyTemplateVariables(content, variables), 'utf8');
336
297
  } else if (sampleKey === 'openyida-page-template/canvas-theme') {
337
- const { buildApplicationProvider } = require('../../yida-skills/skills/yida-canvas-custom-page/scripts/build-canvas-theme');
338
- fs.writeFileSync(outputPath, buildApplicationProvider(), 'utf8');
298
+ const sourceContent = fs.readFileSync(sourcePath, 'utf8');
299
+ const fragment = sourceContent.match(/\/\/ @openyida-canvas-theme:start\r?\n([\s\S]*?)\/\/ @openyida-canvas-theme:end/);
300
+ if (!fragment) {
301
+ throw new CliError('Canvas theme fragment missing', { code: 'SAMPLE_FRAGMENT_MISSING' });
302
+ }
303
+ fs.writeFileSync(outputPath, "import React from 'react';\n\n" + fragment[1], 'utf8');
339
304
  } else if (sampleKey === 'openyida-page-template/form-open-container') {
340
305
  const sourceContent = fs.readFileSync(sourcePath, 'utf8');
341
306
  const fragment = sourceContent.match(/\/\/ @openyida-form-drawer:start\r?\n([\s\S]*?)\/\/ @openyida-form-drawer:end/);
@@ -343,25 +308,18 @@ async function run(args) {
343
308
  throw new CliError('抽屉模板缺少共享代码片段', { code: 'SAMPLE_FRAGMENT_MISSING' });
344
309
  }
345
310
  fs.writeFileSync(outputPath, applyTemplateVariables(fragment[1], variables), 'utf8');
311
+ } else if (Object.keys(variables).length === 0) {
312
+ fs.copyFileSync(sourcePath, outputPath);
346
313
  } else {
347
- const { assembleApplicationTheme } = require('../../yida-skills/skills/yida-canvas-custom-page/scripts/build-canvas-theme');
348
314
  const sourceContent = fs.readFileSync(sourcePath, 'utf-8');
349
- const outputContent = applyTemplateVariables(assembleApplicationTheme(sourceContent), variables);
315
+ const outputContent = applyTemplateVariables(sourceContent, variables);
350
316
  fs.writeFileSync(outputPath, outputContent, 'utf-8');
351
317
  }
352
318
 
353
319
  chalkSuccess(`模板文件已复制到:${c.cyan}${outputPath}${c.reset}`);
354
- const navigationHint = isNavSample
355
- ? '平台导航页默认只实现业务内容,不合并第二套应用菜单;页内 Tab 仅切当前任务的分类或状态。确认独立入口或应用级自绘导航后再使用导航壳片段。'
356
- : '';
357
- const defaultHint = isNavSample
358
- ? '已输出所选导航组件;合并 import 后接入 items、activeKey、onSelect 和现有页面内容,样式直接消费应用 token。'
359
- : '请读取文件并按当前业务需求修改;发布前移除模板标记、示例数据和占位文案。';
360
- const sampleHint = SAMPLE_HINTS[sampleKey] || defaultHint;
361
- const hint = designFile
362
- ? '已按 design.md 应用 token;使用 --theme-file 在应用级配置主题。'
363
- : navigationHint + sampleHint;
364
- chalkHint(hint);
320
+ chalkHint(designFile ? '已按 design.md 应用 token;使用 --theme-file 在应用级配置主题。' :
321
+ SAMPLE_HINTS[sampleKey] || (isNavSample ? '已输出所选导航组件;合并 import 后接入 items、activeKey、onSelect 和现有页面内容,样式直接消费应用 token。' :
322
+ '请读取文件并按当前业务需求修改;发布前移除模板标记、示例数据和占位文案。'));
365
323
  }
366
324
 
367
325
  module.exports = { run, applyTemplateVariables, parseOptions };
package/lib/core/utils.js CHANGED
@@ -842,6 +842,7 @@ function loadTokenAuthData(projectRoot, defaultBaseUrl) {
842
842
  auth_source: session.auth_source || 'token',
843
843
  auth_store: session.auth_store,
844
844
  auth_profile: session.auth_profile,
845
+ credential_source: session.credential_source,
845
846
  persistence_scope: session.persistence_scope,
846
847
  user_auth_store_writable: session.user_auth_store_writable,
847
848
  warning: session.warning,
@@ -1722,6 +1723,8 @@ async function requestWithAutoLogin(requestFn, authRef) {
1722
1723
  const refreshResult = await tokenRefresh({
1723
1724
  projectRoot: authRef && authRef.projectRoot,
1724
1725
  baseUrl: currentBaseUrl,
1726
+ ...(currentAuthData && currentAuthData.credential_source === 'dws'
1727
+ ? { authProfile: currentAuthData.auth_profile } : {}),
1725
1728
  clientId: currentAuthData && (currentAuthData.client_id || currentAuthData.clientId),
1726
1729
  });
1727
1730
  if (!refreshResult || refreshResult.ok === false || !refreshResult.access_token) {
@@ -1811,6 +1814,7 @@ function normalizeRefreshedTokenAuthData(refreshResult, fallbackBaseUrl) {
1811
1814
  auth_source: refreshResult.auth_source || 'token',
1812
1815
  auth_store: refreshResult.auth_store,
1813
1816
  auth_profile: refreshResult.auth_profile,
1817
+ credential_source: refreshResult.credential_source,
1814
1818
  persistence_scope: refreshResult.persistence_scope,
1815
1819
  user_auth_store_writable: refreshResult.user_auth_store_writable,
1816
1820
  warning: refreshResult.warning,
@@ -3,16 +3,15 @@
3
3
  const { CliError } = require('../core/cli-error');
4
4
  const { materialize } = require('./materialize');
5
5
  const { patchPlan } = require('./patch');
6
- const { initialize, catalog } = require('./init');
6
+ const { initialize } = require('./init');
7
7
  const { preview } = require('./preview');
8
8
 
9
9
  function usage() {
10
10
  return [
11
11
  '用法:',
12
- ' openyida design-plan catalog [--json]',
13
12
  ' openyida design-plan init <requirement-brief.json> [--theme-id <id>] [--output-dir <dir>] [--json]',
14
13
  ' openyida design-plan preview <build-plan.json> --part-file <module.json> [--json]',
15
- ' openyida design-plan materialize <build-plan.json> [--from-preview | --business-file <json> --visual-file <json>] [--output-dir <dir>] [--rebase-parts] [--check] [--json]',
14
+ ' openyida design-plan materialize <build-plan.json> [--from-preview | --business-file <json> --visual-file <json>] [--output-dir <dir>] [--check] [--json]',
16
15
  ' openyida design-plan patch <build-plan.json> --set <path=value> [--set <path=value> ...] [--materialize] [--output-dir <dir>] [--json]',
17
16
  ].join('\n');
18
17
  }
@@ -50,63 +49,18 @@ function setValues(args) {
50
49
  return values;
51
50
  }
52
51
 
53
- const OPTION_SCHEMA = Object.freeze({
54
- catalog: { flags: ['--json'], values: [] },
55
- init: { flags: ['--json'], values: ['--theme-id', '--output-dir'] },
56
- preview: { flags: ['--json'], values: ['--part-file'] },
57
- materialize: { flags: ['--from-preview', '--rebase-parts', '--check', '--json'], values: ['--business-file', '--visual-file', '--output-dir'] },
58
- patch: { flags: ['--materialize', '--json'], values: ['--set', '--output-dir'], inlineValues: ['--set'] },
59
- });
60
-
61
- function assertKnownOptions(subcommand, args) {
62
- const schema = OPTION_SCHEMA[subcommand];
63
- const flags = new Set(schema.flags);
64
- const values = new Set(schema.values);
65
- const inlineValues = new Set(schema.inlineValues || []);
66
- for (let index = 0; index < args.length; index += 1) {
67
- const token = args[index];
68
- const equalsAt = token.indexOf('=');
69
- const option = equalsAt === -1 ? token : token.slice(0, equalsAt);
70
- if (equalsAt !== -1 && inlineValues.has(option)) {
71
- continue;
72
- }
73
- if (flags.has(token)) {
74
- continue;
75
- }
76
- if (values.has(token)) {
77
- if (!args[index + 1] || args[index + 1].startsWith('--')) {
78
- throw new CliError(`${token} 缺少参数值`, {
79
- code: 'DESIGN_PLAN_INVALID_ARGUMENT',
80
- usage: usage(),
81
- });
82
- }
83
- index += 1;
84
- continue;
85
- }
86
- throw new CliError(`未知 ${subcommand} 参数:${token}`, {
87
- code: 'DESIGN_PLAN_INVALID_ARGUMENT',
88
- usage: usage(),
89
- });
90
- }
91
- }
92
-
93
52
  async function run(args) {
94
53
  const subcommand = args[0];
95
54
  if (!subcommand || args.includes('--help') || args.includes('-h')) {
96
55
  console.log(usage());
97
56
  return;
98
57
  }
99
- if (!['catalog', 'init', 'preview', 'materialize', 'patch'].includes(subcommand)) {
58
+ if (!['init', 'preview', 'materialize', 'patch'].includes(subcommand)) {
100
59
  throw new CliError(`未知 design-plan 子命令:${subcommand}`, {
101
60
  code: 'DESIGN_PLAN_UNKNOWN_SUBCOMMAND',
102
61
  usage: usage(),
103
62
  });
104
63
  }
105
- if (subcommand === 'catalog') {
106
- assertKnownOptions(subcommand, args.slice(1));
107
- console.log(JSON.stringify(catalog(), null, 2));
108
- return;
109
- }
110
64
  const input = args[1];
111
65
  if (!input || input.startsWith('--')) {
112
66
  throw new CliError(`${subcommand} 缺少 ${subcommand === 'init' ? 'requirement-brief.json' : 'build-plan.json'} 路径`, {
@@ -115,14 +69,13 @@ async function run(args) {
115
69
  });
116
70
  }
117
71
  const options = args.slice(2);
118
- assertKnownOptions(subcommand, options);
119
72
  const outputDir = optionValue(options, '--output-dir');
120
73
  const result = subcommand === 'init'
121
74
  ? initialize(input, { outputDir, themeId: optionValue(options, '--theme-id') })
122
75
  : subcommand === 'preview'
123
76
  ? preview(input, { partFile: optionValue(options, '--part-file') })
124
77
  : subcommand === 'materialize'
125
- ? materialize(input, { outputDir, check: options.includes('--check'), rebaseParts: options.includes('--rebase-parts'), fromPreview: options.includes('--from-preview'), businessFile: optionValue(options, '--business-file'), visualFile: optionValue(options, '--visual-file') })
78
+ ? materialize(input, { outputDir, check: options.includes('--check'), fromPreview: options.includes('--from-preview'), businessFile: optionValue(options, '--business-file'), visualFile: optionValue(options, '--visual-file') })
126
79
  : patchPlan(input, setValues(options), { outputDir, materialize: options.includes('--materialize') });
127
80
 
128
81
  if (options.includes('--json') || subcommand === 'preview') {
@@ -2,34 +2,16 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
- const { getVisualDecisionPolicy } = require('./visual-policy');
6
5
  const { CliError } = require('../core/cli-error');
7
6
  const { readJson, writeFiles } = require('./files');
8
7
  const { planBase } = require('./parallel');
9
- const { collectIssues } = require('./validate');
10
- const { assertVisualFieldObjects } = require('./normalize');
11
8
 
12
- const { PLAN_SKILL_ROOT: ROOT, loadThemeIndex, themeTemplatePath, themeNavTheme } = require('./themes');
9
+ const ROOT = path.resolve(__dirname, '../../yida-skills/skills/yida-design/sub_skill/yida-design-plan');
13
10
 
14
11
  function list(value) {
15
12
  return Array.isArray(value) ? value : [];
16
13
  }
17
14
 
18
- function normalizeColorStrategy(value) {
19
- if (value === undefined || value === null) {return {};}
20
- if (typeof value === 'string') {return { usage: value };}
21
- if (typeof value === 'object' && !Array.isArray(value)) {return value;}
22
- throw new CliError('visualSelection.colorStrategy 应为配色对象或文字说明', {
23
- code: 'DESIGN_PLAN_INVALID_COLOR_STRATEGY',
24
- details: { field: 'visualSelection.colorStrategy', expected: 'object|string' },
25
- });
26
- }
27
-
28
- function quoteArgument(value) {
29
- const escaped = process.platform === 'win32' ? value.replace(/'/g, "''") : value.replace(/'/g, '\'"\'"\'');
30
- return `'${escaped}'`;
31
- }
32
-
33
15
  function customScene(scene) {
34
16
  return !['form', 'process-form', 'report'].includes(scene?.kind);
35
17
  }
@@ -46,62 +28,6 @@ function scopeEntryMatchesScene(entry, scene) {
46
28
  return candidate && [scene?.key, scene?.name].includes(candidate);
47
29
  }
48
30
 
49
- function loadCatalog() {
50
- return {
51
- themes: loadThemeIndex().themes,
52
- pagePatterns: readJson(path.join(ROOT, 'templates/page-patterns/index.json')).patterns,
53
- };
54
- }
55
-
56
- function catalog() {
57
- const { themes, pagePatterns } = loadCatalog();
58
- return {
59
- success: true,
60
- themes: themes.filter(theme => theme.mode !== 'creative').map(theme => ({ ...theme })),
61
- creativeOption: themes.find(theme => theme.mode === 'creative'),
62
- pagePatterns: pagePatterns.map(({ id, label, mustKeep }) => ({ id, label, mustKeep })),
63
- };
64
- }
65
-
66
- // Format examples stay outside business facts, so examples never become requirements.
67
- function authoringGuidance(plan, business, visual, businessReady, visualReady) {
68
- const color = plan.visualStyle.forUser.colorStrategy;
69
- const pendingFields = collectIssues(plan).map(issue => ({
70
- file: issue.path.startsWith('visualStyle.') ? visual : business,
71
- path: `facts.${issue.path}`,
72
- message: issue.message,
73
- }));
74
- for (const [file, ready] of [[business, businessReady], [visual, visualReady]]) {
75
- if (!ready) {pendingFields.push({ file, path: 'ready', message: '完成本片段的业务或视觉内容后设置为 true' });}
76
- }
77
- return {
78
- visualDecision: getVisualDecisionPolicy(),
79
- pendingFields,
80
- completion: '保留 base 和已有事实;按待补字段完成内容并复核业务覆盖,将完成的片段设为 ready=true,再执行 materialize.command。待补字段为初始化检查结果,最终生成时继续执行完整校验。',
81
- examples: {
82
- colorStrategy: { primaryColor: color.primaryColor, primaryColorName: color.primaryColorName, usage: color.usage },
83
- blocks: [{ name: '客房选择', purpose: '按日期和人数筛选可预约房型' }, { name: '预约结果', purpose: '查看提交结果,失败时保留已填内容并显示原因' }],
84
- field: { name: '订单编号', type: '单行文本', required: true, defaultOrOptions: '', relation: '', group: '基本信息', description: '订单唯一标识' },
85
- businessFragment: { facts: {
86
- overview: { businessGraph: { relations: [{ from: '订单', to: '客户', label: '归属客户', description: '一个客户可以拥有多笔订单' }] } },
87
- businessFlows: [{ name: '订单审核', type: '审批', description: '订单提交后审核', trigger: '订单提交', nodes: ['提交', '审批'], rules: ['审批通过后进入执行'] }],
88
- pages: { customPageDetails: [{ pageId: 'orders', dataBinding: 'form', dataSources: ['订单'] }] },
89
- execution: {
90
- sampleDataPlan: [{ form: '订单', records: [{ '订单编号': 'ORDER-001' }] }],
91
- interactionStates: { empty: '展示空态和新建入口', loading: '显示加载状态', error: '保留输入并提示失败原因' },
92
- },
93
- } },
94
- skippedSampleDataPlan: { path: 'facts.execution.sampleDataPlan', value: [{ form: '订单', skipReason: '填写本项目跳过示例数据的原因' }] },
95
- referenceRules: 'relations.from/to、field.relation、dataSources 必须填写 dataModels 中的完整名称;关系描述写 description,不放进引用值。示例中的模型名和流程只说明格式,无此业务时使用空数组。',
96
- pageApplication: { pageId: '填写实际页面ID', firstScreenFocus: '待审批订单位于首屏左上,数量与最临近截止时间组成焦点',
97
- layout: '桌面主列放待审批表格,右列放当前订单详情;两列比例为 2:1,区块间距 24px',
98
- primaryAction: '待审批表格每行末尾提供审批按钮,打开该订单对应的原生审批页面,处理成功后刷新列表',
99
- responsive: '宽度小于 768px 时详情移至表格下方,行内次操作收入菜单,主操作保持可见',
100
- acceptanceChecks: ['首屏待审批数量与表格筛选结果一致', '窄屏下订单号和主操作无需横向滚动即可查看'] },
101
- },
102
- };
103
- }
104
-
105
31
  function initialize(inputPath, options = {}) {
106
32
  const input = path.resolve(inputPath);
107
33
  const brief = readJson(input, 'requirement-brief.json');
@@ -131,22 +57,20 @@ function initialize(inputPath, options = {}) {
131
57
  || (brief.navigation.type === 'custom' && !['side', 'top', 'mixed', 'dock'].includes(brief.navigation.variant))) {
132
58
  throw new CliError('请记录已确认的导航类型;自定义导航还需 variant: side/top/mixed/dock', { code: 'DESIGN_PLAN_NAVIGATION_REQUIRED' });
133
59
  }
134
- const { themes, pagePatterns: patterns } = loadCatalog();
60
+ const themes = readJson(path.join(ROOT, 'templates/design-themes/index.json')).themes;
135
61
  const themeId = options.themeId || brief.visualSelection?.themeId;
136
62
  const theme = themes.find(item => item.themeId === themeId);
137
63
  if (!theme) {
138
64
  throw new CliError('请通过 --theme-id 指定已选风格对应的主题', {
139
- code: 'DESIGN_PLAN_THEME_UNKNOWN', details: { themes: themes.map(({ themeId, label }) => ({ themeId, label })), catalogCommand: 'openyida design-plan catalog --json' },
65
+ code: 'DESIGN_PLAN_THEME_UNKNOWN', details: { themes: themes.map(({ themeId, label }) => ({ themeId, label })) },
140
66
  });
141
67
  }
142
- const navTheme = theme.mode === 'creative' ? brief.visualSelection?.navigationStyle?.tone || '' : themeNavTheme(theme);
143
68
  const outputDir = path.resolve(options.outputDir || path.join('prd', project));
144
69
  const output = path.join(outputDir, 'build-plan.json');
145
70
  const guide = path.join(outputDir, 'authoring-context.md');
146
71
  const business = path.join(outputDir, 'business.json');
147
72
  const visual = path.join(outputDir, 'visual.json');
148
- const materializeCommand = `openyida design-plan materialize ${quoteArgument(output)} --business-file ${quoteArgument(business)} --visual-file ${quoteArgument(visual)} --json`;
149
- if ([output, guide, business, visual, path.join(outputDir, require('./rebase').BASE_FILE)].some(file => fs.existsSync(file))) {
73
+ if ([output, guide, business, visual].some(file => fs.existsSync(file))) {
150
74
  throw new CliError('计划或编写上下文已存在,请继续补充现有文件', { code: 'DESIGN_PLAN_ALREADY_EXISTS' });
151
75
  }
152
76
  const scopedPages = list(brief.explicitScope?.pages);
@@ -158,13 +82,11 @@ function initialize(inputPath, options = {}) {
158
82
  const { key, ...facts } = source;
159
83
  delete facts.kind;
160
84
  return { pageId: key || `page-${index + 1}`, sceneKey: key || `page-${index + 1}`, name: '', primaryTask: '',
161
- primaryUsers: [], positioning: '', blocks: [], firstScreenStructure: '', signatureInteraction: '',
162
- layoutPattern: { id: 'custom-page-pattern', reason: '', adaptations: [] },
85
+ primaryUsers: [], positioning: '', contentPriority: [], blocks: [], firstScreenStructure: '', signatureInteraction: '',
86
+ layoutPattern: { id: 'custom-page-pattern', reason: '', adaptations: [] }, contentRichness: { contentLayers: [] },
163
87
  density: '', permissionSummary: '', dataBinding: '', dataSources: [], ...facts };
164
88
  });
165
89
  const choice = brief.visualSelection || {};
166
- assertVisualFieldObjects(choice, { prefix: 'visualSelection', sourcePath: input });
167
- const visualSource = choice.visualDirection?.source || 'ai_default';
168
90
  const app = brief.resourceContext?.app || brief.resourceContext || {};
169
91
  const appConfig = { navigationType: brief.navigation.type };
170
92
  for (const key of ['appType', 'corpId', 'baseUrl']) {if (app[key]) {appConfig[key] = app[key];}}
@@ -201,7 +123,6 @@ function initialize(inputPath, options = {}) {
201
123
  return { ...model, name: model.name, formType: model.formType || '宜搭表单', description: model.description || '', fields: Array.isArray(model.fields) ? model.fields : [] };
202
124
  }), businessFlows: [], pages: { customPageDetails: pages }, execution: {
203
125
  appConfig,
204
- ...(!resourceOnly && brief.entryRecommendation ? { entryRecommendation: JSON.parse(JSON.stringify(brief.entryRecommendation)) } : {}),
205
126
  explicitScope: { ...normalizedScope, navigation: brief.navigation },
206
127
  ...(resourceOnly ? {
207
128
  sampleDataPlan: modelInputs
@@ -213,37 +134,27 @@ function initialize(inputPath, options = {}) {
213
134
  ...(choice.tokens ? { tokens: choice.tokens } : {}),
214
135
  ...(choice.evidence ? { evidence: choice.evidence } : {}),
215
136
  ...(choice.constraints ? { constraints: choice.constraints } : {}),
216
- ...(choice.creativeDirection ? { creativeDirection: choice.creativeDirection } : {}),
217
- forUser: { visualDirection: { ...(choice.visualDirection || { label: theme.label, description: theme.styleSummary }), source: visualSource },
218
- colorStrategy: { primaryColor: '', primaryColorName: '', source: '', usage: '', ...normalizeColorStrategy(choice.colorStrategy) },
219
- navigationStyle: { structure: '', source: '', selectionReason: '', ...(choice.navigationStyle || {}), tone: navTheme, toneSource: theme.mode === 'creative' ? 'project_defined' : 'theme_derived' },
220
- pageApplications: pages.map(page => ({ pageId: page.pageId, firstScreenFocus: '', layout: '', responsive: '', primaryAction: '', acceptanceChecks: [],
221
- visualMemoryApplications: [], ...list(choice.pageApplications).find(item => item?.pageId === page.pageId) })),
222
- ...(choice.assetStrategy ? { assetStrategy: choice.assetStrategy } : {}),
223
- ...(choice.iconSystem ? { iconSystem: choice.iconSystem } : {}) },
224
- internal: { selectedTheme: { themeId, source: visualSource } },
137
+ forUser: { visualDirection: choice.visualDirection || { label: theme.label, description: theme.description, source: 'user_selected' },
138
+ colorStrategy: { primaryColor: '', primaryColorName: '', source: '', usage: '', surfaceTone: 'brand-tinted', ...choice.colorStrategy },
139
+ navigationStyle: choice.navigationStyle || { structure: '', tone: '', source: '', selectionReason: '' },
140
+ pageApplications: pages.map(page => ({ pageId: page.pageId, visualMemoryApplications: [] })),
141
+ ...(choice.assetStrategy ? { assetStrategy: choice.assetStrategy } : {}) },
142
+ internal: { selectedTheme: { themeId, source: 'user_selected' } },
225
143
  },
226
144
  askhuman: {},
227
145
  };
228
146
  // Keep the business description and visual memory rules verbatim; the renderer consumes the full template.
229
- const template = fs.readFileSync(themeTemplatePath(theme), 'utf8');
230
- const overview = template.match(/^## 1\. 风格摘要\n([\s\S]*?)(?=^## |$(?![\s\S]))/m)?.[0];
231
- if (!overview) {throw new CliError('主题缺少风格摘要,请检查模板', { code: 'DESIGN_PLAN_THEME_CONTEXT_MISSING' });}
147
+ const template = fs.readFileSync(path.join(ROOT, theme.templatePath), 'utf8');
148
+ const overview = template.match(/^## 设计总览\n([\s\S]*?)(?=^## |$(?![\s\S]))/m)?.[0];
149
+ if (!overview) {throw new CliError('主题缺少设计总览,请检查模板', { code: 'DESIGN_PLAN_THEME_CONTEXT_MISSING' });}
150
+ const patterns = readJson(path.join(ROOT, 'templates/page-patterns/index.json')).patterns;
232
151
  const context = [
233
152
  '# 计划编写上下文', '', `需求事实:${input}`, `计划目录:${outputDir}`, '',
234
- `读取本上下文、编写契约和 business.json;按 authoring.pendingFields 补齐事实,保留 base 与已有需求。business facts 填写 overview、dataModels、businessFlows、pages 和可选 execution;视觉填写 visual.json。复核业务覆盖后设置片段 ready=true,再执行:${materializeCommand}。使用成功结果中的 HTML 路径展示“当前方案”,revision 仅放在内部确认字段,不写入用户可见标题、摘要或问题。视觉片段按每页实际任务补齐焦点、布局、主操作、响应式与验收;已完成的选择直接复用。`, '',
235
- '## 本轮编写重点', '设计功能范围、数据与规则、页面组织、关键交互和业务验收。页面 blocks 按优先顺序填写 {name,purpose};CLI 派生默认内容优先级与内容层次,保留明确填写的独立设计。通用状态和验收检查由 CLI 补齐,interactionStates 与 acceptanceCriteria 填写项目差异。', '',
236
- '首页按使用者的主要任务选择:集中办事可用门户式工作台(workbench),单项任务可直达原生业务页;只有已确认的指标分析或投屏监控任务才规划 dashboard/screen。工作台按需求组织待办、操作队列、业务列表和常用入口,辅助统计不改变页面主任务。不得从后台身份、系统名称或暗色风格自动增加驾驶舱。完整规则见 yida-requirement-analysis/references/experience-groups.md 的“首页按任务选择”。', '',
237
- '无论是否分前后台,每个业务入口都要确定默认页面、菜单及分组顺序、打开后的首屏任务。menu 数组记录展示顺序,defaultMenuKey 记录默认任务;按角色需求决定,不按资源创建先后排列。平台导航通过排序命令落实,自定义导航通过页面菜单落实,frontend-only 也必须完成入口排序与首页验收。', '',
238
- '入口方案沿用 execution.entryRecommendation:unified 表示不分前后台,service-management 表示分前后台,frontend-only 表示只有访问前台,backend-only 表示只有访问后台。向用户说明谁使用、看到什么、能做什么;只有前台且提交后需要处理时,在 reason 和业务流程中说明承接方式;逐入口补齐 role、menu 和 defaultMenuKey,前台关联独立页面 sceneKey。任何身份的入口含 local 菜单时,entry.sceneKey 必须关联承载页面,menu.resource 等于页面 name,viewKey 非空。管理端可直接落到原生业务视图,不强制创建首页。所有叶子菜单按资源、视图和操作记录 access 权限依赖,平台导航排序从管理菜单派生。详见 yida-app/references/entry-navigation.md。', '',
239
- theme.mode === 'creative'
240
- ? '保留 visual.json 中 facts.visualStyle.forUser.visualDirection 和 navigationStyle 的对象结构;自由创意需明确填写 structure=top|side 和 tone=light|dark,并配套导航 Token。'
241
- : `保留 visual.json 中 facts.visualStyle.forUser.visualDirection 和 navigationStyle 的对象结构,只补齐内部字段;前者包含 label/description,后者只需维护 structure=top|side。tone=${navTheme} 由已选主题模板派生,不要修改。`, '',
153
+ `先读 build-plan-compact-schema.md,再读 init 已创建的 business.json;保留 base 并一次补完 facts 后写回。business facts 只能包含 overview、dataModels、businessFlows、pages 和可选 execution,不得写 visualStyle。写完后只执行一次:openyida design-plan materialize ${output} --business-file ${business} --visual-file ${visual} --json。标准首版禁止先调用 --from-preview、preview、--check 或无参数 materialize,也不要用 Glob 或额外 Read 检查产物;成功结果已返回 HTML 路径和 revision。只有视觉选择不完整或存在品牌稿、参考图、逐页特殊视觉要求时才补充视觉。保留页面 ID 与已有需求细节。`, '',
242
154
  '## 页面模式', ...patterns.map(item => `- ${item.id}(${item.label}):${item.mustKeep.join(';')}`), '',
243
155
  `## 已选风格:${theme.label}`, overview.trim(), '',
244
- '平台变量清单是基础契约,不是主题能力上限。visualStyle.tokens 可新增项目命名空间的材质、布局、字体、动效和组件状态变量,并在设计正文说明消费位置;平台变量可引用同一主题中已声明且无循环的扩展变量。不要为一次性页面样式强制新增 token。', '',
245
- 'Fast 和 Plan 使用同一主题的颜色、圆角、间距和组件规则。主色按主题公式推导;已选方向承诺的画布、卡片、填充、字体或辅助色与模板不同时,由设计者将差异写入 visualStyle.tokens。description 和 colorStrategy.usage 不会自动转换为 CSS;物化后核对主题变量,再交接页面引用,不能在各页另写固定基础色盘。详见 yida-design/references/application-theme-consistency.md。根背景的渐变使用 --pod-app-root-bg-image,单页装饰写入该页设计。', '',
246
- '完整主题的 token、组件和状态规则由 CLI 注入 design.md。逐页补齐 pageApplications.firstScreenFocus、layout、responsive 和 acceptanceChecks,并在 primaryAction 写明真实主操作及所在位置;这些字段记录基于真实业务和所选主题做出的最终设计决定,不能仅写继承主题。旧计划缺项时继续补充原计划,预览可保持草稿,最终物化前必须完整。', '',
156
+ '用户确认的配色优先于模板固定灰阶:surfaceTone=brand-tinted 将浅色页面、填充和边界与主色协调,正文保留中性层级;用户明确只改强调色、保持中性或忠实参考配色时设为 theme。深色表面保留原层级。不要为了模板的无彩限制撤掉用户要求的品牌氛围。', '',
157
+ '完整主题的 token、组件、状态和响应式规则由 CLI 注入 design.md;调整具体组件时按需读取对应模板章节。', '',
247
158
  ].join('\n');
248
159
  const base = planBase(plan);
249
160
  const businessFacts = Object.fromEntries(
@@ -256,30 +167,24 @@ function initialize(inputPath, options = {}) {
256
167
  && plan.dataModels.every(model => model.name && list(model.fields).length > 0
257
168
  && model.fields.every(field => field?.name && field?.type && typeof field.required === 'boolean'));
258
169
  const businessPart = `${JSON.stringify({ base, ready: businessReady, facts: businessFacts }, null, 2)}\n`;
259
- // Reuse the selected theme; page-specific design remains required for custom pages.
170
+ // The intake already records an atomic visual selection. Seed it here so a
171
+ // standard first Plan only needs one model planning pass for business facts.
260
172
  const selectedVisual = plan.visualStyle.forUser;
261
173
  const visualReady = /^#[0-9a-f]{6}$/i.test(selectedVisual.colorStrategy.primaryColor || '')
262
174
  && ['top', 'side'].includes(selectedVisual.navigationStyle.structure)
263
175
  && ['light', 'dark'].includes(selectedVisual.navigationStyle.tone)
264
- && ['label', 'description'].every(key => typeof selectedVisual.visualDirection[key] === 'string' && selectedVisual.visualDirection[key].trim())
265
- && !collectIssues(plan).some(issue => issue.path.startsWith('visualStyle.forUser.pageApplications[')
266
- || issue.path.startsWith('visualStyle.creativeDirection.') || issue.path.startsWith('visualStyle.tokens.'));
176
+ && ['label', 'description'].every(key => typeof selectedVisual.visualDirection[key] === 'string' && selectedVisual.visualDirection[key].trim());
267
177
  const visualPart = `${JSON.stringify({ base, ready: visualReady, facts: { visualStyle: plan.visualStyle } }, null, 2)}\n`;
268
- const authoring = authoringGuidance(plan, business, visual, businessReady, visualReady);
269
- const formatContext = ['## 输入格式示例', '示例仅说明格式,按当前业务填写。', '```json', JSON.stringify(authoring.examples, null, 2), '```', '', authoring.completion, ''].join('\n');
270
- const baseline = path.join(outputDir, require('./rebase').BASE_FILE);
271
- writeFiles([[output, `${JSON.stringify(plan, null, 2)}\n`], [baseline, `${JSON.stringify({ schemaVersion: 1, base, plan }, null, 2)}\n`], [guide, context + formatContext], [business, businessPart], [visual, visualPart]]);
178
+ writeFiles([[output, `${JSON.stringify(plan, null, 2)}\n`], [guide, context], [business, businessPart], [visual, visualPart]]);
272
179
  return { success: true, input, output, context: guide, contract: path.join(ROOT, 'references/build-plan-compact-schema.md'), draft: true,
273
180
  materialize: { mode: 'complete_files_once', maxCalls: 1,
274
- shell: process.platform === 'win32' ? 'powershell' : 'posix',
275
- command: materializeCommand },
181
+ command: `openyida design-plan materialize ${output} --business-file ${business} --visual-file ${visual} --json` },
276
182
  parallelTasks: [...(!businessReady ? [{ id: 'business', skill: 'yida-prd', output: business, dependsOn: [] }] : []),
277
- ...(!visualReady ? [{ id: 'visual-design', skill: 'yida-design', output: visual, dependsOn: !businessReady && pages.length ? ['business'] : [] }] : [])],
183
+ ...(!visualReady ? [{ id: 'visual-selection', skill: 'yida-design', output: visual, dependsOn: [] }] : [])],
278
184
  preparedInputs: { business, businessReady, visual, visualReady },
279
- authoring: { pendingFields: authoring.pendingFields, completion: authoring.completion, visualDecision: authoring.visualDecision },
280
185
  optionalTasks: [{ id: 'visual-refinement', skill: 'yida-design', input: business, output: visual, dependsOn: ['business'],
281
186
  when: 'brand material, reference images, or explicit page-specific visual differences require refinement' }],
282
187
  };
283
188
  }
284
189
 
285
- module.exports = { initialize, catalog };
190
+ module.exports = { initialize };