cardbuddy 0.11.0 → 0.12.1

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 (313) hide show
  1. package/README.md +46 -5
  2. package/dist/cli.js +51 -1
  3. package/dist/config.js +51 -16
  4. package/dist/core.js +2 -2
  5. package/dist/init.js +425 -0
  6. package/dist/preview-editor/assets/index-CHuGGIR3.js +276 -0
  7. package/dist/preview-editor/assets/{index-B4VZgNSK.css → index-CQScMhyg.css} +1 -1
  8. package/dist/preview-editor/index.html +2 -2
  9. package/dist/standalone.js +8 -0
  10. package/dist/vendored/mcp/client.mjs +537 -0
  11. package/dist/vendored/mcp/tools.mjs +268 -0
  12. package/dist/vendored/preview/assets/default-image.png +0 -0
  13. package/dist/{server-core → vendored/server/core}/ai-chat.js +82 -38
  14. package/dist/{server-core → vendored/server/core}/browser.js +1 -1
  15. package/dist/{server-core → vendored/server/core}/cardSave.js +8 -3
  16. package/dist/{server-core → vendored/server/core}/cardSync.js +6 -14
  17. package/dist/{server-core → vendored/server/core}/cardValidate.js +11 -8
  18. package/dist/{server-core → vendored/server/core}/index.js +5 -3
  19. package/dist/vendored/server/core/skillPaths.js +124 -0
  20. package/dist/{server-core → vendored/server/core}/sliceUpload.js +5 -8
  21. package/dist/vendored/skills/README.md +93 -0
  22. package/dist/vendored/skills/card-doctor/SKILL.md +52 -0
  23. package/dist/vendored/skills/card-skill-trainer/SKILL.md +312 -0
  24. package/dist/vendored/skills/card-skill-trainer/baselines/v3-r038n.json +43 -0
  25. package/dist/vendored/skills/card-skill-trainer/baselines/v3-r039n.json +47 -0
  26. package/dist/vendored/skills/card-skill-trainer/baselines/v3-r050n.json +48 -0
  27. package/dist/vendored/skills/card-skill-trainer/scripts/build_dataset.py +472 -0
  28. package/dist/vendored/skills/card-skill-trainer/scripts/build_sample.mjs +162 -0
  29. package/dist/vendored/skills/card-skill-trainer/scripts/diagnose_case.mjs +241 -0
  30. package/dist/vendored/skills/card-skill-trainer/scripts/lib/scoring.mjs +525 -0
  31. package/dist/vendored/skills/card-skill-trainer/scripts/round_diff.mjs +133 -0
  32. package/dist/vendored/skills/card-skill-trainer/scripts/run_round.mjs +1043 -0
  33. package/dist/vendored/skills/card-skill-trainer/scripts/score_round.mjs +195 -0
  34. package/dist/vendored/skills/card-skill-trainer/scripts/test_missing_slice.py +122 -0
  35. package/dist/vendored/skills/dsl-card-ai/SKILL.md +191 -0
  36. package/dist/vendored/skills/dsl-card-generator/SKILL.md +480 -0
  37. package/dist/vendored/skills/dsl-card-generator/config/render-contract.json +11 -0
  38. package/dist/vendored/skills/dsl-card-generator/references/amount_formatting.md +138 -0
  39. package/dist/vendored/skills/dsl-card-generator/references/card_index.json +1597 -0
  40. package/dist/vendored/skills/dsl-card-generator/references/card_templates.json +384 -0
  41. package/dist/vendored/skills/dsl-card-generator/references/card_to_summary.md +56 -0
  42. package/dist/vendored/skills/dsl-card-generator/references/component_rules.md +76 -0
  43. package/dist/vendored/skills/dsl-card-generator/references/component_specs.md +393 -0
  44. package/dist/vendored/skills/dsl-card-generator/references/dsl_structure.md +208 -0
  45. package/dist/vendored/skills/dsl-card-generator/references/event_patterns.md +287 -0
  46. package/dist/vendored/skills/dsl-card-generator/references/expression_engine.md +121 -0
  47. package/dist/vendored/skills/dsl-card-generator/references/field_name_dict.json +34 -0
  48. package/dist/vendored/skills/dsl-card-generator/references/field_naming.md +101 -0
  49. package/dist/vendored/skills/dsl-card-generator/references/generation_pitfalls.md +928 -0
  50. package/dist/vendored/skills/dsl-card-generator/references/handcrafted/README.md +69 -0
  51. package/dist/vendored/skills/dsl-card-generator/references/handcrafted/examples_index.json +2967 -0
  52. package/dist/vendored/skills/dsl-card-generator/references/handcrafted/patterns.json +2835 -0
  53. package/dist/vendored/skills/dsl-card-generator/references/handcrafted/recipes_v2.json +648 -0
  54. package/dist/vendored/skills/dsl-card-generator/references/handcrafted/recipes_v2_schema.md +295 -0
  55. package/dist/vendored/skills/dsl-card-generator/references/image_diff.md +48 -0
  56. package/dist/vendored/skills/dsl-card-generator/references/image_to_card.md +129 -0
  57. package/dist/vendored/skills/dsl-card-generator/references/ir-format.md +212 -0
  58. package/dist/vendored/skills/dsl-card-generator/references/message-center-pattern.md +149 -0
  59. package/dist/vendored/skills/dsl-card-generator/references/platform_jsapi.md +196 -0
  60. package/dist/vendored/skills/dsl-card-generator/references/previewer_contract.md +54 -0
  61. package/dist/vendored/skills/dsl-card-generator/references/quickref.md +197 -0
  62. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/absolute-badge.json +84 -0
  63. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/accordion-group-toggle.json +18 -0
  64. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/alertCard-pair.json +12 -0
  65. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/alertDialog-call.json +12 -0
  66. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/canvas-countdown.json +15 -0
  67. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/canvas-donut.json +15 -0
  68. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/canvas-gauge-score.json +11 -0
  69. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/canvas-radar.json +10 -0
  70. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/canvas-title-head.json +13 -0
  71. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/globalSet.json +12 -0
  72. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/label-col-modes.json +21 -0
  73. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/list-expand-collapse.json +17 -0
  74. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/money-format.json +11 -0
  75. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/opacity-switch.json +130 -0
  76. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/progress-bar.json +25 -0
  77. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/tab-billMode.json +15 -0
  78. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/title-underline-overlay.json +21 -0
  79. package/dist/vendored/skills/dsl-card-generator/references/recipes.md +797 -0
  80. package/dist/vendored/skills/dsl-card-generator/references/rules.md +235 -0
  81. package/dist/vendored/skills/dsl-card-generator/references/slices_convention.md +177 -0
  82. package/dist/vendored/skills/dsl-card-generator/references/spec_to_schema_patterns.md +609 -0
  83. package/dist/vendored/skills/dsl-card-generator/references/ui_fidelity_rules.md +131 -0
  84. package/dist/vendored/skills/dsl-card-generator/scripts/add_component.mjs +118 -0
  85. package/dist/vendored/skills/dsl-card-generator/scripts/analyze_component_usage.mjs +153 -0
  86. package/dist/vendored/skills/dsl-card-generator/scripts/apply_opacity_pattern.mjs +343 -0
  87. package/dist/vendored/skills/dsl-card-generator/scripts/build_card_index.mjs +108 -0
  88. package/dist/vendored/skills/dsl-card-generator/scripts/build_card_templates.mjs +190 -0
  89. package/dist/vendored/skills/dsl-card-generator/scripts/check_fidelity.mjs +257 -0
  90. package/dist/vendored/skills/dsl-card-generator/scripts/check_magic_values.mjs +79 -0
  91. package/dist/vendored/skills/dsl-card-generator/scripts/crop_slices.mjs +98 -0
  92. package/dist/vendored/skills/dsl-card-generator/scripts/describe_card.mjs +265 -0
  93. package/dist/vendored/skills/dsl-card-generator/scripts/diff_bands.mjs +257 -0
  94. package/dist/vendored/skills/dsl-card-generator/scripts/diff_card.mjs +316 -0
  95. package/dist/vendored/skills/dsl-card-generator/scripts/expand_ir.mjs +873 -0
  96. package/dist/vendored/skills/dsl-card-generator/scripts/extract_handcrafted.py +1199 -0
  97. package/dist/vendored/skills/dsl-card-generator/scripts/extract_subtree.mjs +191 -0
  98. package/dist/vendored/skills/dsl-card-generator/scripts/generate_cards.mjs +389 -0
  99. package/dist/vendored/skills/dsl-card-generator/scripts/inventory_schemas.py +160 -0
  100. package/dist/vendored/skills/dsl-card-generator/scripts/iterate.mjs +700 -0
  101. package/dist/vendored/skills/dsl-card-generator/scripts/lib/design_image.mjs +56 -0
  102. package/dist/vendored/skills/dsl-card-generator/scripts/lib/design_sample.mjs +328 -0
  103. package/dist/vendored/skills/dsl-card-generator/scripts/lib/layout-tokens.mjs +79 -0
  104. package/dist/vendored/skills/dsl-card-generator/scripts/lib/paths.mjs +103 -0
  105. package/dist/vendored/skills/dsl-card-generator/scripts/lib/scaffold.mjs +575 -0
  106. package/dist/vendored/skills/dsl-card-generator/scripts/lib/slicePath.mjs +81 -0
  107. package/dist/vendored/skills/dsl-card-generator/scripts/lib/slice_dedupe.mjs +147 -0
  108. package/dist/vendored/skills/dsl-card-generator/scripts/lint_autofix.mjs +363 -0
  109. package/dist/vendored/skills/dsl-card-generator/scripts/lint_card.mjs +1399 -0
  110. package/dist/vendored/skills/dsl-card-generator/scripts/preflight.mjs +249 -0
  111. package/dist/vendored/skills/dsl-card-generator/scripts/register_card_template.mjs +208 -0
  112. package/dist/vendored/skills/dsl-card-generator/scripts/render_baseline.mjs +231 -0
  113. package/dist/vendored/skills/dsl-card-generator/scripts/render_card.mjs +801 -0
  114. package/dist/vendored/skills/dsl-card-generator/scripts/render_diff.mjs +239 -0
  115. package/dist/vendored/skills/dsl-card-generator/scripts/resolve_card_template.mjs +73 -0
  116. package/dist/vendored/skills/dsl-card-generator/scripts/route_input.mjs +447 -0
  117. package/dist/vendored/skills/dsl-card-generator/scripts/scaffold_card.mjs +81 -0
  118. package/dist/vendored/skills/dsl-card-generator/scripts/slices_normalize.mjs +316 -0
  119. package/dist/vendored/skills/dsl-card-generator/scripts/spec_audit.mjs +462 -0
  120. package/dist/vendored/skills/dsl-card-generator/scripts/spec_to_schema_v3.mjs +7735 -0
  121. package/dist/vendored/skills/dsl-card-generator/scripts/spec_tree.mjs +355 -0
  122. package/dist/vendored/skills/dsl-card-generator/scripts/validate_all_schemas.py +71 -0
  123. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/default-image-wzZYQ86K.png +0 -0
  124. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-C9k-07y7.css +1 -0
  125. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/standalone-oFRM4f4V.js +55 -0
  126. package/dist/vendored/skills/dsl-card-generator/vendor/preview/assets/svg-symbols-B2exBrAr.svg +118 -0
  127. package/dist/vendored/skills/dsl-card-generator/vendor/preview/meta/component-meta.json +2714 -0
  128. package/dist/vendored/skills/dsl-card-generator/vendor/preview/meta/directive-meta.json +40 -0
  129. package/dist/vendored/skills/dsl-card-generator/vendor/preview/meta/style-meta.json +1086 -0
  130. package/dist/vendored/{standalone.html → skills/dsl-card-generator/vendor/preview/standalone.html} +2 -1
  131. package/dist/vendored/skills/finmall-card-sync/SKILL.md +262 -0
  132. package/dist/vendored/skills/finmall-session-navigator/SKILL.md +169 -0
  133. package/dist/vendored/skills/finmall-session-navigator/scripts/finmall_login.mjs +882 -0
  134. package/dist/vendored/skills/finmall-session-navigator/scripts/package-lock.json +59 -0
  135. package/dist/vendored/skills/finmall-session-navigator/scripts/package.json +10 -0
  136. package/dist/vendored/skills/finmall-session-navigator/scripts/session-manager.mjs +96 -0
  137. package/dist/vendored/skills/shared/README.md +55 -0
  138. package/dist/vendored/skills/shared/auth-model.md +79 -0
  139. package/dist/vendored/skills/sketch-spec-to-card/SKILL.md +329 -0
  140. package/dist/vendored/skills/sketch-spec-to-card/references/boundary.json +14 -0
  141. package/dist/vendored/skills/sketch-spec-to-card/references/card_refs.json +13 -0
  142. package/dist/vendored/skills/sketch-spec-to-card/references/spec-schema.md +103 -0
  143. package/dist/vendored/skills/sketch-spec-to-card/scripts/build_prompt.py +797 -0
  144. package/dist/vendored/skills/sketch-spec-to-card/scripts/card_refs.py +94 -0
  145. package/dist/vendored/skills/sketch-spec-to-card/scripts/cluster_states.py +706 -0
  146. package/dist/vendored/skills/sketch-spec-to-card/scripts/parse_meaxure.py +1781 -0
  147. package/dist/vendored/skills/sketch-spec-to-card/scripts/png_utils.py +318 -0
  148. package/dist/vendored/skills/sketch-spec-to-card/scripts/vision.py +1118 -0
  149. package/dist/vendored/templates/helloCard/data.json +10 -0
  150. package/dist/vendored/templates/helloCard/schema.json +238 -0
  151. package/dist/vendored/tools/link-skills.mjs +485 -0
  152. package/package.json +2 -1
  153. package/dist/preview-editor/assets/index-jl4YJzKv.js +0 -180
  154. package/dist/vendored/App.vue +0 -2858
  155. package/dist/vendored/ansi.js +0 -185
  156. package/dist/vendored/assets/apple-touch-icon.png +0 -0
  157. package/dist/vendored/assets/default-image.png +0 -0
  158. package/dist/vendored/assets/favicon-16.png +0 -0
  159. package/dist/vendored/assets/favicon-32.png +0 -0
  160. package/dist/vendored/assets/site-icon.png +0 -0
  161. package/dist/vendored/assets/svgIcons/icons.svg +0 -87
  162. package/dist/vendored/assets/svgIcons/index.js +0 -39
  163. package/dist/vendored/components/AiSettings.vue +0 -392
  164. package/dist/vendored/components/AlertCardInstance.vue +0 -58
  165. package/dist/vendored/components/AlertCardLayer.vue +0 -59
  166. package/dist/vendored/components/ApiCallPanel.vue +0 -127
  167. package/dist/vendored/components/ApiPayloadTree.vue +0 -201
  168. package/dist/vendored/components/AppToast.vue +0 -37
  169. package/dist/vendored/components/CardGallery.vue +0 -291
  170. package/dist/vendored/components/CardPreview.vue +0 -72
  171. package/dist/vendored/components/CardSelect.vue +0 -206
  172. package/dist/vendored/components/ChatComposer.vue +0 -413
  173. package/dist/vendored/components/ChatMessage.vue +0 -383
  174. package/dist/vendored/components/ChatPanel.vue +0 -937
  175. package/dist/vendored/components/ComponentPalette.vue +0 -301
  176. package/dist/vendored/components/ConfirmDialog.vue +0 -54
  177. package/dist/vendored/components/DatePickerOverlay.vue +0 -345
  178. package/dist/vendored/components/DebugPanel.vue +0 -1734
  179. package/dist/vendored/components/DeviceOverlay.vue +0 -70
  180. package/dist/vendored/components/Dropdown.vue +0 -193
  181. package/dist/vendored/components/EventEditor.vue +0 -273
  182. package/dist/vendored/components/HoverGuides.vue +0 -122
  183. package/dist/vendored/components/JsonTree.vue +0 -547
  184. package/dist/vendored/components/LogValue.vue +0 -52
  185. package/dist/vendored/components/MarkdownBody.vue +0 -64
  186. package/dist/vendored/components/NewCardDialog.vue +0 -132
  187. package/dist/vendored/components/NodeInspector.vue +0 -295
  188. package/dist/vendored/components/NumberStepper.vue +0 -125
  189. package/dist/vendored/components/PickerOverlay.vue +0 -131
  190. package/dist/vendored/components/PropControl.vue +0 -245
  191. package/dist/vendored/components/PropTree.vue +0 -128
  192. package/dist/vendored/components/RemotePreview.vue +0 -173
  193. package/dist/vendored/components/SelectionOverlay.vue +0 -105
  194. package/dist/vendored/components/StructureTree.vue +0 -1002
  195. package/dist/vendored/components/Switch.vue +0 -38
  196. package/dist/vendored/components/setters/SetBgPosition.vue +0 -64
  197. package/dist/vendored/components/setters/SetBgSize.vue +0 -90
  198. package/dist/vendored/components/setters/SetCode.vue +0 -198
  199. package/dist/vendored/components/setters/SetColor.vue +0 -244
  200. package/dist/vendored/components/setters/SetCustomSelect.vue +0 -58
  201. package/dist/vendored/components/setters/SetExpr.vue +0 -107
  202. package/dist/vendored/components/setters/SetGradient.vue +0 -125
  203. package/dist/vendored/components/setters/SetGrid9.vue +0 -68
  204. package/dist/vendored/components/setters/SetIconSelect.vue +0 -67
  205. package/dist/vendored/components/setters/SetIfForm.vue +0 -61
  206. package/dist/vendored/components/setters/SetImage.vue +0 -43
  207. package/dist/vendored/components/setters/SetList.vue +0 -139
  208. package/dist/vendored/components/setters/SetNumber.vue +0 -118
  209. package/dist/vendored/components/setters/SetNumberStyle.vue +0 -113
  210. package/dist/vendored/components/setters/SetPadding.vue +0 -77
  211. package/dist/vendored/components/setters/SetSegment.vue +0 -160
  212. package/dist/vendored/components/setters/SetSelect.vue +0 -51
  213. package/dist/vendored/components/setters/SetSwitch.vue +0 -49
  214. package/dist/vendored/components/setters/SetText.vue +0 -52
  215. package/dist/vendored/components/setters/props.js +0 -23
  216. package/dist/vendored/fidelity/baseline-messageOverview.json +0 -87
  217. package/dist/vendored/fidelity/calibration.json +0 -29
  218. package/dist/vendored/fidelity/fidelity-messageOverview-after.html +0 -114
  219. package/dist/vendored/fidelity/fidelity-messageOverview-after.json +0 -272
  220. package/dist/vendored/fidelity/fidelity-messageOverview.html +0 -185
  221. package/dist/vendored/fidelity/fidelity-messageOverview.json +0 -336
  222. package/dist/vendored/fidelity/fidelity-messageOverview_v2.html +0 -262
  223. package/dist/vendored/fidelity/fidelity-messageOverview_v2.json +0 -502
  224. package/dist/vendored/fidelity/fidelity-messageOverview_v3.html +0 -201
  225. package/dist/vendored/fidelity/fidelity-messageOverview_v3.json +0 -417
  226. package/dist/vendored/fidelity/fidelity-messageOverview_visual.html +0 -125
  227. package/dist/vendored/fidelity/fidelity-messageOverview_visual.json +0 -338
  228. package/dist/vendored/index.html +0 -16
  229. package/dist/vendored/main.js +0 -37
  230. package/dist/vendored/runtime/ai-api.js +0 -165
  231. package/dist/vendored/runtime/alert-card.js +0 -125
  232. package/dist/vendored/runtime/app-toast.js +0 -33
  233. package/dist/vendored/runtime/clipboard-node.js +0 -78
  234. package/dist/vendored/runtime/clipboard.js +0 -29
  235. package/dist/vendored/runtime/event-model.js +0 -300
  236. package/dist/vendored/runtime/hoverGuide.js +0 -31
  237. package/dist/vendored/runtime/jsapi-mock.js +0 -256
  238. package/dist/vendored/runtime/markdown.js +0 -140
  239. package/dist/vendored/runtime/node-model.js +0 -217
  240. package/dist/vendored/skills/.manifest.json +0 -1101
  241. package/dist/vendored/standalone-main.js +0 -36
  242. package/dist/vendored/styles/ai-chat.css +0 -1850
  243. package/dist/vendored/styles/app.css +0 -3648
  244. package/dist/vendored/styles/card-gallery.css +0 -285
  245. package/dist/vendored/styles/card-select.css +0 -288
  246. package/dist/vendored/styles/components.css +0 -383
  247. package/dist/vendored/styles/dropdown.css +0 -324
  248. package/dist/vendored/styles/json-tree.css +0 -308
  249. package/dist/vendored/styles/node-inspector.css +0 -800
  250. package/dist/vendored/styles/setters.css +0 -1050
  251. package/dist/vendored/styles/standalone.css +0 -27
  252. package/dist/vendored/styles/structure-tree.css +0 -460
  253. /package/dist/vendored/{api.js → preview/api.js} +0 -0
  254. /package/dist/vendored/{assets → preview/assets}/svg-symbols.svg +0 -0
  255. /package/dist/vendored/{components → preview/components}/AbsoluteLayout.vue +0 -0
  256. /package/dist/vendored/{components → preview/components}/Button.vue +0 -0
  257. /package/dist/vendored/{components → preview/components}/Canvas.vue +0 -0
  258. /package/dist/vendored/{components → preview/components}/CheckGroup.vue +0 -0
  259. /package/dist/vendored/{components → preview/components}/Column.vue +0 -0
  260. /package/dist/vendored/{components → preview/components}/CustomPlaceholder.vue +0 -0
  261. /package/dist/vendored/{components → preview/components}/Divider.vue +0 -0
  262. /package/dist/vendored/{components → preview/components}/GridLayout.vue +0 -0
  263. /package/dist/vendored/{components → preview/components}/Icon.vue +0 -0
  264. /package/dist/vendored/{components → preview/components}/Image.vue +0 -0
  265. /package/dist/vendored/{components → preview/components}/Input.vue +0 -0
  266. /package/dist/vendored/{components → preview/components}/ListLayout.vue +0 -0
  267. /package/dist/vendored/{components → preview/components}/Map.vue +0 -0
  268. /package/dist/vendored/{components → preview/components}/MultiColumn.vue +0 -0
  269. /package/dist/vendored/{components → preview/components}/MultiText.vue +0 -0
  270. /package/dist/vendored/{components → preview/components}/ProgressSlider.vue +0 -0
  271. /package/dist/vendored/{components → preview/components}/RadioButton.vue +0 -0
  272. /package/dist/vendored/{components → preview/components}/RenderTree.vue +0 -0
  273. /package/dist/vendored/{components → preview/components}/Root.vue +0 -0
  274. /package/dist/vendored/{components → preview/components}/Row.vue +0 -0
  275. /package/dist/vendored/{components → preview/components}/SvgCode.vue +0 -0
  276. /package/dist/vendored/{components → preview/components}/SvgSymbols.vue +0 -0
  277. /package/dist/vendored/{components → preview/components}/Text.vue +0 -0
  278. /package/dist/vendored/{components → preview/components}/Video.vue +0 -0
  279. /package/dist/vendored/{components → preview/components}/ViewContainer.vue +0 -0
  280. /package/dist/vendored/{components → preview/components}/base.js +0 -0
  281. /package/dist/vendored/{components → preview/components}/icons.js +0 -0
  282. /package/dist/vendored/{components → preview/components}/index.js +0 -0
  283. /package/dist/vendored/{meta → preview/meta}/component-meta.json +0 -0
  284. /package/dist/vendored/{meta → preview/meta}/directive-meta.json +0 -0
  285. /package/dist/vendored/{meta → preview/meta}/style-meta.json +0 -0
  286. /package/dist/vendored/{runtime → preview/runtime}/StyleParser.js +0 -0
  287. /package/dist/vendored/{runtime → preview/runtime}/adapter.js +0 -0
  288. /package/dist/vendored/{runtime → preview/runtime}/assets.js +0 -0
  289. /package/dist/vendored/{runtime → preview/runtime}/canvas-context.js +0 -0
  290. /package/dist/vendored/{runtime → preview/runtime}/card-runtime.js +0 -0
  291. /package/dist/vendored/{runtime → preview/runtime}/evaluate.js +0 -0
  292. /package/dist/vendored/{runtime → preview/runtime}/property.js +0 -0
  293. /package/dist/vendored/{runtime → preview/runtime}/selectionOverlay.js +0 -0
  294. /package/dist/vendored/{runtime → preview/runtime}/toPreview.js +0 -0
  295. /package/dist/{server-core → vendored/server/core}/assetProxy.js +0 -0
  296. /package/dist/{server-core → vendored/server/core}/bbox.js +0 -0
  297. /package/dist/{server-core → vendored/server/core}/buildDataFromSchema.js +0 -0
  298. /package/dist/{server-core → vendored/server/core}/cardFiles.js +0 -0
  299. /package/dist/{server-core → vendored/server/core}/cardHistory.js +0 -0
  300. /package/dist/{server-core → vendored/server/core}/cardImage.js +0 -0
  301. /package/dist/{server-core → vendored/server/core}/cardImportMeta.js +0 -0
  302. /package/dist/{server-core → vendored/server/core}/cardListCache.js +0 -0
  303. /package/dist/{server-core → vendored/server/core}/cardOpenFolder.js +0 -0
  304. /package/dist/{server-core → vendored/server/core}/cardSidecar.js +0 -0
  305. /package/dist/{server-core → vendored/server/core}/codeBridge.js +0 -0
  306. /package/dist/{server-core → vendored/server/core}/logStream.js +0 -0
  307. /package/dist/{server-core → vendored/server/core}/logger.js +0 -0
  308. /package/dist/{server-core → vendored/server/core}/nodeModels.js +0 -0
  309. /package/dist/{server-core → vendored/server/core}/renderStatus.js +0 -0
  310. /package/dist/{server-core → vendored/server/core}/screenshot.js +0 -0
  311. /package/dist/{server-core → vendored/server/core}/sliceStatic.js +0 -0
  312. /package/dist/vendored/{meta → skills/dsl-card-generator/vendor/preview/meta}/action-meta.json +0 -0
  313. /package/dist/{server-core/_vendor → vendored/tools}/finmall-env.mjs +0 -0
@@ -0,0 +1,56 @@
1
+ /**
2
+ * design_image.mjs — 设计稿 card-N.png 归档到卡片目录。
3
+ *
4
+ * 约定:生成卡片时,把对应的 card-*.png 复制到卡片目录并重命名为
5
+ * <cardId>.png,使 schema.json / data.json / 设计稿参考图同目录存放。
6
+ */
7
+ import fs from 'node:fs'
8
+ import path from 'node:path'
9
+
10
+ const CARD_IMAGE_RE = /^card-\d+\.png$/i
11
+
12
+ /**
13
+ * 判断文件是否为 card-N.png 设计稿聚焦图。
14
+ *
15
+ * @param {string} p 文件路径
16
+ * @returns {boolean}
17
+ */
18
+ export function isCardDesignImage(p) {
19
+ return CARD_IMAGE_RE.test(path.basename(p || ''))
20
+ }
21
+
22
+ /**
23
+ * 把 card-*.png 设计稿复制到卡片目录并重命名为 <cardId>.png。
24
+ *
25
+ * 仅处理 card-N.png 命名的设计稿聚焦图;artboard.png 等其它图片不动。
26
+ * 源文件与目标为同一路径时跳过;复制失败不阻断主流程(返回 null)。
27
+ *
28
+ * @param {{ designPath?: string, outDir: string, cardId: string }} args
29
+ * @returns {string|null} 目标文件路径(未复制时返回 null)
30
+ */
31
+ export function copyCardDesignImage({ designPath, outDir, cardId }) {
32
+ if (!designPath || !isCardDesignImage(designPath) || !outDir || !cardId) return null
33
+ const source = path.resolve(designPath)
34
+ if (!fs.existsSync(source) || !fs.statSync(source).isFile()) return null
35
+ const target = path.join(path.resolve(outDir), `${cardId}.png`)
36
+ if (source === target) return null
37
+ try {
38
+ fs.mkdirSync(path.dirname(target), { recursive: true })
39
+ fs.copyFileSync(source, target)
40
+ return target
41
+ } catch {
42
+ return null
43
+ }
44
+ }
45
+
46
+ /**
47
+ * 定位画板目录中第 N 张卡的 card-N.png(N 从 1 开始)。
48
+ *
49
+ * @param {string} canvasDir 画板目录(如 UI/10贷款查询)
50
+ * @param {number} cardNumber 卡片序号(1-based)
51
+ * @returns {string|null} 存在则返回绝对路径,否则 null
52
+ */
53
+ export function findCardDesignImage(canvasDir, cardNumber = 1) {
54
+ const p = path.join(canvasDir, `card-${cardNumber}.png`)
55
+ return fs.existsSync(p) ? p : null
56
+ }
@@ -0,0 +1,328 @@
1
+ /**
2
+ * design_sample.mjs — 从设计稿聚焦图(card-N.png)采样顶部色带。
3
+ *
4
+ * 用途:弥散背景/浅色顶带没有切片素材时,按「缺素材用纯色」约束,
5
+ * 从设计稿截图采样带高与纯色近似值(不裁切图片,只取颜色)。
6
+ *
7
+ * 算法(纯几何 + 统计,无任何业务/样本硬编码):
8
+ * 1. 取中央竖条(30%-70% 宽)避开圆角与侧边装饰;
9
+ * 2. 每行取中位色(对文字等前景像素稳健);
10
+ * 3. 卡体基色 = 底部 8% 行中位色的中位数;
11
+ * 4. 从顶部扫描:行色与基色平均通道差 > 6 视为色带行,
12
+ * 允许开头 ≤8 CSS px 的基色行(圆角行),允许 1 行例外(抗锯齿);
13
+ * 5. 带高 ≥10 且 ≤60% 卡高才采纳。
14
+ */
15
+ import fs from 'node:fs'
16
+ import { PNG } from 'pngjs'
17
+
18
+ function median(nums) {
19
+ if (!nums.length) return 0
20
+ const sorted = [...nums].sort((a, b) => a - b)
21
+ return sorted[Math.floor(sorted.length / 2)]
22
+ }
23
+
24
+ function toHex(r, g, b) {
25
+ const c = (v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0').toUpperCase()
26
+ return `#${c(r)}${c(g)}${c(b)}`
27
+ }
28
+
29
+ /**
30
+ * @param {string} designPath 设计稿聚焦图路径
31
+ * @param {number} cardWidth 卡片宽(CSS px)
32
+ * @param {number} cardHeight 卡片高(CSS px)
33
+ * @returns {{ height: number, color: string } | null}
34
+ */
35
+ export function sampleTopBand(designPath, cardWidth, cardHeight) {
36
+ try {
37
+ if (!designPath || !fs.existsSync(designPath)) return null
38
+ const png = PNG.sync.read(fs.readFileSync(designPath))
39
+ const scale = png.width / Math.max(1, cardWidth)
40
+ if (!(scale > 0.5 && scale < 5)) return null
41
+ const { width: w, height: h, data } = png
42
+ const x0 = Math.floor(w * 0.3)
43
+ const x1 = Math.max(x0 + 2, Math.ceil(w * 0.7))
44
+
45
+ const rowMedian = (y) => {
46
+ const rs = [], gs = [], bs = []
47
+ for (let x = x0; x < x1; x += 2) {
48
+ const i = (y * w + x) * 4
49
+ rs.push(data[i]); gs.push(data[i + 1]); bs.push(data[i + 2])
50
+ }
51
+ return [median(rs), median(gs), median(bs)]
52
+ }
53
+
54
+ // 卡体基色:底部 8% 的行
55
+ const bodyRows = []
56
+ for (let y = Math.floor(h * 0.92); y < h; y++) bodyRows.push(rowMedian(y))
57
+ const body = [0, 1, 2].map((i) => median(bodyRows.map((c) => c[i])))
58
+ const dist = (a, b) => (Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]) + Math.abs(a[2] - b[2])) / 3
59
+
60
+ const maxLeadRows = Math.round(8 * scale) // 圆角保护
61
+ const bandColors = []
62
+ let bandEndRow = -1
63
+ let started = false
64
+ let exceptions = 0
65
+ for (let y = 0; y < h; y++) {
66
+ const c = rowMedian(y)
67
+ if (dist(c, body) > 6) {
68
+ started = true
69
+ bandColors.push(c)
70
+ bandEndRow = y
71
+ exceptions = 0
72
+ } else {
73
+ if (!started) {
74
+ if (y > maxLeadRows) return null // 顶部 8px 内没有出现色带 → 无顶带
75
+ continue
76
+ }
77
+ exceptions += 1
78
+ if (exceptions > 1) break // 容忍 1 行例外(分隔线/抗锯齿)
79
+ }
80
+ }
81
+ if (!started || bandEndRow < 0) return null
82
+ const heightCss = (bandEndRow + 1) / scale
83
+ // 上限 80%:整卡同色时底行=带色根本检不出带,能检出的高带(如顶面板+异色底栏)是合法形态
84
+ if (heightCss < 10 || heightCss > cardHeight * 0.8) return null
85
+ const color = toHex(
86
+ median(bandColors.map((c) => c[0])),
87
+ median(bandColors.map((c) => c[1])),
88
+ median(bandColors.map((c) => c[2])),
89
+ )
90
+ return { height: Math.round(heightCss), color }
91
+ } catch {
92
+ return null
93
+ }
94
+ }
95
+
96
+ /**
97
+ * 采样设计稿聚焦图中某个卡内区域的主色(区域中央 50% 的中位色,对内部文字稳健)。
98
+ * 用途:无导出素材的大切片(如烘焙按钮图)用纯色块近似(constraint:缺素材用纯色)。
99
+ * @param {string} designPath
100
+ * @param {number} cardWidth CSS px
101
+ * @param {{x:number,y:number,width:number,height:number}} region 卡内相对坐标
102
+ * @returns {string|null} hex 颜色
103
+ */
104
+ export function sampleRegionColor(designPath, cardWidth, region) {
105
+ try {
106
+ if (!designPath || !fs.existsSync(designPath)) return null
107
+ const png = PNG.sync.read(fs.readFileSync(designPath))
108
+ const scale = png.width / Math.max(1, cardWidth)
109
+ if (!(scale > 0.5 && scale < 5)) return null
110
+ const { width: w, height: h, data } = png
111
+ const x0 = Math.max(0, Math.round((region.x + region.width * 0.25) * scale))
112
+ const x1 = Math.min(w, Math.round((region.x + region.width * 0.75) * scale))
113
+ const y0 = Math.max(0, Math.round((region.y + region.height * 0.25) * scale))
114
+ const y1 = Math.min(h, Math.round((region.y + region.height * 0.75) * scale))
115
+ if (x1 - x0 < 2 || y1 - y0 < 2) return null
116
+ const rs = [], gs = [], bs = []
117
+ for (let y = y0; y < y1; y += 2) {
118
+ for (let x = x0; x < x1; x += 2) {
119
+ const i = (y * w + x) * 4
120
+ rs.push(data[i]); gs.push(data[i + 1]); bs.push(data[i + 2])
121
+ }
122
+ }
123
+ return toHex(median(rs), median(gs), median(bs))
124
+ } catch {
125
+ return null
126
+ }
127
+ }
128
+
129
+ /**
130
+ * 采样区域边缘条带主色(左右两条竖带的中位色,避开中央文字)。
131
+ * 用途:按钮/pill 的标注填充色与设计稿像素交叉验证——中央采样会被按钮文字污染,
132
+ * 边缘条带(圆角半径之外的纯背景区)才是填充色真值。
133
+ * @param {string} designPath
134
+ * @param {number} cardWidth CSS px
135
+ * @param {{x:number,y:number,width:number,height:number}} region 卡内相对坐标
136
+ * @returns {string|null} hex 颜色
137
+ */
138
+ export function sampleRegionEdgeColor(designPath, cardWidth, region) {
139
+ try {
140
+ if (!designPath || !fs.existsSync(designPath)) return null
141
+ const png = PNG.sync.read(fs.readFileSync(designPath))
142
+ const scale = png.width / Math.max(1, cardWidth)
143
+ if (!(scale > 0.5 && scale < 5)) return null
144
+ const { width: w, height: h, data } = png
145
+ // 条带内缩:横向 8%-22% / 78%-92%(避开圆角与中央文字),纵向 30%-70%
146
+ const y0 = Math.max(0, Math.round((region.y + region.height * 0.3) * scale))
147
+ const y1 = Math.min(h, Math.round((region.y + region.height * 0.7) * scale))
148
+ const strips = [
149
+ [Math.round((region.x + region.width * 0.08) * scale), Math.round((region.x + region.width * 0.22) * scale)],
150
+ [Math.round((region.x + region.width * 0.78) * scale), Math.round((region.x + region.width * 0.92) * scale)],
151
+ ]
152
+ const rs = [], gs = [], bs = []
153
+ for (const [sx0, sx1] of strips) {
154
+ const x0 = Math.max(0, sx0), x1 = Math.min(w, sx1)
155
+ if (x1 - x0 < 2 || y1 - y0 < 2) continue
156
+ for (let y = y0; y < y1; y += 2) {
157
+ for (let x = x0; x < x1; x += 2) {
158
+ const i = (y * w + x) * 4
159
+ rs.push(data[i]); gs.push(data[i + 1]); bs.push(data[i + 2])
160
+ }
161
+ }
162
+ }
163
+ if (!rs.length) return null
164
+ return toHex(median(rs), median(gs), median(bs))
165
+ } catch {
166
+ return null
167
+ }
168
+ }
169
+
170
+ /**
171
+ * 采样卡体主色(设计稿聚焦图中央竖条底部 8% 行的中位色)。
172
+ * 用于校验/纠正 spec cardFill 与设计稿明显不一致的情况(视觉优先)。
173
+ * @returns {string|null} hex
174
+ */
175
+ export function sampleCardBodyColor(designPath, cardWidth) {
176
+ try {
177
+ if (!designPath || !fs.existsSync(designPath)) return null
178
+ const png = PNG.sync.read(fs.readFileSync(designPath))
179
+ const scale = png.width / Math.max(1, cardWidth)
180
+ if (!(scale > 0.5 && scale < 5)) return null
181
+ const { width: w, height: h, data } = png
182
+ const x0 = Math.floor(w * 0.3)
183
+ const x1 = Math.max(x0 + 2, Math.ceil(w * 0.7))
184
+ const rs = [], gs = [], bs = []
185
+ for (let y = Math.floor(h * 0.94); y < h; y++) {
186
+ for (let x = x0; x < x1; x += 2) {
187
+ const i = (y * w + x) * 4
188
+ rs.push(data[i]); gs.push(data[i + 1]); bs.push(data[i + 2])
189
+ }
190
+ }
191
+ return toHex(median(rs), median(gs), median(bs))
192
+ } catch {
193
+ return null
194
+ }
195
+ }
196
+
197
+ /**
198
+ * 文本颜色交叉校验(标注缺陷治理,视觉优先):
199
+ * 标注 textStyle.color 与设计稿实际字形颜色明显不一致时(如设计是蓝灰字、标注写深色),
200
+ * 从设计稿聚焦图采样字形真实颜色覆盖标注。
201
+ *
202
+ * 算法(纯几何 + 统计,无业务词):
203
+ * 1. 文本所在小壳(按钮/pill)bbox 内缩 15% 取中央区(避开圆角/壳边抗锯齿);
204
+ * 2. 全区中位色 ≈ 壳底色(文字稀疏);
205
+ * 3. 与底色距离 >40 的像素视为字形;取其中亮度最低 25%(抗锯齿核心)的中位色;
206
+ * 4. 采样色与标注色平均通道差 >28 才覆盖(小差不折腾,保留标注)。
207
+ *
208
+ * @param {string} designPath 设计稿聚焦图路径(card-N.png)
209
+ * @param {number} cardWidth 卡片宽(CSS px)
210
+ * @param {{x:number,y:number,width:number,height:number}} bboxCardRel 壳 bbox(卡内相对坐标)
211
+ * @param {string} specColorHex 标注颜色(#RRGGBB)
212
+ * @returns {string|null} 需覆盖时返回采样色 #RRGGBB,否则 null
213
+ */
214
+ export function crossCheckTextColor(designPath, cardWidth, bboxCardRel, specColorHex) {
215
+ try {
216
+ if (!designPath || !fs.existsSync(designPath)) return null
217
+ const png = PNG.sync.read(fs.readFileSync(designPath))
218
+ const scale = png.width / Math.max(1, cardWidth)
219
+ if (!(scale > 0.5 && scale < 5)) return null
220
+ const { width: w, height: h, data } = png
221
+ const bx = (bboxCardRel.x || 0) * scale
222
+ const by = (bboxCardRel.y || 0) * scale
223
+ const bw = (bboxCardRel.width || 0) * scale
224
+ const bh = (bboxCardRel.height || 0) * scale
225
+ if (bw < 8 || bh < 6) return null
226
+ const x0 = Math.max(0, Math.round(bx + bw * 0.15))
227
+ const x1 = Math.min(w - 1, Math.round(bx + bw * 0.85))
228
+ const y0 = Math.max(0, Math.round(by + bh * 0.15))
229
+ const y1 = Math.min(h - 1, Math.round(by + bh * 0.85))
230
+ if (x1 - x0 < 4 || y1 - y0 < 4) return null
231
+ const rs = [], gs = [], bs = []
232
+ for (let y = y0; y <= y1; y++) {
233
+ for (let x = x0; x <= x1; x++) {
234
+ const i = (y * w + x) * 4
235
+ rs.push(data[i]); gs.push(data[i + 1]); bs.push(data[i + 2])
236
+ }
237
+ }
238
+ const bg = [median(rs), median(gs), median(bs)]
239
+ const dist = (r, g, b, t) => (Math.abs(r - t[0]) + Math.abs(g - t[1]) + Math.abs(b - t[2])) / 3
240
+ const glyphs = []
241
+ for (let k = 0; k < rs.length; k++) {
242
+ if (dist(rs[k], gs[k], bs[k], bg) > 40) {
243
+ glyphs.push([rs[k], gs[k], bs[k], rs[k] * 0.299 + gs[k] * 0.587 + bs[k] * 0.114])
244
+ }
245
+ }
246
+ if (glyphs.length < 30) return null
247
+ glyphs.sort((a, b) => a[3] - b[3])
248
+ const core = glyphs.slice(0, Math.max(10, Math.floor(glyphs.length * 0.25)))
249
+ const sampled = [
250
+ median(core.map((c) => c[0])),
251
+ median(core.map((c) => c[1])),
252
+ median(core.map((c) => c[2])),
253
+ ]
254
+ const m = String(specColorHex || '').replace('#', '')
255
+ if (!/^[0-9a-fA-F]{6}$/.test(m)) return toHex(...sampled)
256
+ const spec = [parseInt(m.slice(0, 2), 16), parseInt(m.slice(2, 4), 16), parseInt(m.slice(4, 6), 16)]
257
+ if (dist(sampled[0], sampled[1], sampled[2], spec) > 28) return toHex(...sampled)
258
+ return null
259
+ } catch {
260
+ return null
261
+ }
262
+ }
263
+
264
+ /**
265
+ * 描边环采样(标注缺陷治理,视觉优先):
266
+ * 壳标注无 fill 无 border("隐形"壳),但设计稿可见描边时(如线框 pill 按钮),
267
+ * 从设计稿采样壳边缘环带颜色,判定是否存在描边并取其颜色。
268
+ *
269
+ * 算法(纯几何 + 统计):
270
+ * 1. 壳 bbox 四边各取中段 30%-70%(避开圆角);
271
+ * 2. 环带 = bbox 边缘向内 max(1, round(1.6×scale)) px 的窄带;
272
+ * 3. 内部参照色 = 中央 30% 区域中位色;
273
+ * 4. 环带亮度最低 40% 像素的中位色与内部参照色距离 >18 → 存在描边,返回其颜色。
274
+ *
275
+ * @param {string} designPath 设计稿聚焦图路径
276
+ * @param {number} cardWidth 卡片宽(CSS px)
277
+ * @param {{x:number,y:number,width:number,height:number}} bboxCardRel 壳 bbox(卡内相对坐标)
278
+ * @returns {string|null} 描边色 #RRGGBB;无描边/采样失败返回 null
279
+ */
280
+ export function sampleOutlineRing(designPath, cardWidth, bboxCardRel) {
281
+ try {
282
+ if (!designPath || !fs.existsSync(designPath)) return null
283
+ const png = PNG.sync.read(fs.readFileSync(designPath))
284
+ const scale = png.width / Math.max(1, cardWidth)
285
+ if (!(scale > 0.5 && scale < 5)) return null
286
+ const { width: w, height: h, data } = png
287
+ const bx = Math.round((bboxCardRel.x || 0) * scale)
288
+ const by = Math.round((bboxCardRel.y || 0) * scale)
289
+ const bw = Math.round((bboxCardRel.width || 0) * scale)
290
+ const bh = Math.round((bboxCardRel.height || 0) * scale)
291
+ if (bw < 10 || bh < 8) return null
292
+ const t = Math.max(1, Math.round(1.6 * scale))
293
+ const at = (x, y) => {
294
+ const i = (Math.min(h - 1, Math.max(0, y)) * w + Math.min(w - 1, Math.max(0, x))) * 4
295
+ return [data[i], data[i + 1], data[i + 2]]
296
+ }
297
+ const ring = []
298
+ const push = (x, y) => { const c = at(x, y); ring.push([c[0], c[1], c[2], c[0] * 0.299 + c[1] * 0.587 + c[2] * 0.114]) }
299
+ for (let x = bx + Math.round(bw * 0.3); x <= bx + Math.round(bw * 0.7); x++) {
300
+ for (let k = 0; k < t; k++) { push(x, by + k); push(x, by + bh - 1 - k) }
301
+ }
302
+ for (let y = by + Math.round(bh * 0.3); y <= by + Math.round(bh * 0.7); y++) {
303
+ for (let k = 0; k < t; k++) { push(bx + k, y); push(bx + bw - 1 - k, y) }
304
+ }
305
+ if (ring.length < 20) return null
306
+ // 内部参照色(中央 30% 区域中位色)
307
+ const ir = [], ig = [], ib = []
308
+ for (let y = by + Math.round(bh * 0.35); y <= by + Math.round(bh * 0.65); y += 2) {
309
+ for (let x = bx + Math.round(bw * 0.35); x <= bx + Math.round(bw * 0.65); x += 2) {
310
+ const c = at(x, y); ir.push(c[0]); ig.push(c[1]); ib.push(c[2])
311
+ }
312
+ }
313
+ const interior = [median(ir), median(ig), median(ib)]
314
+ ring.sort((a, b) => a[3] - b[3])
315
+ const core = ring.slice(0, Math.max(8, Math.floor(ring.length * 0.4)))
316
+ const ringColor = [
317
+ median(core.map((c) => c[0])),
318
+ median(core.map((c) => c[1])),
319
+ median(core.map((c) => c[2])),
320
+ ]
321
+ const dist = (Math.abs(ringColor[0] - interior[0])
322
+ + Math.abs(ringColor[1] - interior[1])
323
+ + Math.abs(ringColor[2] - interior[2])) / 3
324
+ return dist > 18 ? toHex(...ringColor) : null
325
+ } catch {
326
+ return null
327
+ }
328
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * 布局 Token 表(消灭魔法值:gap/padding/radius/fontSize/color 一律引用此处)。
3
+ *
4
+ * 纪律(2026-08-17 L1 落地):
5
+ * - v3 生成器(spec_to_schema_v3.mjs)禁止裸数字魔法值,
6
+ * 一律引用 TOKEN.<组>.<语义名>。
7
+ * - L2 几何推导优先:spec.rect 实测值 > TOKEN(兜底)> 历史魔法值(最后兜底)。
8
+ * - 语义命名按"用途"而非"数值":GAP.base 表示组件内标准间距,不叫 GAP.eight。
9
+ * - 改值单点生效,三策略视觉统一。
10
+ */
11
+ export const TOKEN = {
12
+ /** 间距(flex gap) */
13
+ GAP: {
14
+ tight: 4, // 行内紧密元素(图标+文字、两段小字)
15
+ micro: 2, // 最密(legacy 文字列)
16
+ none: 0, // 无间距
17
+ base: 8, // 组件内标准间距(默认 Row/Column)
18
+ loose: 12, // 大区块内子区块间距
19
+ section: 16, // 段落/分组间距
20
+ huge: 24, // 大区块间距
21
+ },
22
+ /** 内边距(padding) */
23
+ PADDING: {
24
+ card: 16, // 卡片整体内边距
25
+ section: 12, // 区块内边距
26
+ item: 12, // 列表项内边距
27
+ compact: 8, // 紧凑内边距(v3 标签行/操作行)
28
+ mini: 4, // 最小内边距
29
+ micro: 2, // 极小内边距(列表行等紧凑场景兜底)
30
+ buttonH: 12, // 按钮垂直内边距
31
+ buttonW: 24, // 按钮水平内边距
32
+ root: 0, // Root 内边距(默认 0,宽度由 view.width 承载)
33
+ },
34
+ /** 圆角(borderRadius) */
35
+ RADIUS: {
36
+ root: 8, // Root 圆角
37
+ card: 12, // 卡片圆角
38
+ item: 8, // 列表项/小容器圆角
39
+ colorBlock: 6, // 背景色块圆角
40
+ button: 24, // 按钮圆角(胶囊风格)
41
+ pill: 100, // 全圆角胶囊
42
+ },
43
+ /** 字号(fontSize) */
44
+ FONT: {
45
+ body: 14, // 正文
46
+ sub: 13, // 辅助说明
47
+ small: 12, // 时间/列表小字
48
+ title: 15, // 区块标题
49
+ button: 17, // 按钮文字
50
+ buttonLegacy: 16, // legacy 生成器按钮兜底字号
51
+ large: 30, // 数字大标题
52
+ },
53
+ /** 颜色 */
54
+ COLOR: {
55
+ pageBg: '#F5F6F8', // 页面/画布背景
56
+ cardBg: '#FFFFFF', // 卡片背景
57
+ primary: '#00B578', // 品牌主色(绿,geo/v3)
58
+ primaryBlue: '#0079F2', // legacy 生成器历史主色(蓝)
59
+ fallbackBg: '#F5F5F5', // pickBg 兜底色
60
+ danger: '#F6434F', // 危险/未读红点
61
+ textMain: '#111111', // 主文字
62
+ textDefault: '#333333', // 文本兜底色(spec 未给 color 时)
63
+ blockFill: '#EDEDED', // 色块兜底色(spec 未给 fill 时)
64
+ textSub: '#555555', // 次级文字
65
+ divider: '#EEEEEE', // 分隔线
66
+ link: '#1584FF', // 链接/操作文字(蓝)
67
+ btnText: '#FFFFFF', // 按钮文字(主色底)
68
+ arrow: '#CCCCCC', // 次级箭头
69
+ },
70
+ }
71
+
72
+ /** 便捷:直接拿到字符串化的 Token 值(生成器 setStyleChild 入参用) */
73
+ export const T = {
74
+ gap: (k) => String(TOKEN.GAP[k]),
75
+ pad: (k) => String(TOKEN.PADDING[k]),
76
+ radius: (k) => String(TOKEN.RADIUS[k]),
77
+ font: (k) => String(TOKEN.FONT[k]),
78
+ color: (k) => TOKEN.COLOR[k],
79
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * paths.mjs — skill 内部路径与宿主项目路径单一来源(Node 侧)。
3
+ *
4
+ * 自包含约定:
5
+ * - skill 自身的渲染器/元数据资源固定放在 <skill>/vendor/preview;
6
+ * - 宿主项目(卡片与切图所在目录)默认是调用脚本时的 cwd,也可用环境变量覆盖;
7
+ * - 不再向上查找 package.json,因此本 skill 可整体复制到任意项目使用。
8
+ *
9
+ * 环境变量(按优先级覆盖默认值):
10
+ * DSL_CARD_PROJECT_ROOT 宿主项目根目录(默认 process.cwd())
11
+ * DSL_CARD_CARDS_DIR 卡片目录(默认 <project>/src/cards)
12
+ * DSL_CARD_SLICES_DIR 切图目录(默认 <project>/src/slices)
13
+ * DSL_CARD_META_DIR meta 元数据目录(默认 <skill>/vendor/preview/meta)
14
+ * DSL_CARD_PREVIEW_DIR 自包含预览目录(默认 <skill>/vendor/preview)
15
+ * DSL_CARD_BASELINES_DIR 渲染基线目录(默认 <project>/.card-baselines)
16
+ */
17
+ import fs from 'node:fs'
18
+ import path from 'node:path'
19
+ import { fileURLToPath } from 'node:url'
20
+
21
+ const HERE = path.dirname(fileURLToPath(import.meta.url))
22
+
23
+ /** 当前 skill 根目录:scripts/lib -> scripts -> dsl-card-generator */
24
+ export const skillRoot = path.resolve(HERE, '..', '..')
25
+
26
+ /** skill 自包含资源根目录。 */
27
+ export const vendorDir = path.join(skillRoot, 'vendor')
28
+
29
+ /** 独立卡片预览目录(vendor/preview)。 */
30
+ export const previewDir =
31
+ process.env.DSL_CARD_PREVIEW_DIR || path.join(vendorDir, 'preview')
32
+
33
+ /** meta 元数据目录。 */
34
+ export const metaDir =
35
+ process.env.DSL_CARD_META_DIR || path.join(previewDir, 'meta')
36
+
37
+ /** 宿主项目根目录(默认当前工作目录)。 */
38
+ export const projectRoot = process.env.DSL_CARD_PROJECT_ROOT || process.cwd()
39
+
40
+ /** 卡片源数据目录。 */
41
+ export const cardsDir =
42
+ process.env.DSL_CARD_CARDS_DIR || path.join(projectRoot, 'src', 'cards')
43
+
44
+ /** 切图统一落点目录。 */
45
+ export const slicesDir =
46
+ process.env.DSL_CARD_SLICES_DIR || path.join(projectRoot, 'src', 'slices')
47
+
48
+ /** 渲染回归基线目录。 */
49
+ export const baselinesDir =
50
+ process.env.DSL_CARD_BASELINES_DIR || path.join(projectRoot, '.card-baselines')
51
+
52
+ /** 兼容旧脚本的别名:宿主项目根目录。 */
53
+ export const repoRoot = projectRoot
54
+
55
+ /** skills 父目录(供需要跨 skill 的脚本使用)。 */
56
+ export const skillsDir = path.dirname(skillRoot)
57
+
58
+ /**
59
+ * 解析卡片目录的绝对路径。
60
+ * @param {string} id 卡片 id
61
+ * @returns {string} `<cardsDir>/<id>` 绝对路径
62
+ */
63
+ export function cardDir(id) {
64
+ return path.join(cardsDir, id)
65
+ }
66
+
67
+ /**
68
+ * 解析卡片 schema.json 的绝对路径。
69
+ * @param {string} id 卡片 id
70
+ * @returns {string}
71
+ */
72
+ export function cardSchemaPath(id) {
73
+ return path.join(cardsDir, id, 'schema.json')
74
+ }
75
+
76
+ /**
77
+ * 解析卡片 data.json 的绝对路径。
78
+ * @param {string} id 卡片 id
79
+ * @returns {string}
80
+ */
81
+ export function cardDataPath(id) {
82
+ return path.join(cardsDir, id, 'data.json')
83
+ }
84
+
85
+ /**
86
+ * 安全读取 JSON(不存在或解析失败时返回 fallback)。
87
+ *
88
+ * @param {string} p 路径
89
+ * @param {*} fallback 不存在/解析失败时的返回值(默认抛错)
90
+ * @returns {*} 解析后的 JS 值
91
+ */
92
+ export function readJson(p, fallback = undefined) {
93
+ if (!fs.existsSync(p)) {
94
+ if (fallback === undefined) throw new Error(`File not found: ${p}`)
95
+ return fallback
96
+ }
97
+ try {
98
+ return JSON.parse(fs.readFileSync(p, 'utf8'))
99
+ } catch (e) {
100
+ if (fallback === undefined) throw new Error(`Cannot parse JSON ${p}: ${e.message}`)
101
+ return fallback
102
+ }
103
+ }