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
@@ -1,392 +0,0 @@
1
- <template>
2
- <div class="aiset__mask" @click.self="$emit('close')">
3
- <section class="aiset" role="dialog" aria-modal="true" aria-label="AI 模型设置">
4
- <header class="aiset__head">
5
- <svg class="aiset__head-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-sparkles" /></svg>
6
- <span class="aiset__title">模型设置</span>
7
- <button type="button" class="aiset__x" title="关闭" @click="$emit('close')">
8
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-x" /></svg>
9
- </button>
10
- </header>
11
-
12
- <!-- 字段说明一律收进「?」浮层:面板只留标签 + 控件,需要时点开看详情 -->
13
- <div class="aiset__body">
14
- <div class="aiset__field">
15
- <div class="aiset__labelrow">
16
- <label class="aiset__label" for="aiset-baseurl">Base URL</label>
17
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'baseUrl' }" :aria-expanded="help === 'baseUrl'" title="查看说明" @click.stop="toggleHelp('baseUrl')">
18
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
19
- </button>
20
- </div>
21
- <input id="aiset-baseurl" v-model="form.baseUrl" class="aiset__input" type="text" placeholder="https://api.example.com/v1" spellcheck="false" autocomplete="off" />
22
- <p v-if="help === 'baseUrl'" class="aiset__pop">OpenAI 兼容网关的基址,<strong>不含</strong> <code>/chat/completions</code> 后缀(后端会自己拼)。例:<code>https://api.openai.com/v1</code>。</p>
23
- </div>
24
-
25
- <div class="aiset__field">
26
- <div class="aiset__labelrow">
27
- <label class="aiset__label" for="aiset-model">模型名</label>
28
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'model' }" :aria-expanded="help === 'model'" title="查看说明" @click.stop="toggleHelp('model')">
29
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
30
- </button>
31
- </div>
32
- <input id="aiset-model" v-model="form.model" class="aiset__input" type="text" placeholder="gpt-4o / GLM-4.6 / deepseek-chat" spellcheck="false" autocomplete="off" />
33
- <p v-if="help === 'model'" class="aiset__pop">必须与网关侧的模型标识完全一致。建卡这类多步工具调用建议用支持 function calling 的模型。</p>
34
- </div>
35
-
36
- <div class="aiset__field">
37
- <div class="aiset__labelrow">
38
- <label class="aiset__label" for="aiset-key">API Key</label>
39
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'apiKey' }" :aria-expanded="help === 'apiKey'" title="查看说明" @click.stop="toggleHelp('apiKey')">
40
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
41
- </button>
42
- </div>
43
- <div class="aiset__keywrap">
44
- <input
45
- id="aiset-key"
46
- v-model="form.apiKey"
47
- class="aiset__input aiset__input--key"
48
- :type="reveal ? 'text' : 'password'"
49
- :placeholder="keyPlaceholder"
50
- spellcheck="false"
51
- autocomplete="off"
52
- />
53
- <button
54
- type="button"
55
- class="aiset__eye"
56
- :title="reveal ? '掩码显示密钥' : '明文显示密钥'"
57
- :aria-pressed="reveal"
58
- @click="reveal = !reveal"
59
- >
60
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use :href="reveal ? '#icon-eye-off' : '#icon-eye'" /></svg>
61
- </button>
62
- </div>
63
- <p v-if="help === 'apiKey'" class="aiset__pop">
64
- 密钥保存在项目根 <code>.env.cb.local</code>(个人覆盖层,已被 .gitignore 忽略,不会进版本库)。
65
- 打开面板自动回填已保存的密钥(默认掩码),点输入框尾部小眼睛切换明文;<strong>清空后保存即删除</strong>已保存的密钥。
66
- </p>
67
- </div>
68
-
69
- <div class="aiset__field">
70
- <div class="aiset__labelrow">
71
- <label class="aiset__label">单次输出上限</label>
72
- <span class="aiset__unit">max_tokens</span>
73
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'maxTokens' }" :aria-expanded="help === 'maxTokens'" title="查看说明" @click.stop="toggleHelp('maxTokens')">
74
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
75
- </button>
76
- </div>
77
- <div class="aiset__stepperrow">
78
- <NumberStepper
79
- id="aiset-maxtok"
80
- class="aiset__stepper"
81
- :value="form.maxTokens > 0 ? String(form.maxTokens) : ''"
82
- :step="1024"
83
- :min="0"
84
- :max="262144"
85
- :placeholder="maxTokensPlaceholder"
86
- @input="onMaxTokens"
87
- />
88
- <button type="button" class="aiset__btn" :disabled="probing || saving || testing" @click="probe">
89
- {{ probing ? '探测中…' : '探测' }}
90
- </button>
91
- </div>
92
- <p v-if="maxTokensOver" class="aiset__warnline">
93
- 超过网关已知上限 {{ knownCapLimit }}:对话时会主动夹取到该值,建议留空走自动
94
- </p>
95
- <p v-if="help === 'maxTokens'" class="aiset__pop">
96
- <strong>普通用户不用管这一项:留空 = 自动</strong>。后端自己协商:先读网关
97
- <code>/v1/models</code> 的上下文窗口(免费、毫秒级,最多等 2 秒,超时先用默认 24576 开跑),
98
- 拿到后取 <code>min(窗口, 32768)</code> 当作单次输出上限(输出预算 ≠ 上下文窗口,建卡一轮 32k 足够)。
99
- 读不到元数据也不会偷偷发试探请求;想知道窗口多大就点「探测」做一次二分试探(会产生一次真实补全,约十几秒)。
100
- 手填值超过网关接受上限时,对话开跑前会主动夹取并说明;真被 400 拒绝才会自动减半重试,
101
- 减半成功的值记为「接受上限」(**不是窗口**:窗口与输出上限是两回事,有网关窗口 262144 但 max_tokens 硬上限 131072)。
102
- 只有某轮明确报「被单次输出上限截断」才需要手填更大值。注意:推理模型的思考过程也算进这个上限。
103
- <br />当前自动生效值:<strong>{{ config.maxTokens > 0 ? config.maxTokens : 24576 }}</strong>;
104
- 网关上下文窗口:{{ config.maxTokensWindow > 0 ? config.maxTokensWindow : '未拿到(网关可能不提供元数据)' }};
105
- 接受的单次输出上限:{{ config.maxTokensCap > 0 ? config.maxTokensCap : '未知(点「探测」,或撞过一次 400 后自动回写)' }}。
106
- </p>
107
- </div>
108
-
109
- <div class="aiset__field">
110
- <div class="aiset__labelrow">
111
- <label class="aiset__label">单轮步数上限</label>
112
- <span class="aiset__unit">0 / 留空 = 不限</span>
113
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'maxSteps' }" :aria-expanded="help === 'maxSteps'" title="查看说明" @click.stop="toggleHelp('maxSteps')">
114
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
115
- </button>
116
- </div>
117
- <div class="aiset__stepperrow">
118
- <NumberStepper
119
- id="aiset-maxsteps"
120
- class="aiset__stepper"
121
- :value="form.maxSteps > 0 ? String(form.maxSteps) : ''"
122
- :step="8"
123
- :min="0"
124
- :max="1000"
125
- placeholder="留空 = 不限(推荐)"
126
- @input="onMaxSteps"
127
- />
128
- </div>
129
- <p v-if="help === 'maxSteps'" class="aiset__pop">
130
- <strong>普通用户不用管这一项:留空 = 不限</strong>。设计稿建卡一轮要连跑
131
- <code>spec_audit → crop_slices → expand_ir → iterate × N → check_fidelity</code> 十几到几十次调用,
132
- 硬顶只会把用户变成「继续」按钮,而步数多本身不代表 AI 在空转。
133
- 失控由三道<strong>精准熔断</strong>兜住:①连续 3 轮「同工具 + 同参数」判定原地打转,跳过执行并收尾汇报
134
- ②单轮墙钟到点(<code>AI_TURN_TIMEOUT_MS</code>,默认 {{ turnTimeoutMinutes }} 分钟,用到 80% 先催收敛)
135
- ③每 24 步注入一次收敛提醒(不打断)。任何一种收尾都会给出「做到哪 / 卡在哪 / 下一步说什么」,上下文不丢,回复「继续」接着做。
136
- 另外单轮上下文超预算时会自动折叠<strong>早期</strong>工具结果与图像(最近 10 条保持原文),避免撑爆网关窗口。
137
- 只有想硬性控成本时才填一个数(>0 即恢复旧行为:剩 2 步催收敛、到顶收尾汇总)。
138
- </p>
139
- </div>
140
-
141
- <div class="aiset__field">
142
- <!-- 仅「勾选框 + 标题」包进 label:点说明 / 问号不应误触开关 -->
143
- <div class="aiset__labelrow">
144
- <span class="aiset__label">深度思考</span>
145
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'thinking' }" :aria-expanded="help === 'thinking'" title="查看说明" @click.stop="toggleHelp('thinking')">
146
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
147
- </button>
148
- <Switch v-model="form.thinking" class="aiset__switch" />
149
- </div>
150
- <p v-if="help === 'thinking'" class="aiset__pop">
151
- 开启:模型先长篇推理再动手,规划更稳但慢很多、更费 token。关闭:直接出结果,实测同一网关快数倍。
152
- 关闭依赖网关支持 <code>chat_template_kwargs.enable_thinking</code>(vLLM / SGLang 系);网关不认时后端会自动回退成带思考并在对话里提示一次。
153
- 另外,<strong>某一轮思考超时</strong>时后端会自动只在那一轮关闭深度思考并重试,逼出结果。
154
- </p>
155
- </div>
156
-
157
- <div class="aiset__field">
158
- <div class="aiset__labelrow">
159
- <span class="aiset__label">多模态视觉</span>
160
- <button type="button" class="aiset__help" :class="{ 'is-on': help === 'vision' }" :aria-expanded="help === 'vision'" title="查看说明" @click.stop="toggleHelp('vision')">
161
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use href="#icon-help" /></svg>
162
- </button>
163
- <Switch v-model="form.vision" class="aiset__switch" />
164
- </div>
165
- <p v-if="help === 'vision'" class="aiset__pop">
166
- 开启后首轮对话会<strong>自动探测</strong>网关是否真支持图像(比较带图 / 不带图的 prompt_tokens):支持则把渲染截图、设计稿 vs 渲染并排对比图、你挂载的图片注入上下文,AI 可直接读图找差异;
167
- 不支持会自动降级为数值闭环(pixelDiff.match)并在对话里提示一次。注入前降采样到长边 ≤ 1024px / ≤ 900KB,每轮最多 2 张;对话记录落盘不含图像。
168
- </p>
169
- </div>
170
-
171
- <div v-if="ping" class="aiset__ping" :class="ping.ok ? 'is-ok' : 'is-bad'">
172
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
173
- <use :href="ping.ok ? '#icon-check' : '#icon-alert-triangle'" />
174
- </svg>
175
- <span>{{ ping.text }}</span>
176
- </div>
177
- </div>
178
-
179
- <footer class="aiset__foot">
180
- <button type="button" class="aiset__btn" :disabled="testing || saving" @click="test">
181
- <svg class="aiset__btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><use :href="testing ? '#icon-loading' : '#icon-activity'" /></svg>
182
- <span>{{ testing ? '测试中…' : '测试连接' }}</span>
183
- </button>
184
- <span class="aiset__foot-gap"></span>
185
- <button type="button" class="aiset__btn" :disabled="saving" @click="$emit('close')">取消</button>
186
- <button type="button" class="aiset__btn aiset__btn--primary" :disabled="saving || testing" @click="save">
187
- {{ saving ? '保存中…' : '保存' }}
188
- </button>
189
- </footer>
190
- </section>
191
- </div>
192
- </template>
193
-
194
- <script>
195
- import NumberStepper from './NumberStepper.vue'
196
- import Switch from './Switch.vue'
197
- import { saveAiConfig, pingAi, fetchAiConfig, probeMaxTokens } from '../runtime/ai-api.js'
198
-
199
- export default {
200
- name: 'AiSettings',
201
- components: { NumberStepper, Switch },
202
- props: {
203
- /** 面板已加载的配置(密钥脱敏):{ baseUrl, model, hasKey, apiKeyMasked, maxTokens, maxSteps, thinking, vision, turnTimeoutMs } */
204
- config: { type: Object, default: () => ({ baseUrl: '', model: '', hasKey: false, apiKeyMasked: '' }) },
205
- },
206
- emits: ['close', 'saved'],
207
- data() {
208
- return {
209
- form: {
210
- baseUrl: this.config.baseUrl || '',
211
- model: this.config.model || '',
212
- apiKey: '',
213
- thinking: this.config.thinking !== false,
214
- vision: this.config.vision === true,
215
- // 留空(0) = 自动:后端按网关窗口协商;不再预填默认值误导用户以为必须填
216
- // maxTokensAuto = 用户没手填过,即使后端回了「自动解析出的实际值」也保持输入框空白
217
- maxTokens: this.config.maxTokensAuto ? 0 : Number(this.config.maxTokens) > 0 ? Number(this.config.maxTokens) : 0,
218
- // 单轮步数上限:0 / 留空 = 不限(默认)。>0 才恢复旧硬顶行为
219
- maxSteps: Number(this.config.maxSteps) > 0 ? Number(this.config.maxSteps) : 0,
220
- },
221
- reveal: false,
222
- saving: false,
223
- testing: false,
224
- probing: false,
225
- ping: null,
226
- /** 当前展开的字段说明(null = 全部收起):一次只开一个,点面板外或 Esc 关闭 */
227
- help: null,
228
- /** 已存密钥是否成功回填:回填成功时输入框即真值(清空保存 = 删除密钥) */
229
- keyLoaded: false,
230
- }
231
- },
232
- computed: {
233
- /** 墙钟上限(分钟):后端按 AI_TURN_TIMEOUT_MS 回传,面板只做人话展示 */
234
- turnTimeoutMinutes() {
235
- const ms = Number(this.config.turnTimeoutMs) > 0 ? Number(this.config.turnTimeoutMs) : 3600000
236
- return Math.round(ms / 60000)
237
- },
238
- /** 占位符直接把「自动」解析成的实际值告诉用户:不用猜该填多大 */
239
- /** 网关已知上限:接受的输出上限优先(减半 / 试探证据),缺时退窗口(窗口也是必 400 的绝对边界) */
240
- knownCapLimit() {
241
- const cap = Number(this.config.maxTokensCap) > 0 ? Number(this.config.maxTokensCap) : 0
242
- if (cap) return cap
243
- return Number(this.config.maxTokensWindow) > 0 ? Number(this.config.maxTokensWindow) : 0
244
- },
245
- /** 手填值超网关已知上限:输入框下红线提示 */
246
- maxTokensOver() {
247
- return this.knownCapLimit > 0 && this.form.maxTokens > this.knownCapLimit
248
- },
249
- maxTokensPlaceholder() {
250
- const n = Number(this.config.maxTokens) > 0 ? Number(this.config.maxTokens) : 0
251
- return n > 0 ? `留空 = 自动(当前按 ${n})` : '留空 = 自动'
252
- },
253
- keyPlaceholder() {
254
- if (this.keyLoaded) return this.form.apiKey ? '' : '已保存的密钥为空,请填写新密钥'
255
- if (this.config.hasKey) return `已保存(${this.config.apiKeyMasked || '••••'}),回显失败:留空沿用、填写覆盖`
256
- return 'sk-…'
257
- },
258
- },
259
- created() {
260
- this.loadKey()
261
- },
262
- mounted() {
263
- document.addEventListener('click', this.onDocClick, true)
264
- document.addEventListener('keydown', this.onKeydown)
265
- },
266
- beforeUnmount() {
267
- document.removeEventListener('click', this.onDocClick, true)
268
- document.removeEventListener('keydown', this.onKeydown)
269
- },
270
- methods: {
271
- toggleHelp(id) {
272
- this.help = this.help === id ? null : id
273
- },
274
- /** 点浮层与问号以外的任意处即收起(捕获阶段,避免被 stopPropagation 挡住) */
275
- onDocClick(e) {
276
- if (!this.help) return
277
- const el = e.target
278
- if (el instanceof Element && el.closest('.aiset__pop, .aiset__help')) return
279
- this.help = null
280
- },
281
- onKeydown(e) {
282
- if (e.key === 'Escape' && this.help) {
283
- e.stopPropagation()
284
- this.help = null
285
- }
286
- },
287
- /** NumberStepper 原样上抛文本:这里负责解析成数字,空串 / 非法值回落默认 */
288
- onMaxTokens(text) {
289
- const n = Number(String(text).trim())
290
- this.form.maxTokens = Number.isFinite(n) && n >= 0 ? Math.round(n) : 0
291
- },
292
- /** 单轮步数上限:同上,空串 / 0 = 不限(后端据此关掉硬顶,只留熔断器) */
293
- onMaxSteps(text) {
294
- const n = Number(String(text).trim())
295
- this.form.maxSteps = Number.isFinite(n) && n > 0 ? Math.round(n) : 0
296
- },
297
- /** 探测网关窗口上限并回填:来源 models 元数据 / 二分试探 */
298
- async probe() {
299
- this.probing = true
300
- this.ping = null
301
- try {
302
- const res = await probeMaxTokens()
303
- const win = Number(res.window) > 0 ? Number(res.window) : 0
304
- const cap = Number(res.cap) > 0 ? Number(res.cap) : 0
305
- if ((win > 0 || cap > 0) && Number(res.maxTokens) > 0) {
306
- this.form.maxTokens = Number(res.maxTokens)
307
- const src =
308
- res.source === 'models-meta'
309
- ? '模型元数据'
310
- : res.source === 'probe'
311
- ? '二分试探'
312
- : res.source === 'halved'
313
- ? '减半回写'
314
- : res.source || '探测'
315
- const facts = []
316
- if (win > 0) facts.push(`上下文窗口 ${win}`)
317
- if (cap > 0) facts.push(`接受单次输出上限 ${cap}`)
318
- this.ping = {
319
- ok: true,
320
- text: `网关${facts.join('、')}(来源:${src})→ 留空自动取 ${res.maxTokens},已填入;留空保存则继续走自动`,
321
- }
322
- } else {
323
- this.ping = {
324
- ok: false,
325
- text: '探测未拿到网关窗口与接受上限(网关没提供 /v1/models 元数据,试探请求也被拒):建议留空走自动,后端用默认值并按网关反馈夹取 / 减半',
326
- }
327
- }
328
- } catch (e) {
329
- this.ping = { ok: false, text: `探测失败:${e.message || e}` }
330
- } finally {
331
- this.probing = false
332
- }
333
- },
334
- /** 回填已保存的密钥:优先 reveal 明文;旧版后端直接回明文 apiKey 字段,同样兼容 */
335
- async loadKey() {
336
- try {
337
- const cfg = await fetchAiConfig(true)
338
- const key = typeof cfg.apiKey === 'string' ? cfg.apiKey : ''
339
- if (key) {
340
- this.form.apiKey = key
341
- this.keyLoaded = true
342
- }
343
- // 自动模式(没手填)保持空白,只把解析值留在占位符里
344
- this.form.maxTokens = cfg.maxTokensAuto || !(Number(cfg.maxTokens) > 0) ? 0 : Number(cfg.maxTokens)
345
- this.form.maxSteps = Number(cfg.maxSteps) > 0 ? Number(cfg.maxSteps) : 0
346
- if (cfg.thinking !== undefined) this.form.thinking = cfg.thinking !== false
347
- if (cfg.vision !== undefined) this.form.vision = cfg.vision === true
348
- } catch {
349
- /* 回显失败退化为占位掩码提示,不阻断其它字段的保存 */
350
- }
351
- },
352
- /** 提交体:回填成功以输入框为准(空串 = 清除);未回填且未填写 → 不带 apiKey(后端保持原值) */
353
- payload() {
354
- const out = {
355
- baseUrl: this.form.baseUrl.trim(),
356
- model: this.form.model.trim(),
357
- thinking: Boolean(this.form.thinking),
358
- vision: Boolean(this.form.vision),
359
- maxTokens: Number(this.form.maxTokens) > 0 ? Number(this.form.maxTokens) : 0,
360
- maxSteps: Number(this.form.maxSteps) > 0 ? Number(this.form.maxSteps) : 0,
361
- }
362
- if (this.keyLoaded || this.form.apiKey.trim()) out.apiKey = this.form.apiKey.trim()
363
- return out
364
- },
365
- async test() {
366
- this.testing = true
367
- this.ping = null
368
- try {
369
- const res = await pingAi(this.payload())
370
- this.ping = res.ok
371
- ? { ok: true, text: `连接正常 · ${res.model || this.form.model} · ${res.latencyMs}ms${res.reply ? ` · 回复「${res.reply}」` : ''}` }
372
- : { ok: false, text: `连接失败${res.status ? `(HTTP ${res.status})` : ''}:${res.message || '未知错误'}` }
373
- } catch (e) {
374
- this.ping = { ok: false, text: `测试失败:${e.message || e}` }
375
- } finally {
376
- this.testing = false
377
- }
378
- },
379
- async save() {
380
- this.saving = true
381
- try {
382
- const res = await saveAiConfig(this.payload())
383
- this.$emit('saved', res)
384
- } catch (e) {
385
- this.ping = { ok: false, text: `保存失败:${e.message || e}` }
386
- } finally {
387
- this.saving = false
388
- }
389
- },
390
- },
391
- }
392
- </script>
@@ -1,58 +0,0 @@
1
- <!--
2
- 单张弹窗卡片实例:为 alertCard 弹出的卡片提供「独立」的 cardRuntime,
3
- 使其脚本里的 this.data / this.state / setData / setRootData 都指向自身作用域,
4
- 而不是父卡片(主卡片)的作用域。渲染复用 RenderTree 同一套预览管线。
5
-
6
- 同时把弹窗卡片内部的「绑定错误 / 接口调用」转发到主运行时(mainRt),
7
- 以便右侧调试面板能像主卡片一样看到弹窗卡片的运行情况。
8
- -->
9
- <script>
10
- import { h } from 'vue'
11
- import Adapter from '@/runtime/adapter.js'
12
- import { createCardRuntime } from '@/runtime/card-runtime.js'
13
- import RenderTree from './RenderTree.vue'
14
-
15
- export default {
16
- name: 'AlertCardInstance',
17
- components: { RenderTree },
18
- props: {
19
- entry: { type: Object, required: true },
20
- mainRt: { type: Object, default: null },
21
- },
22
- data() {
23
- const adapter = new Adapter()
24
- const cardRuntime = createCardRuntime(this.entry.scope, adapter)
25
-
26
- // 转发弹窗卡片的绑定错误 / 接口调用到主运行时,方便调试面板查看
27
- const mainRt = this.mainRt
28
- if (mainRt && mainRt.pushError && mainRt.pushApiCall) {
29
- const origErr = cardRuntime.pushError.bind(cardRuntime)
30
- cardRuntime.pushError = (k, m) => {
31
- origErr(k, m)
32
- mainRt.pushError(k, m)
33
- }
34
- const origApi = cardRuntime.pushApiCall.bind(cardRuntime)
35
- cardRuntime.pushApiCall = (api, p) => {
36
- origApi(api, p)
37
- mainRt.pushApiCall(api, p)
38
- }
39
- }
40
-
41
- return { adapter, cardRuntime }
42
- },
43
- provide() {
44
- return {
45
- adapter: this.adapter,
46
- cardRuntime: this.cardRuntime,
47
- customComponents: {},
48
- }
49
- },
50
- render() {
51
- return h(RenderTree, {
52
- node: this.entry.preview.view,
53
- scope: this.cardRuntime.rootScope,
54
- key: this.entry.id,
55
- })
56
- },
57
- }
58
- </script>
@@ -1,59 +0,0 @@
1
- <!--
2
- 弹窗卡片图层:固定全屏遮罩 + 按 gravity 定位的卡片面板,渲染 alertStack 栈顶的卡片。
3
- 点击遮罩(仅当该弹窗 clickOutsideCanHide)关闭栈顶弹窗。
4
- -->
5
- <template>
6
- <div class="alert-layer" v-if="top">
7
- <div
8
- class="alert-mask"
9
- :class="'alert-mask--' + top.gravity"
10
- @click.self="onMaskClick(top)"
11
- >
12
- <div class="alert-panel" :style="panelStyle(top)">
13
- <AlertCardInstance
14
- :entry="top"
15
- :main-rt="mainRt"
16
- />
17
- </div>
18
- </div>
19
- </div>
20
- </template>
21
-
22
- <script>
23
- import AlertCardInstance from './AlertCardInstance.vue'
24
- import { alertStore, closeAlertCard } from '@/runtime/alert-card.js'
25
-
26
- export default {
27
- name: 'AlertCardLayer',
28
- components: { AlertCardInstance },
29
- props: {
30
- mainRt: { type: Object, default: null },
31
- },
32
- computed: {
33
- top() {
34
- // 必须先读 alertStore.stack(走对象 getter)才能收集到数组依赖,
35
- // 直接对导出的数组做索引/length 访问不会触发响应式更新。
36
- const stack = alertStore.stack
37
- return stack.length ? stack[stack.length - 1] : null
38
- },
39
- },
40
- methods: {
41
- onMaskClick(entry) {
42
- if (entry.clickOutsideCanHide) {
43
- closeAlertCard({ cardCode: entry.cardCode })
44
- }
45
- },
46
- panelStyle(entry) {
47
- const s = {}
48
- if (entry.width) s.width = entry.width + 'px'
49
- if (entry.height) s.height = entry.height + 'px'
50
- // offsetX / offsetY:在 gravity 定位基础上做平移微调
51
- const transforms = []
52
- if (entry.offsetX) transforms.push('translateX(' + entry.offsetX + 'px)')
53
- if (entry.offsetY) transforms.push('translateY(' + entry.offsetY + 'px)')
54
- if (transforms.length) s.transform = transforms.join(' ')
55
- return s
56
- },
57
- },
58
- }
59
- </script>
@@ -1,127 +0,0 @@
1
- <!--
2
- 接口调用面板:右侧常驻独立面板(由 App 顶栏按钮 / 面板内 ✕ 控制展开收起)。
3
- 展示 ynet.callJSAPI / postMessage 的调用流水,内容原属调试面板的「接口调用」tab,
4
- 拆出后调试面板聚焦「绑定数据 / 组件结构 / 卡片来源」,接口流水可常驻可视。
5
- -->
6
- <template>
7
- <aside class="apipanel">
8
- <div class="apipanel__head">
9
- <span class="apipanel__title">
10
- API调用
11
- <span v-if="apiCalls.length" class="debug__count">{{ apiCalls.length }}</span>
12
- </span>
13
- <span class="apipanel__spacer"></span>
14
- <button
15
- class="apipanel__btn"
16
- type="button"
17
- :disabled="!apiCalls.length"
18
- title="清空日志"
19
- @click="clearApiLog"
20
- >
21
- <svg width="15" height="15" viewBox="0 0 24 24" fill="none"
22
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><use href="#icon-trash" /></svg>
23
- </button>
24
- <button
25
- class="apipanel__btn"
26
- type="button"
27
- title="收起接口调用面板"
28
- @click="$emit('close')"
29
- >
30
- <svg width="15" height="15" viewBox="0 0 24 24" fill="none"
31
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="5" x2="19" y2="19" /><line x1="19" y1="5" x2="5" y2="19" /></svg>
32
- </button>
33
- </div>
34
- <div class="apipanel__body">
35
- <!-- 空状态占位:虚线圆形徽章 + 插头图标(与全局 24 网格线性图标同语言)+ 文案 + 弱提示 -->
36
- <div v-if="!apiCalls.length" class="empty-state">
37
- <span class="empty-state__badge" aria-hidden="true">
38
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
39
- <path d="M9 7V3" />
40
- <path d="M15 7V3" />
41
- <path d="M6 7h12v4a6 6 0 0 1-12 0V7z" />
42
- <path d="M12 17v4" />
43
- </svg>
44
- </span>
45
- <p class="debug__empty">暂无API调用</p>
46
- <p class="empty-state__hint">卡片事件触发 ynet.callJSAPI / postMessage 后,调用流水会实时显示在这里</p>
47
- </div>
48
- <ul class="debug__list">
49
- <li v-for="(c, i) in apiCalls" :key="i" class="debug__item debug__item--api">
50
- <div class="debug__api-row">
51
- <span class="debug__kind">{{ c.api }}</span>
52
- <button
53
- class="debug__copy-ic"
54
- type="button"
55
- :title="copiedIndex === i ? '已复制 ✓' : '复制数据(不含方法名)'"
56
- @click="copyApiPayload(c, i)"
57
- >
58
- <svg v-if="copiedIndex !== i" width="15" height="15" viewBox="0 0 24 24" fill="none"
59
- stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><use href="#icon-copy-sm" /></svg>
60
- <span v-else class="debug__copy-ok">✓</span>
61
- </button>
62
- </div>
63
- <!-- 返回数据:结构化折叠树(Chrome 控制台风格) -->
64
- <ApiPayloadTree :value="c.payload" />
65
- </li>
66
- </ul>
67
- </div>
68
- </aside>
69
- </template>
70
-
71
- <script>
72
- import ApiPayloadTree from './ApiPayloadTree.vue'
73
- import { copyText } from '@/runtime/clipboard.js'
74
-
75
- export default {
76
- name: 'ApiCallPanel',
77
- components: { ApiPayloadTree },
78
- props: {
79
- rt: { type: Object, required: true },
80
- },
81
- emits: ['close'],
82
- data() {
83
- return {
84
- // 刚复制过数据的条目下标(用于图标变 ✓ 反馈),null=无
85
- copiedIndex: null,
86
- apiCopyTimer: null,
87
- }
88
- },
89
- computed: {
90
- // 依赖 apiRev,使接口调用流水在 pushApiCall / clearApiCalls 后实时刷新
91
- // (apiCalls 本身是非响应式数组,模板直接读它不会触发重渲染)
92
- //
93
- // ⚠️ 必须 slice() 返回**新数组**,不能直接 return 原数组引用:
94
- // Vue 3.4+ 引入了「computed 值稳定性」——重算后若新值与旧值 Object.is 相等,
95
- // 就不再通知下游 effect。原数组是同一个引用,即使 apiRev 自增触发了重算,
96
- // 渲染 effect 也收不到通知,界面纹丝不动。
97
- apiCalls() {
98
- void this.rt.apiRev
99
- return this.rt.apiCalls.slice()
100
- },
101
- },
102
- methods: {
103
- /** 清空接口调用流水:调用运行时 clearApiCalls(清空数组 + 自增 apiRev),
104
- * 因 apiCalls computed 返回 slice() 新引用,触发实时重渲染 */
105
- clearApiLog() {
106
- this.rt.clearApiCalls()
107
- },
108
- /** 复制某条接口调用的「返回数据」(即 payload 全文),不含方法名(api) */
109
- async copyApiPayload(c, i) {
110
- let text = ''
111
- try {
112
- text = JSON.stringify(c.payload, null, 2)
113
- } catch {
114
- text = String(c.payload)
115
- }
116
- const ok = await copyText(text)
117
- if (ok) {
118
- this.copiedIndex = i
119
- if (this.apiCopyTimer) clearTimeout(this.apiCopyTimer)
120
- this.apiCopyTimer = setTimeout(() => {
121
- if (this.copiedIndex === i) this.copiedIndex = null
122
- }, 1500)
123
- }
124
- },
125
- },
126
- }
127
- </script>