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.
- package/README.md +21 -6
- package/dist/cli.js +17 -6
- package/dist/config.js +20 -2
- package/dist/portGuard.js +293 -0
- package/dist/preview-editor/assets/index-B4VZgNSK.css +1 -0
- package/dist/preview-editor/assets/index-jl4YJzKv.js +180 -0
- package/dist/preview-editor/index.html +2 -2
- package/dist/server-core/_vendor/finmall-env.mjs +4 -4
- package/dist/server-core/ai-chat.js +3710 -0
- package/dist/server-core/assetProxy.js +3 -22
- package/dist/server-core/buildDataFromSchema.js +36 -4
- package/dist/server-core/cardFiles.js +95 -2
- package/dist/server-core/cardImage.js +14 -0
- package/dist/server-core/cardListCache.js +0 -17
- package/dist/server-core/cardSave.js +2 -0
- package/dist/server-core/cardValidate.js +3 -0
- package/dist/server-core/index.js +6 -5
- package/dist/server-core/logStream.js +1 -6
- package/dist/server-core/sliceUpload.js +8 -1
- package/dist/standalone.js +24 -8
- package/dist/vendored/App.vue +405 -125
- package/dist/vendored/api.js +4 -4
- package/dist/vendored/assets/svgIcons/icons.svg +28 -0
- package/dist/vendored/components/AiSettings.vue +392 -0
- package/dist/vendored/components/CardGallery.vue +51 -5
- package/dist/vendored/components/ChatComposer.vue +413 -0
- package/dist/vendored/components/ChatMessage.vue +383 -0
- package/dist/vendored/components/ChatPanel.vue +937 -0
- package/dist/vendored/components/ComponentPalette.vue +1 -1
- package/dist/vendored/components/DebugPanel.vue +732 -90
- package/dist/vendored/components/Dropdown.vue +4 -2
- package/dist/vendored/components/MarkdownBody.vue +64 -0
- package/dist/vendored/components/NewCardDialog.vue +132 -0
- package/dist/vendored/components/NumberStepper.vue +125 -0
- package/dist/vendored/components/ProgressSlider.vue +9 -1
- package/dist/vendored/components/RemotePreview.vue +1 -1
- package/dist/vendored/components/StructureTree.vue +2 -2
- package/dist/vendored/main.js +1 -0
- package/dist/vendored/runtime/adapter.js +1 -1
- package/dist/vendored/runtime/ai-api.js +165 -0
- package/dist/vendored/runtime/clipboard-node.js +0 -5
- package/dist/vendored/runtime/markdown.js +140 -0
- package/dist/vendored/skills/.manifest.json +1101 -0
- package/dist/vendored/skills/dsl-card-generator/scripts/autofix_schema.py +249 -0
- package/dist/vendored/skills/dsl-card-generator/scripts/check_topology.py +678 -0
- package/dist/vendored/skills/dsl-card-generator/scripts/derive_data_json.py +81 -0
- package/dist/vendored/skills/dsl-card-generator/scripts/lib/paths.py +105 -0
- package/dist/vendored/skills/dsl-card-generator/scripts/validate_schema.py +624 -0
- package/dist/vendored/skills/finmall-card-sync/scripts/api_batch_sync.mjs +900 -0
- package/dist/vendored/skills/finmall-card-sync/scripts/slice_upload.mjs +699 -0
- package/dist/vendored/skills/shared/finmall-config.mjs +124 -0
- package/dist/vendored/styles/ai-chat.css +1850 -0
- package/dist/vendored/styles/app.css +725 -213
- package/dist/vendored/styles/card-gallery.css +48 -10
- package/dist/vendored/styles/card-select.css +13 -6
- package/dist/vendored/styles/dropdown.css +1 -2
- package/dist/vendored/styles/json-tree.css +3 -3
- package/dist/vendored/styles/node-inspector.css +13 -289
- package/dist/vendored/styles/setters.css +48 -49
- package/dist/vendored/styles/structure-tree.css +6 -11
- package/package.json +1 -1
- package/dist/preview-editor/assets/index-B9MOriNv.js +0 -80
- package/dist/preview-editor/assets/index-CwD14gm3.css +0 -1
- 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
|