cardbuddy 0.9.1 → 0.11.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 (64) hide show
  1. package/README.md +21 -6
  2. package/dist/cli.js +17 -6
  3. package/dist/config.js +20 -2
  4. package/dist/portGuard.js +293 -0
  5. package/dist/preview-editor/assets/index-B4VZgNSK.css +1 -0
  6. package/dist/preview-editor/assets/index-jl4YJzKv.js +180 -0
  7. package/dist/preview-editor/index.html +2 -2
  8. package/dist/server-core/_vendor/finmall-env.mjs +4 -4
  9. package/dist/server-core/ai-chat.js +3710 -0
  10. package/dist/server-core/assetProxy.js +3 -22
  11. package/dist/server-core/buildDataFromSchema.js +36 -4
  12. package/dist/server-core/cardFiles.js +95 -2
  13. package/dist/server-core/cardImage.js +14 -0
  14. package/dist/server-core/cardListCache.js +0 -17
  15. package/dist/server-core/cardSave.js +2 -0
  16. package/dist/server-core/cardValidate.js +3 -0
  17. package/dist/server-core/index.js +6 -5
  18. package/dist/server-core/logStream.js +1 -6
  19. package/dist/server-core/sliceUpload.js +8 -1
  20. package/dist/standalone.js +24 -8
  21. package/dist/vendored/App.vue +405 -125
  22. package/dist/vendored/api.js +4 -4
  23. package/dist/vendored/assets/svgIcons/icons.svg +28 -0
  24. package/dist/vendored/components/AiSettings.vue +392 -0
  25. package/dist/vendored/components/CardGallery.vue +51 -5
  26. package/dist/vendored/components/ChatComposer.vue +413 -0
  27. package/dist/vendored/components/ChatMessage.vue +383 -0
  28. package/dist/vendored/components/ChatPanel.vue +937 -0
  29. package/dist/vendored/components/ComponentPalette.vue +1 -1
  30. package/dist/vendored/components/DebugPanel.vue +732 -90
  31. package/dist/vendored/components/Dropdown.vue +4 -2
  32. package/dist/vendored/components/MarkdownBody.vue +64 -0
  33. package/dist/vendored/components/NewCardDialog.vue +132 -0
  34. package/dist/vendored/components/NumberStepper.vue +125 -0
  35. package/dist/vendored/components/ProgressSlider.vue +9 -1
  36. package/dist/vendored/components/RemotePreview.vue +1 -1
  37. package/dist/vendored/components/StructureTree.vue +2 -2
  38. package/dist/vendored/main.js +1 -0
  39. package/dist/vendored/runtime/adapter.js +1 -1
  40. package/dist/vendored/runtime/ai-api.js +165 -0
  41. package/dist/vendored/runtime/clipboard-node.js +0 -5
  42. package/dist/vendored/runtime/markdown.js +140 -0
  43. package/dist/vendored/skills/.manifest.json +1101 -0
  44. package/dist/vendored/skills/dsl-card-generator/scripts/autofix_schema.py +249 -0
  45. package/dist/vendored/skills/dsl-card-generator/scripts/check_topology.py +678 -0
  46. package/dist/vendored/skills/dsl-card-generator/scripts/derive_data_json.py +81 -0
  47. package/dist/vendored/skills/dsl-card-generator/scripts/lib/paths.py +105 -0
  48. package/dist/vendored/skills/dsl-card-generator/scripts/validate_schema.py +624 -0
  49. package/dist/vendored/skills/finmall-card-sync/scripts/api_batch_sync.mjs +900 -0
  50. package/dist/vendored/skills/finmall-card-sync/scripts/slice_upload.mjs +699 -0
  51. package/dist/vendored/skills/shared/finmall-config.mjs +124 -0
  52. package/dist/vendored/styles/ai-chat.css +1850 -0
  53. package/dist/vendored/styles/app.css +725 -213
  54. package/dist/vendored/styles/card-gallery.css +48 -10
  55. package/dist/vendored/styles/card-select.css +13 -6
  56. package/dist/vendored/styles/dropdown.css +1 -2
  57. package/dist/vendored/styles/json-tree.css +3 -3
  58. package/dist/vendored/styles/node-inspector.css +13 -289
  59. package/dist/vendored/styles/setters.css +48 -49
  60. package/dist/vendored/styles/structure-tree.css +6 -11
  61. package/package.json +1 -1
  62. package/dist/preview-editor/assets/index-B9MOriNv.js +0 -80
  63. package/dist/preview-editor/assets/index-CwD14gm3.css +0 -1
  64. package/dist/vendored/assets/logo.png +0 -0
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Derive data.json from schema.json
4
+
5
+ data.json must equal { inputParams[i].key: inputParams[i].defaultValue }.
6
+ Objects/arrays are kept as-is (no deep re-serialization).
7
+
8
+ Usage:
9
+ python3 derive_data_json.py <schema.json> # print derived data.json to stdout
10
+ python3 derive_data_json.py <schema.json> --overwrite # write data.json next to schema.json
11
+ python3 derive_data_json.py <schema.json> --check # compare with existing data.json
12
+ """
13
+
14
+ import argparse
15
+ import json
16
+ import os
17
+ import sys
18
+
19
+
20
+ def derive(schema):
21
+ params = schema.get("dictionary", {}).get("inputParams", [])
22
+ return {p["key"]: p.get("defaultValue") for p in params if "key" in p}
23
+
24
+
25
+ def main():
26
+ ap = argparse.ArgumentParser(description="Derive data.json from a card schema.json")
27
+ ap.add_argument("schema", help="path to schema.json")
28
+ ap.add_argument("--overwrite", action="store_true", help="write data.json next to schema.json")
29
+ ap.add_argument("--check", action="store_true", help="compare with existing data.json and report diffs")
30
+ args = ap.parse_args()
31
+
32
+ if not os.path.isfile(args.schema):
33
+ print(f"[ERROR] File not found: {args.schema}")
34
+ return 1
35
+
36
+ schema = json.load(open(args.schema, encoding="utf-8"))
37
+ data = derive(schema)
38
+
39
+ if args.check:
40
+ data_path = os.path.join(os.path.dirname(args.schema), "data.json")
41
+ if not os.path.isfile(data_path):
42
+ print(f"[WARN] No data.json beside schema; derived keys: {sorted(data.keys())}")
43
+ return 1
44
+ existing = json.load(open(data_path, encoding="utf-8"))
45
+ if set(data.keys()) != set(existing.keys()):
46
+ only_schema = sorted(set(data) - set(existing))
47
+ only_existing = sorted(set(existing) - set(data))
48
+ print(f"[DIFF] key sets differ")
49
+ if only_schema:
50
+ print(f" missing in data.json: {only_schema}")
51
+ if only_existing:
52
+ print(f" extra in data.json: {only_existing}")
53
+ return 1
54
+ diffs = []
55
+ for k in data:
56
+ if k == "otherLangLabels":
57
+ continue # tolerated i18n drift
58
+ if data[k] != existing.get(k):
59
+ diffs.append((k, data[k], existing.get(k)))
60
+ if diffs:
61
+ print(f"[DIFF] {len(diffs)} value mismatch(es):")
62
+ for k, exp, got in diffs:
63
+ print(f" {k}: schema={exp!r} data={got!r}")
64
+ return 1
65
+ print(f"[OK] data.json matches inputParams.defaultValue ({len(data)} keys)")
66
+ return 0
67
+
68
+ if args.overwrite:
69
+ out_path = os.path.join(os.path.dirname(args.schema), "data.json")
70
+ with open(out_path, "w", encoding="utf-8") as f:
71
+ json.dump(data, f, ensure_ascii=False, indent=2)
72
+ f.write("\n")
73
+ print(f"[OK] Wrote {out_path} ({len(data)} keys)")
74
+ return 0
75
+
76
+ print(json.dumps(data, ensure_ascii=False, indent=2))
77
+ return 0
78
+
79
+
80
+ if __name__ == "__main__":
81
+ sys.exit(main())
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ paths.py — skill 内部路径与宿主项目路径单一来源(Python 侧)。
4
+
5
+ 自包含约定:
6
+ - skill 自身的渲染器/元数据资源固定放在 <skill>/vendor/preview;
7
+ - 宿主项目(卡片与切图所在目录)默认是调用脚本时的 cwd,也可用环境变量覆盖;
8
+ - 不再向上查找 package.json,因此本 skill 可整体复制到任意项目使用。
9
+
10
+ 环境变量(按优先级覆盖默认值):
11
+ DSL_CARD_PROJECT_ROOT 宿主项目根目录(默认 Path.cwd())
12
+ DSL_CARD_CARDS_DIR 卡片目录(默认 <project>/src/cards)
13
+ DSL_CARD_SLICES_DIR 切图目录(默认 <project>/src/slices)
14
+ DSL_CARD_META_DIR meta 元数据目录(默认 <skill>/vendor/preview/meta)
15
+ DSL_CARD_PREVIEW_DIR 自包含预览目录(默认 <skill>/vendor/preview)
16
+ DSL_CARD_BASELINES_DIR 渲染基线目录(默认 <project>/.card-baselines)
17
+ """
18
+ import json
19
+ import os
20
+ from pathlib import Path
21
+
22
+ _HERE = Path(__file__).resolve().parent
23
+
24
+ # 占位 sentinel:与任何用户传入的 fallback 都不会相同的内部对象。
25
+ _MISSING = object()
26
+
27
+ # 当前 skill 根目录:scripts/lib -> scripts -> dsl-card-generator
28
+ skill_root = _HERE.parent.parent
29
+
30
+ # skill 自包含资源根目录。
31
+ vendor_dir = skill_root / "vendor"
32
+
33
+ # 独立卡片预览目录(vendor/preview)。
34
+ preview_dir = Path(
35
+ os.environ.get("DSL_CARD_PREVIEW_DIR", str(vendor_dir / "preview"))
36
+ ).resolve()
37
+
38
+ # meta 元数据目录。
39
+ meta_dir = Path(
40
+ os.environ.get("DSL_CARD_META_DIR", str(preview_dir / "meta"))
41
+ ).resolve()
42
+
43
+ # 宿主项目根目录(默认当前工作目录)。
44
+ project_root = Path(
45
+ os.environ.get("DSL_CARD_PROJECT_ROOT", str(Path.cwd()))
46
+ ).resolve()
47
+
48
+ # 卡片源数据目录。
49
+ cards_dir = Path(
50
+ os.environ.get("DSL_CARD_CARDS_DIR", str(project_root / "src" / "cards"))
51
+ ).resolve()
52
+
53
+ # 切图统一落点目录。
54
+ slices_dir = Path(
55
+ os.environ.get("DSL_CARD_SLICES_DIR", str(project_root / "src" / "slices"))
56
+ ).resolve()
57
+
58
+ # 渲染回归基线目录。
59
+ baselines_dir = Path(
60
+ os.environ.get("DSL_CARD_BASELINES_DIR", str(project_root / ".card-baselines"))
61
+ ).resolve()
62
+
63
+ # 兼容旧脚本的别名。
64
+ repo_root = project_root
65
+
66
+ # skills 父目录。
67
+ skills_dir = skill_root.parent
68
+
69
+
70
+ def card_dir(card_id: str) -> Path:
71
+ """解析卡片目录的绝对路径:`<cards_dir>/<id>`。"""
72
+ return cards_dir / card_id
73
+
74
+
75
+ def card_schema_path(card_id: str) -> Path:
76
+ """解析卡片 schema.json 的绝对路径。"""
77
+ return cards_dir / card_id / "schema.json"
78
+
79
+
80
+ def card_data_path(card_id: str) -> Path:
81
+ """解析卡片 data.json 的绝对路径。"""
82
+ return cards_dir / card_id / "data.json"
83
+
84
+
85
+ def read_json(p: Path, fallback=_MISSING):
86
+ """
87
+ 安全读取 JSON(不存在或解析失败时返回 fallback)。
88
+
89
+ Args:
90
+ p: 路径
91
+ fallback: 不存在/解析失败时的返回值。默认抛错。
92
+ Returns:
93
+ 解析后的 Python 值
94
+ """
95
+ p = Path(p)
96
+ if not p.is_file():
97
+ if fallback is _MISSING:
98
+ raise FileNotFoundError(f"File not found: {p}")
99
+ return fallback
100
+ try:
101
+ return json.loads(p.read_text(encoding="utf-8"))
102
+ except Exception as e:
103
+ if fallback is _MISSING:
104
+ raise RuntimeError(f"Cannot parse JSON {p}: {e}") from e
105
+ return fallback