@topmindspace/tms-skills 0.1.4 → 0.1.5
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/CHANGELOG.md +15 -0
- package/README.md +6 -6
- package/package.json +2 -2
- package/top-ppt-html/README.md +2 -2
- package/top-ppt-html/SKILL.md +8 -5
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +72 -27
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +72 -27
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +72 -27
- package/top-ppt-html/assets/templates/architecture.html +1 -0
- package/top-ppt-html/assets/templates/presentation.html +1 -0
- package/top-ppt-html/assets/templates/research.html +1 -0
- package/top-ppt-html/package-lock.json +2 -2
- package/top-ppt-html/package.json +2 -2
- package/top-ppt-html/references/modes.md +1 -1
- package/top-ppt-html/references/playbook.md +1 -1
- package/top-ppt-html/references/presentation-craft.md +1 -1
- package/top-ppt-html/references/tech-design.md +1 -1
- package/top-ppt-html/scripts/cross_verify.py +1 -1
- package/top-ppt-html/scripts/negative_tests.py +65 -9
- package/top-ppt-html/scripts/render_from_model.py +1 -1
- package/top-ppt-html/scripts/sync_runtime.py +10 -4
- package/top-ppt-html/scripts/validate_report.py +31 -1
|
@@ -59,6 +59,7 @@ UI = TPL_DIR / 'ui.js'
|
|
|
59
59
|
TEMPLATES = [TPL_DIR / 'presentation.html',
|
|
60
60
|
TPL_DIR / 'research.html',
|
|
61
61
|
TPL_DIR / 'architecture.html']
|
|
62
|
+
EXAMPLES = sorted((ROOT / 'assets' / 'examples').glob('*.html')) if (ROOT / 'assets' / 'examples').is_dir() else []
|
|
62
63
|
BJ = ROOT / 'scripts' / 'build_pptx.js'
|
|
63
64
|
EM = ROOT / 'scripts' / 'extract_model.py'
|
|
64
65
|
|
|
@@ -336,14 +337,19 @@ def main() -> int:
|
|
|
336
337
|
ui_repl = ('/* __TOPPPT_UI_START__ */\n'
|
|
337
338
|
'/* ══ TopPPT HTML 公共 UI 脚本(assets/templates/ui.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */\n'
|
|
338
339
|
+ ui_js + '\n/* __TOPPPT_UI_END__ */')
|
|
340
|
+
# 运行时同版本戳:对注入源 assets/pptx-export.js(rstrip 后)取 sha256[:16],
|
|
341
|
+
# 写入模板内联块,供 validate_report 比对防「模板未 sync」漂移。
|
|
342
|
+
runtime_sha = hashlib.sha256(runtime.encode('utf-8')).hexdigest()[:16]
|
|
339
343
|
runtime_repl = ('/* __TOPPPT_RUNTIME_START__ */\n'
|
|
340
344
|
'/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */\n'
|
|
345
|
+
f'/* __TOPPPT_RUNTIME_SHA__:{runtime_sha} */\n'
|
|
341
346
|
+ runtime + '\n/* __TOPPPT_RUNTIME_END__ */')
|
|
342
347
|
|
|
343
|
-
# ③ 注入三份模式模板
|
|
344
|
-
|
|
348
|
+
# ③ 注入三份模式模板 + 黄金样张(样张也内联运行时,须同戳)
|
|
349
|
+
inject_targets = list(TEMPLATES) + list(EXAMPLES)
|
|
350
|
+
for tpl in inject_targets:
|
|
345
351
|
if not tpl.exists():
|
|
346
|
-
print(f'警告:
|
|
352
|
+
print(f'警告: 模板/样张不存在 {tpl}')
|
|
347
353
|
ok = False
|
|
348
354
|
continue
|
|
349
355
|
ok = inject(tpl, ENGINE_PAT, engine_repl, '__TOPPPT_ENGINE__') and ok
|
|
@@ -649,7 +655,7 @@ process.exit(bad ? 1 : 0);
|
|
|
649
655
|
print(f' model-schema.json sha256[:16] = {ms_digest} · 页型 {n_schema_pt} 种')
|
|
650
656
|
print(f' 风格 token {n_styles} 套 · 三模式独立比例尺 {len([k for k in lc["modeTypeScale"] if not k.startswith("$")])} 套 · 页型几何 {n_pt} 组')
|
|
651
657
|
print(f' 图表登记 {n_charts} 种(原生 {n_native} / 形状 {n_shape}) · 语义字阶 {n_typo} 级 · 12 列网格 {lc["grid"]["columns"]} 列 · 布局 IR {n_slots} 页型')
|
|
652
|
-
print(' 已刷新: assets/pptx-export.js(常量块 + schema 块) · assets/style-gallery.html(常量块) · templates/{presentation,research,architecture}.html(引擎/UI
|
|
658
|
+
print(' 已刷新: assets/pptx-export.js(常量块 + schema 块) · assets/style-gallery.html(常量块) · templates/{presentation,research,architecture}.html + assets/examples/*.html(引擎/UI/运行时内联副本,含 __TOPPPT_RUNTIME_SHA__)')
|
|
653
659
|
print(f' 双端单源引用校验: {"PASS" if ok else "WARN(build_pptx 应 require layout-constants.json;extract_model 应读 model-schema.json;页型四件套与图表登记须完整)"}')
|
|
654
660
|
print(f' 说明: 页型几何 {n_pt} 组(多页型共享几何组) · schema 页型 {n_schema_pt} 种')
|
|
655
661
|
return 0
|
|
@@ -28,6 +28,8 @@ research / architecture 仍须显式传 --layout-qa(不强制)。
|
|
|
28
28
|
import sys
|
|
29
29
|
import re
|
|
30
30
|
import json
|
|
31
|
+
import hashlib
|
|
32
|
+
from typing import Optional
|
|
31
33
|
from html.parser import HTMLParser
|
|
32
34
|
from pathlib import Path
|
|
33
35
|
|
|
@@ -433,8 +435,22 @@ def _check_type_features(txt, chk, model):
|
|
|
433
435
|
f"{len(missing)} 处: {missing[:4]}" if missing else "", level="WARN")
|
|
434
436
|
|
|
435
437
|
|
|
438
|
+
RUNTIME_SHA_RE = re.compile(r'/\* __TOPPPT_RUNTIME_SHA__:([0-9a-f]{16}) \*/')
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def _pptx_export_source_sha() -> Optional[str]:
|
|
442
|
+
"""当前技能包 assets/pptx-export.js 的 sha256[:16](与 sync_runtime 注入口径一致)。"""
|
|
443
|
+
pe = Path(__file__).resolve().parent.parent / 'assets' / 'pptx-export.js'
|
|
444
|
+
try:
|
|
445
|
+
body = pe.read_text(encoding='utf-8').rstrip('\n')
|
|
446
|
+
except OSError:
|
|
447
|
+
return None
|
|
448
|
+
return hashlib.sha256(body.encode('utf-8')).hexdigest()[:16]
|
|
449
|
+
|
|
450
|
+
|
|
436
451
|
def _check_pptx_export(txt, chk):
|
|
437
|
-
"""PPTX 预览配套:有预览按钮就必须有内容模型 + 预览运行时;页面不得残留导出按钮。
|
|
452
|
+
"""PPTX 预览配套:有预览按钮就必须有内容模型 + 预览运行时;页面不得残留导出按钮。
|
|
453
|
+
另:内联运行时必须带 __TOPPPT_RUNTIME_SHA__ 且与当前 pptx-export.js 同源。"""
|
|
438
454
|
has_btn = 'id="pptPreviewBtn"' in txt
|
|
439
455
|
has_model = 'REPORT_MODEL' in txt
|
|
440
456
|
has_runtime = ('g.TopPptHtml = api' in txt) and ('function slidesXml' in txt)
|
|
@@ -445,6 +461,20 @@ def _check_pptx_export(txt, chk):
|
|
|
445
461
|
else:
|
|
446
462
|
chk("含 PPTX 预览按钮与内容模型(建议保留)",
|
|
447
463
|
has_model and has_runtime, "未集成预览按钮/模型", level="WARN")
|
|
464
|
+
# 同版本戳:有运行时块时强制核对(缺戳或漂移 = FAIL)
|
|
465
|
+
if has_runtime or '/* __TOPPPT_RUNTIME_START__ */' in txt:
|
|
466
|
+
m = RUNTIME_SHA_RE.search(txt)
|
|
467
|
+
expected = _pptx_export_source_sha()
|
|
468
|
+
if not m:
|
|
469
|
+
chk("运行时同版本戳(__TOPPPT_RUNTIME_SHA__)", False,
|
|
470
|
+
"内联运行时缺戳;请跑 scripts/sync_runtime.py")
|
|
471
|
+
elif expected is None:
|
|
472
|
+
chk("运行时同版本戳(__TOPPPT_RUNTIME_SHA__)", False,
|
|
473
|
+
"无法读取 assets/pptx-export.js 计算源哈希")
|
|
474
|
+
else:
|
|
475
|
+
got = m.group(1)
|
|
476
|
+
chk("运行时同版本戳(__TOPPPT_RUNTIME_SHA__)", got == expected,
|
|
477
|
+
f"stamp={got} ≠ source={expected}(模板未 sync 或源已改)")
|
|
448
478
|
chk("页面无 PPTX 导出按钮(仅预览 + 提示词)",
|
|
449
479
|
'id="pptxBtn"' not in txt and 'id="pptDownload"' not in txt,
|
|
450
480
|
"残留导出按钮 pptxBtn/pptDownload", level="WARN")
|