cardbuddy 0.14.3 → 0.16.0

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 (108) hide show
  1. package/dist/cli.js +0 -0
  2. package/dist/preview-editor/assets/index-BkbBxDTT.css +1 -0
  3. package/dist/preview-editor/assets/index-Bro07DTa.js +313 -0
  4. package/dist/preview-editor/index.html +2 -2
  5. package/dist/standalone.js +3 -0
  6. package/dist/vendored/card-editor/runtime/adapter.js +2 -2
  7. package/dist/vendored/mcp/client.mjs +9 -2
  8. package/dist/vendored/server/core/ai-chat.js +1702 -134
  9. package/dist/vendored/server/core/browser.js +12 -3
  10. package/dist/vendored/server/core/cardFiles.js +3 -0
  11. package/dist/vendored/server/core/cardHistory.js +1 -0
  12. package/dist/vendored/server/core/cardImportMeta.js +7 -6
  13. package/dist/vendored/server/core/cardOpenFolder.js +1 -0
  14. package/dist/vendored/server/core/cardSave.js +1 -0
  15. package/dist/vendored/server/core/cardSync.js +3 -0
  16. package/dist/vendored/server/core/cardValidate.js +16 -5
  17. package/dist/vendored/server/core/codeBridge.js +5 -1
  18. package/dist/vendored/server/core/logStream.js +1 -0
  19. package/dist/vendored/server/core/sliceStatic.js +24 -4
  20. package/dist/vendored/server/core/sliceUpload.js +1 -0
  21. package/dist/vendored/server/core/turnJournal.js +6 -0
  22. package/dist/vendored/skills/card-skill-trainer/SKILL.md +257 -201
  23. package/dist/vendored/skills/card-skill-trainer/scripts/diagnose_case.mjs +14 -82
  24. package/dist/vendored/skills/card-skill-trainer/scripts/lib/diagnosis.mjs +207 -0
  25. package/dist/vendored/skills/card-skill-trainer/scripts/lib/layout-correction-sim.mjs +62 -0
  26. package/dist/vendored/skills/card-skill-trainer/scripts/lib/paradigm-router.mjs +76 -0
  27. package/dist/vendored/skills/card-skill-trainer/scripts/lib/pixel-worker-runner.mjs +31 -0
  28. package/dist/vendored/skills/card-skill-trainer/scripts/lib/pixel-worker.mjs +138 -0
  29. package/dist/vendored/skills/card-skill-trainer/scripts/lib/scoring.mjs +24 -20
  30. package/dist/vendored/skills/card-skill-trainer/scripts/lib/telemetry.mjs +46 -0
  31. package/dist/vendored/skills/card-skill-trainer/scripts/plan_next_round.mjs +4 -1
  32. package/dist/vendored/skills/card-skill-trainer/scripts/run_round.mjs +279 -90
  33. package/dist/vendored/skills/card-skill-trainer/scripts/score_round.mjs +74 -2
  34. package/dist/vendored/skills/card-skill-trainer/scripts/sink_rules.mjs +127 -0
  35. package/dist/vendored/skills/dsl-card-ai/SKILL.md +1 -1
  36. package/dist/vendored/skills/dsl-card-generator/SKILL.md +208 -380
  37. package/dist/vendored/skills/dsl-card-generator/references/dsl_structure.md +1 -15
  38. package/dist/vendored/skills/dsl-card-generator/references/expression_engine.md +11 -20
  39. package/dist/vendored/skills/dsl-card-generator/references/generation_pitfalls.md +233 -61
  40. package/dist/vendored/skills/dsl-card-generator/references/ir-format.md +202 -4
  41. package/dist/vendored/skills/dsl-card-generator/references/iteration_protocol.md +87 -0
  42. package/dist/vendored/skills/dsl-card-generator/references/previewer_contract.md +1 -1
  43. package/dist/vendored/skills/dsl-card-generator/references/quickref.md +42 -33
  44. package/dist/vendored/skills/dsl-card-generator/references/recipe_snippets/title-underline-overlay.json +59 -11
  45. package/dist/vendored/skills/dsl-card-generator/references/recipes.md +44 -8
  46. package/dist/vendored/skills/dsl-card-generator/references/rules.md +26 -6
  47. package/dist/vendored/skills/dsl-card-generator/references/scripts_reference.md +54 -0
  48. package/dist/vendored/skills/dsl-card-generator/references/semantic_adjudication.md +23 -0
  49. package/dist/vendored/skills/dsl-card-generator/references/slices_convention.md +6 -6
  50. package/dist/vendored/skills/dsl-card-generator/references/spec_to_schema_patterns.md +33 -4
  51. package/dist/vendored/skills/dsl-card-generator/references/ui_fidelity_rules.md +13 -1
  52. package/dist/vendored/skills/dsl-card-generator/scripts/add_component.mjs +5 -14
  53. package/dist/vendored/skills/dsl-card-generator/scripts/autofix_schema.py +133 -2
  54. package/dist/vendored/skills/dsl-card-generator/scripts/check_fidelity.mjs +226 -19
  55. package/dist/vendored/skills/dsl-card-generator/scripts/check_magic_values.mjs +6 -1
  56. package/dist/vendored/skills/dsl-card-generator/scripts/check_topology.py +0 -35
  57. package/dist/vendored/skills/dsl-card-generator/scripts/crop_slices.mjs +92 -6
  58. package/dist/vendored/skills/dsl-card-generator/scripts/expand_ir.mjs +277 -27
  59. package/dist/vendored/skills/dsl-card-generator/scripts/gate.mjs +147 -0
  60. package/dist/vendored/skills/dsl-card-generator/scripts/generate_cards.mjs +12 -8
  61. package/dist/vendored/skills/dsl-card-generator/scripts/ir_merge.mjs +288 -0
  62. package/dist/vendored/skills/dsl-card-generator/scripts/ir_restore.mjs +175 -0
  63. package/dist/vendored/skills/dsl-card-generator/scripts/iterate.mjs +1015 -54
  64. package/dist/vendored/skills/dsl-card-generator/scripts/lib/component_contract.mjs +315 -0
  65. package/dist/vendored/skills/dsl-card-generator/scripts/lib/geometry_audit.mjs +131 -0
  66. package/dist/vendored/skills/dsl-card-generator/scripts/lib/layout-tokens.mjs +1 -1
  67. package/dist/vendored/skills/dsl-card-generator/scripts/lib/layout_rules.mjs +160 -0
  68. package/dist/vendored/skills/dsl-card-generator/scripts/lib/paths.mjs +23 -0
  69. package/dist/vendored/skills/dsl-card-generator/scripts/lib/paths.py +0 -37
  70. package/dist/vendored/skills/dsl-card-generator/scripts/lib/python.mjs +99 -0
  71. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/adaptive-width.mjs +105 -0
  72. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/bindings.mjs +260 -0
  73. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/expr.mjs +52 -0
  74. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/image.mjs +96 -0
  75. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/registry.mjs +166 -0
  76. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/structure.mjs +127 -0
  77. package/dist/vendored/skills/dsl-card-generator/scripts/lib/rules/walk.mjs +61 -0
  78. package/dist/vendored/skills/dsl-card-generator/scripts/lib/scope_alias.mjs +125 -0
  79. package/dist/vendored/skills/dsl-card-generator/scripts/lib/slicePath.mjs +17 -5
  80. package/dist/vendored/skills/dsl-card-generator/scripts/lib/slice_dedupe.mjs +102 -0
  81. package/dist/vendored/skills/dsl-card-generator/scripts/lib/v3_assemble.mjs +5727 -0
  82. package/dist/vendored/skills/dsl-card-generator/scripts/lib/v3_extract.mjs +4214 -0
  83. package/dist/vendored/skills/dsl-card-generator/scripts/lib/v3_shared.mjs +1110 -0
  84. package/dist/vendored/skills/dsl-card-generator/scripts/lint_card.mjs +322 -71
  85. package/dist/vendored/skills/dsl-card-generator/scripts/preflight.mjs +87 -43
  86. package/dist/vendored/skills/dsl-card-generator/scripts/readiness.mjs +634 -0
  87. package/dist/vendored/skills/dsl-card-generator/scripts/register_card_template.mjs +5 -8
  88. package/dist/vendored/skills/dsl-card-generator/scripts/render_card.mjs +91 -43
  89. package/dist/vendored/skills/dsl-card-generator/scripts/route_input.mjs +7 -11
  90. package/dist/vendored/skills/dsl-card-generator/scripts/spec_audit.mjs +272 -46
  91. package/dist/vendored/skills/dsl-card-generator/scripts/spec_to_schema_v3.mjs +43 -10499
  92. package/dist/vendored/skills/dsl-card-generator/scripts/v3_regression.mjs +188 -0
  93. package/dist/vendored/skills/dsl-card-generator/scripts/validate_schema.py +23 -15
  94. package/dist/vendored/skills/shared/exit-codes.md +79 -0
  95. package/dist/vendored/skills/shared/spec-contract.md +118 -0
  96. package/dist/vendored/skills/sketch-spec-to-card/SKILL.md +43 -20
  97. package/dist/vendored/skills/sketch-spec-to-card/references/spec-schema.md +4 -4
  98. package/dist/vendored/skills/sketch-spec-to-card/scripts/build_prompt.py +47 -9
  99. package/dist/vendored/skills/sketch-spec-to-card/scripts/cluster_states.py +14 -25
  100. package/dist/vendored/skills/sketch-spec-to-card/scripts/parse_meaxure.py +546 -91
  101. package/dist/vendored/skills/sketch-spec-to-card/scripts/png_utils.py +51 -5
  102. package/dist/vendored/skills/sketch-spec-to-card/scripts/test_text_only_artboard.py +217 -0
  103. package/dist/vendored/skills/sketch-spec-to-card/scripts/vision.py +64 -34
  104. package/package.json +1 -1
  105. package/dist/preview-editor/assets/index-Cm0USikc.js +0 -307
  106. package/dist/preview-editor/assets/index-cbTCHp8J.css +0 -1
  107. package/dist/vendored/skills/card-skill-trainer/scripts/test_missing_slice.py +0 -122
  108. package/dist/vendored/skills/dsl-card-generator/scripts/analyze_component_usage.mjs +0 -153
@@ -137,7 +137,7 @@ export function rectMask(normalizedRects, width, height) {
137
137
  return mask
138
138
  }
139
139
 
140
- export function imageFidelity(designBuffer, renderBuffer, exclusionRects = [], pixelOnlyRects = []) {
140
+ export function imageFidelity(designBuffer, renderBuffer, exclusionRects = [], pixelOnlyRects = [], opts = {}) {
141
141
  try {
142
142
  const designPng = PNG.sync.read(designBuffer)
143
143
  const renderPng = PNG.sync.read(renderBuffer)
@@ -166,27 +166,31 @@ export function imageFidelity(designBuffer, renderBuffer, exclusionRects = [], p
166
166
  // 诊断:最佳纵向对齐偏移(仅记录,不参与评分)。
167
167
  // 用于区分「截图裁切/节奏误差」与「真实布局错误」——
168
168
  // 禁止用对齐搜索后的差异替代零偏移差异评分,避免放宽阈值掩盖还原缺陷。
169
+ // 该扫描 13× 全图(dy -12..+12 step2),属纯诊断、不进任何门禁;默认关闭以省 CPU,
170
+ // 仅最终报告像素(run_round 显式 includeAlignDy:true)保留,供 score_round / diagnose 消费。
169
171
  let bestAlignDy = 0
170
- let bestAlignedRatio = ratio
171
- for (let dy = -12; dy <= 12; dy += 2) {
172
- let alignDiff = 0
173
- let alignCompared = 0
174
- for (let y = Math.max(0, dy); y < Math.min(height, height + dy); y += 1) {
175
- for (let x = 0; x < width; x += 1) {
176
- const leftIndex = (y * width + x) * 4
177
- const rightIndex = ((y - dy) * width + x) * 4
178
- if (rightIndex < 0 || rightIndex >= right.length) continue
179
- if (mask[leftIndex / 4]) continue
180
- alignCompared += 1
181
- if (Math.abs(left[leftIndex] - right[rightIndex]) > 15 ||
182
- Math.abs(left[leftIndex + 1] - right[rightIndex + 1]) > 15 ||
183
- Math.abs(left[leftIndex + 2] - right[rightIndex + 2]) > 15) alignDiff += 1
172
+ if (opts.includeAlignDy) {
173
+ let bestAlignedRatio = ratio
174
+ for (let dy = -12; dy <= 12; dy += 2) {
175
+ let alignDiff = 0
176
+ let alignCompared = 0
177
+ for (let y = Math.max(0, dy); y < Math.min(height, height + dy); y += 1) {
178
+ for (let x = 0; x < width; x += 1) {
179
+ const leftIndex = (y * width + x) * 4
180
+ const rightIndex = ((y - dy) * width + x) * 4
181
+ if (rightIndex < 0 || rightIndex >= right.length) continue
182
+ if (mask[leftIndex / 4]) continue
183
+ alignCompared += 1
184
+ if (Math.abs(left[leftIndex] - right[rightIndex]) > 15 ||
185
+ Math.abs(left[leftIndex + 1] - right[rightIndex + 1]) > 15 ||
186
+ Math.abs(left[leftIndex + 2] - right[rightIndex + 2]) > 15) alignDiff += 1
187
+ }
188
+ }
189
+ const alignedRatio = alignDiff / Math.max(1, alignCompared)
190
+ if (alignedRatio < bestAlignedRatio - 0.005) {
191
+ bestAlignedRatio = alignedRatio
192
+ bestAlignDy = dy
184
193
  }
185
- }
186
- const alignedRatio = alignDiff / Math.max(1, alignCompared)
187
- if (alignedRatio < bestAlignedRatio - 0.005) {
188
- bestAlignedRatio = alignedRatio
189
- bestAlignDy = dy
190
194
  }
191
195
  }
192
196
 
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 训练 telemetry 纯函数集(2026-09-25):PNG 尺寸嗅探、视觉 token 估算、阶段计时器。
3
+ * run_round.mjs 消费;tools/tests/trainer-telemetry.test.mjs 直测本模块
4
+ * (run_round.mjs 底部 main() 无条件执行,不可被测试 import)。
5
+ */
6
+
7
+ // PNG 尺寸只读 IHDR 头(前 24 字节),不做全图解压;非 PNG / 截断 buffer 返回 null。
8
+ export function pngSize(buffer) {
9
+ if (!buffer || buffer.length < 24 || buffer.readUInt32BE(0) !== 0x89504e47) return null
10
+ try { return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20) } } catch { return null }
11
+ }
12
+
13
+ // 视觉模型图像 token 口径:面积 / 750(Claude 视觉近似)。用于估算 Agent 在环归因的
14
+ // 证据包成本——训练闭环中真实发生的 token 消耗在「失败案例的多模态归因」,不在 v3 生成
15
+ // (v3 是纯规则引擎,0 LLM 调用)。口径只作预算参考,不参与任何门禁。
16
+ export function estimateImageTokens(width, height) {
17
+ return Math.ceil(((width || 0) * (height || 0)) / 750)
18
+ }
19
+
20
+ export function estimateReviewTokens({ designBuffer, renderBuffer, specChars }) {
21
+ const d = pngSize(designBuffer)
22
+ const r = pngSize(renderBuffer)
23
+ const imageTokens = estimateImageTokens(d?.width, d?.height) + estimateImageTokens(r?.width, r?.height)
24
+ const textTokens = Math.ceil((specChars || 0) / 4)
25
+ return { imageTokens, textTokens, total: imageTokens + textTokens }
26
+ }
27
+
28
+ // P1-2:在环归因改以结构化「diagnosis」证据包为主、双 PNG 为 fallback,故新增纯文本 token
29
+ // 估算(结构化包已是 JSON 文本,无图像 token)。返回形状与 estimateReviewTokens 一致,便于
30
+ // telemetry 直接累加。口径只作预算参考,不参与任何门禁。
31
+ export function estimateStructuredReviewTokens(diagnosis) {
32
+ const len = diagnosis ? JSON.stringify(diagnosis).length : 0
33
+ const textTokens = Math.ceil(len / 4)
34
+ return { imageTokens: 0, textTokens, total: textTokens }
35
+ }
36
+
37
+ // 阶段计时器:timings 阶段名 → 累计 ms;同步/异步两种包裹(finally 保证异常也计时)。
38
+ export function createStageTimer() {
39
+ const timings = {}
40
+ const record = (name, ms) => { timings[name] = (timings[name] || 0) + ms }
41
+ return {
42
+ timings,
43
+ time(name, fn) { const t0 = Date.now(); try { return fn() } finally { record(name, Date.now() - t0) } },
44
+ async timeAsync(name, fn) { const t0 = Date.now(); try { return await fn() } finally { record(name, Date.now() - t0) } },
45
+ }
46
+ }
@@ -26,6 +26,7 @@ import {
26
26
  MASK_REVIEW_THRESHOLD,
27
27
  } from './lib/scoring.mjs'
28
28
  import { compareRounds, listRounds, loadRunReports, loadRunSummary, roundMetrics } from './lib/runs.mjs'
29
+ import { enrichSameSignatureDetail } from './lib/paradigm-router.mjs'
29
30
 
30
31
  const repoRoot = path.resolve(import.meta.dirname, '../../..')
31
32
 
@@ -320,9 +321,11 @@ function main() {
320
321
 
321
322
  const signals = []
322
323
  for (const item of history.repeatedSignatures) {
324
+ const enriched = enrichSameSignatureDetail(item)
323
325
  signals.push({
324
326
  signal: 'same-signature-3-rounds',
325
- detail: `签名 ${item.signature} 在 ${item.occurrences} 轮重复出现(${item.rounds.join(' → ')}):脚本补丁无效,需升级 Skill 级范式`,
327
+ detail: enriched.detail,
328
+ paradigm: enriched.pattern,
326
329
  })
327
330
  }
328
331
  const series = history.marginal?.series || []