@topmindspace/tms-skills 0.3.9 → 0.4.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 (161) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.en.md +11 -8
  3. package/README.md +11 -8
  4. package/bin/tms-skills.js +144 -12
  5. package/package.json +1 -1
  6. package/top-ppt-html/README.en.md +2 -2
  7. package/top-ppt-html/README.md +1 -1
  8. package/top-ppt-html/SKILL.md +8 -7
  9. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +16 -171
  10. package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.model.json +13 -3
  11. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +16 -324
  12. package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.model.json +15 -1
  13. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +16 -917
  14. package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.model.json +15 -1
  15. package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +99 -18
  16. package/top-ppt-html/assets/icons/index.json +557 -0
  17. package/top-ppt-html/assets/icons//344/270/212/344/274/240.png +0 -0
  18. package/top-ppt-html/assets/icons//344/270/212/344/274/240.svg +1 -0
  19. package/top-ppt-html/assets/icons//344/270/213/350/275/275.png +0 -0
  20. package/top-ppt-html/assets/icons//344/270/213/350/275/275.svg +1 -0
  21. package/top-ppt-html/assets/icons//344/270/213/351/231/215.png +0 -0
  22. package/top-ppt-html/assets/icons//344/270/213/351/231/215.svg +1 -0
  23. package/top-ppt-html/assets/icons//344/271/246/347/255/276.png +0 -0
  24. package/top-ppt-html/assets/icons//344/271/246/347/255/276.svg +1 -0
  25. package/top-ppt-html/assets/icons//344/272/221.png +0 -0
  26. package/top-ppt-html/assets/icons//344/272/221.svg +1 -0
  27. package/top-ppt-html/assets/icons//344/275/215/347/275/256.png +0 -0
  28. package/top-ppt-html/assets/icons//344/275/215/347/275/256.svg +1 -0
  29. package/top-ppt-html/assets/icons//344/277/241/346/201/257.png +0 -0
  30. package/top-ppt-html/assets/icons//344/277/241/346/201/257.svg +1 -0
  31. package/top-ppt-html/assets/icons//345/210/206/344/272/253.png +0 -0
  32. package/top-ppt-html/assets/icons//345/210/206/344/272/253.svg +1 -0
  33. package/top-ppt-html/assets/icons//345/213/276/351/200/211.png +0 -0
  34. package/top-ppt-html/assets/icons//345/213/276/351/200/211.svg +1 -0
  35. package/top-ppt-html/assets/icons//345/215/240/346/257/224.png +0 -0
  36. package/top-ppt-html/assets/icons//345/215/240/346/257/224.svg +1 -0
  37. package/top-ppt-html/assets/icons//345/233/242/351/230/237.png +0 -0
  38. package/top-ppt-html/assets/icons//345/233/242/351/230/237.svg +1 -0
  39. package/top-ppt-html/assets/icons//345/233/276/350/241/250.png +0 -0
  40. package/top-ppt-html/assets/icons//345/233/276/350/241/250.svg +1 -0
  41. package/top-ppt-html/assets/icons//345/242/236/351/225/277.png +0 -0
  42. package/top-ppt-html/assets/icons//345/242/236/351/225/277.svg +1 -0
  43. package/top-ppt-html/assets/icons//345/256/211/345/205/250.png +0 -0
  44. package/top-ppt-html/assets/icons//345/256/211/345/205/250.svg +1 -0
  45. package/top-ppt-html/assets/icons//345/257/271/350/257/235.png +0 -0
  46. package/top-ppt-html/assets/icons//345/257/271/350/257/235.svg +1 -0
  47. package/top-ppt-html/assets/icons//345/267/245/345/205/267.png +0 -0
  48. package/top-ppt-html/assets/icons//345/267/245/345/205/267.svg +1 -0
  49. package/top-ppt-html/assets/icons//345/276/252/347/216/257.png +0 -0
  50. package/top-ppt-html/assets/icons//345/276/252/347/216/257.svg +1 -0
  51. package/top-ppt-html/assets/icons//346/210/220/346/236/234.png +0 -0
  52. package/top-ppt-html/assets/icons//346/210/220/346/236/234.svg +1 -0
  53. package/top-ppt-html/assets/icons//346/211/213/346/234/272.png +0 -0
  54. package/top-ppt-html/assets/icons//346/211/213/346/234/272.svg +1 -0
  55. package/top-ppt-html/assets/icons//346/225/210/347/216/207.png +0 -0
  56. package/top-ppt-html/assets/icons//346/225/210/347/216/207.svg +1 -0
  57. package/top-ppt-html/assets/icons//346/225/260/346/215/256.png +0 -0
  58. package/top-ppt-html/assets/icons//346/225/260/346/215/256.svg +1 -0
  59. package/top-ppt-html/assets/icons//346/226/207/344/273/266/345/244/271.png +0 -0
  60. package/top-ppt-html/assets/icons//346/226/207/344/273/266/345/244/271.svg +1 -0
  61. package/top-ppt-html/assets/icons//346/226/207/346/241/243.png +0 -0
  62. package/top-ppt-html/assets/icons//346/226/207/346/241/243.svg +1 -0
  63. package/top-ppt-html/assets/icons//346/227/227/345/270/234.png +0 -0
  64. package/top-ppt-html/assets/icons//346/227/227/345/270/234.svg +1 -0
  65. package/top-ppt-html/assets/icons//346/227/266/351/227/264.png +0 -0
  66. package/top-ppt-html/assets/icons//346/227/266/351/227/264.svg +1 -0
  67. package/top-ppt-html/assets/icons//346/230/237/346/240/207.png +0 -0
  68. package/top-ppt-html/assets/icons//346/230/237/346/240/207.svg +1 -0
  69. package/top-ppt-html/assets/icons//346/231/272/350/203/275.png +0 -0
  70. package/top-ppt-html/assets/icons//346/231/272/350/203/275.svg +1 -0
  71. package/top-ppt-html/assets/icons//346/235/203/351/231/220.png +0 -0
  72. package/top-ppt-html/assets/icons//346/235/203/351/231/220.svg +1 -0
  73. package/top-ppt-html/assets/icons//346/243/200/346/237/245.png +0 -0
  74. package/top-ppt-html/assets/icons//346/243/200/346/237/245.svg +1 -0
  75. package/top-ppt-html/assets/icons//346/264/236/345/257/237.png +0 -0
  76. package/top-ppt-html/assets/icons//346/264/236/345/257/237.svg +1 -0
  77. package/top-ppt-html/assets/icons//346/265/201/347/250/213.png +0 -0
  78. package/top-ppt-html/assets/icons//346/265/201/347/250/213.svg +1 -0
  79. package/top-ppt-html/assets/icons//346/270/205/345/215/225.png +0 -0
  80. package/top-ppt-html/assets/icons//346/270/205/345/215/225.svg +1 -0
  81. package/top-ppt-html/assets/icons//347/201/253/347/256/255.png +0 -0
  82. package/top-ppt-html/assets/icons//347/201/253/347/256/255.svg +1 -0
  83. package/top-ppt-html/assets/icons//347/201/257/346/263/241.png +0 -0
  84. package/top-ppt-html/assets/icons//347/201/257/346/263/241.svg +1 -0
  85. package/top-ppt-html/assets/icons//347/224/250/346/210/267.png +0 -0
  86. package/top-ppt-html/assets/icons//347/224/250/346/210/267.svg +1 -0
  87. package/top-ppt-html/assets/icons//347/233/256/346/240/207.png +0 -0
  88. package/top-ppt-html/assets/icons//347/233/256/346/240/207.svg +1 -0
  89. package/top-ppt-html/assets/icons//347/256/255/345/244/264.png +0 -0
  90. package/top-ppt-html/assets/icons//347/256/255/345/244/264.svg +1 -0
  91. package/top-ppt-html/assets/icons//347/273/204/347/273/207.png +0 -0
  92. package/top-ppt-html/assets/icons//347/273/204/347/273/207.svg +1 -0
  93. package/top-ppt-html/assets/icons//347/275/227/347/233/230.png +0 -0
  94. package/top-ppt-html/assets/icons//347/275/227/347/233/230.svg +1 -0
  95. package/top-ppt-html/assets/icons//350/241/250/346/240/274.png +0 -0
  96. package/top-ppt-html/assets/icons//350/241/250/346/240/274.svg +1 -0
  97. package/top-ppt-html/assets/icons//350/256/241/345/210/222.png +0 -0
  98. package/top-ppt-html/assets/icons//350/256/241/345/210/222.svg +1 -0
  99. package/top-ppt-html/assets/icons//350/256/276/347/275/256.png +0 -0
  100. package/top-ppt-html/assets/icons//350/256/276/347/275/256.svg +1 -0
  101. package/top-ppt-html/assets/icons//350/266/213/345/212/277.png +0 -0
  102. package/top-ppt-html/assets/icons//350/266/213/345/212/277.svg +1 -0
  103. package/top-ppt-html/assets/icons//351/202/256/344/273/266.png +0 -0
  104. package/top-ppt-html/assets/icons//351/202/256/344/273/266.svg +1 -0
  105. package/top-ppt-html/assets/icons//351/207/221/351/222/261.png +0 -0
  106. package/top-ppt-html/assets/icons//351/207/221/351/222/261.svg +1 -0
  107. package/top-ppt-html/assets/icons//351/223/276/346/216/245.png +0 -0
  108. package/top-ppt-html/assets/icons//351/223/276/346/216/245.svg +1 -0
  109. package/top-ppt-html/assets/icons//351/227/252/347/224/265.png +0 -0
  110. package/top-ppt-html/assets/icons//351/227/252/347/224/265.svg +1 -0
  111. package/top-ppt-html/assets/icons//351/243/216/351/231/251.png +0 -0
  112. package/top-ppt-html/assets/icons//351/243/216/351/231/251.svg +1 -0
  113. package/top-ppt-html/assets/pptx-export.js +2 -2
  114. package/top-ppt-html/assets/style-gallery.html +1 -1
  115. package/top-ppt-html/assets/templates/architecture.html +15 -3
  116. package/top-ppt-html/assets/templates/engine.css +12 -0
  117. package/top-ppt-html/assets/templates/presentation.html +15 -3
  118. package/top-ppt-html/assets/templates/research.html +15 -3
  119. package/top-ppt-html/package-lock.json +2 -2
  120. package/top-ppt-html/package.json +2 -2
  121. package/top-ppt-html/references/icons.md +22 -19
  122. package/top-ppt-html/references/layout-variants.md +69 -0
  123. package/top-ppt-html/references/style-pack.md +40 -0
  124. package/top-ppt-html/scripts/build_pptx.js +93 -26
  125. package/top-ppt-html/scripts/check_icons.py +119 -0
  126. package/top-ppt-html/scripts/hydrate_charts.py +60 -5
  127. package/top-ppt-html/scripts/icon_lib.js +66 -37
  128. package/top-ppt-html/scripts/layout-constants.json +91 -4
  129. package/top-ppt-html/scripts/make_icon_pack.py +172 -0
  130. package/top-ppt-html/scripts/model-schema.json +4 -1
  131. package/top-ppt-html/scripts/render_from_model.py +116 -55
  132. package/top-ppt-html/scripts/validate_pptx.py +1 -0
  133. package/top-ppt-html/scripts/validate_report.py +153 -0
  134. package/topmind-cover/README.en.md +4 -4
  135. package/topmind-cover/README.md +4 -4
  136. package/topmind-cover/SKILL.md +36 -18
  137. package/topmind-cover/assets/examples/README.md +13 -7
  138. package/topmind-cover/assets/examples/bg-blur-alt.png +0 -0
  139. package/topmind-cover/assets/examples/bg-blur-wechat.png +0 -0
  140. package/topmind-cover/assets/examples/bg-blur.png +0 -0
  141. package/topmind-cover/assets/examples/overview.png +0 -0
  142. package/topmind-cover/assets/examples/paper-collage-alt.png +0 -0
  143. package/topmind-cover/assets/examples/paper-collage-wechat.png +0 -0
  144. package/topmind-cover/assets/examples/paper-collage.png +0 -0
  145. package/topmind-cover/assets/examples/white-clean-alt-wechat.png +0 -0
  146. package/topmind-cover/assets/examples/white-clean-alt.png +0 -0
  147. package/topmind-cover/assets/examples/white-clean-wechat.png +0 -0
  148. package/topmind-cover/assets/examples/white-clean.png +0 -0
  149. package/topmind-cover/package.json +2 -2
  150. package/topmind-cover/references/cover-styles.md +146 -14
  151. package/topmind-cover/references/impact-language.md +9 -6
  152. package/topmind-cover/references/ref-white-clean-1.png +0 -0
  153. package/topmind-cover/references/ref-white-clean-2.png +0 -0
  154. package/topmind-wechat-post/README.en.md +1 -1
  155. package/topmind-wechat-post/README.md +1 -1
  156. package/topmind-wechat-post/scripts/md2wechat.py +130 -27
  157. package/topmind-wechat-post/scripts/negative_tests.py +74 -0
  158. package/topmind-x-article/README.en.md +1 -1
  159. package/topmind-x-article/README.md +1 -1
  160. package/topmind-x-article/scripts/md2x.py +18 -3
  161. package/topmind-x-article/scripts/negative_tests.py +17 -0
@@ -138,6 +138,7 @@ SLIDE_RE = re.compile(r"ppt/slides/slide(\d+)\.xml$")
138
138
  _PROBE_SKIP_KEYS = {
139
139
  "colors", "color", "icon", "href", "id", "type", "exhibitNo", "max", "unit",
140
140
  "hint", "src", "alt", "fit", "layout", "placeholder", "ratio", "dataTable",
141
+ "variant", # 版式变体注册值(bento-grid/timeline/2-col-feature)不渲染为文本
141
142
  }
142
143
 
143
144
 
@@ -31,6 +31,8 @@ import re
31
31
  import json
32
32
  import base64
33
33
  import hashlib
34
+ import html as _html
35
+ import unicodedata
34
36
  from typing import Optional
35
37
  from html.parser import HTMLParser
36
38
  from pathlib import Path
@@ -371,6 +373,155 @@ def _check_bands(txt, chk, mode="presentation"):
371
373
  f"{bad_grids} 处未对齐" if bad_grids else "", level="WARN")
372
374
 
373
375
 
376
+ def _icon_pack_names():
377
+ """图标包合法名集合(assets/icons/index.json);读不到时返回 None(跳过存在性检查)。"""
378
+ try:
379
+ idx = json.loads((Path(__file__).resolve().parent.parent / 'assets' / 'icons'
380
+ / 'index.json').read_text(encoding='utf-8'))
381
+ return set((idx.get('icons') or {}).keys())
382
+ except OSError:
383
+ return None
384
+
385
+
386
+ def _check_icon_refs(txt, chk):
387
+ """图标引用存在性:data-icon / icon: 标记引用了包外图标 → WARN(不 FAIL)。"""
388
+ names = _icon_pack_names()
389
+ if names is None:
390
+ return
391
+ # 只扫渲染正文:去掉 script/style/注释与嵌入模型 JSON,避免代码与文档示例误报
392
+ body = re.sub(r'<script[\s\S]*?</script>', '', txt, flags=re.I)
393
+ body = re.sub(r'<style[\s\S]*?</style>', '', body, flags=re.I)
394
+ body = re.sub(r'<!--[\s\S]*?-->', '', body)
395
+ body = re.sub(r'window\.REPORT_MODEL\s*=\s*\{[\s\S]*?\n\};', '', body)
396
+ refs = set(re.findall(r'data-icon="([^"]+)"', body))
397
+ refs |= set(re.findall(r'icon:([\u4e00-\u9fa5A-Za-z0-9_-]+)', body))
398
+ # 排除 hydrate 占位与 CSS 类名噪声:只看真实引用上下文
399
+ bad = sorted(r for r in refs if r not in names and not r.startswith('{{'))
400
+ chk("图标引用存在(assets/icons 包内)", not bad,
401
+ f"未知图标: {', '.join(bad[:6])}{'…' if len(bad) > 6 else ''}({len(bad)} 个)" if bad else "",
402
+ level="WARN")
403
+
404
+
405
+ # ── 内容覆盖率(0.2.0):版式不得以丢文字为代价美化 ──
406
+ # 口径:REPORT_MODEL 可见文本串(去重、归一化)有多少字符能在渲染后 HTML 可见文本中找到;
407
+ # <95% → WARN(只报告,不 FAIL;长串按 8 字窗口部分计分,避免数字重排/截断误杀)。
408
+ _COV_SKIP_KEYS = {
409
+ # 元字段(不渲染为正文)
410
+ "style", "theme", "mode", "type", "variant", "icon", "color", "colors",
411
+ "src", "href", "id", "layout", "datatable", "dataTable", "font", "fontface",
412
+ "exhibitno", "exhibitNo", "columns", "max", "min", "unit", "ratio", "fit",
413
+ "align", "width", "height", "placeholder", "alt", "target", "rel", "dir",
414
+ "lang", "charset", "defer", "async", "media",
415
+ "hint", # 搭建期给智能体的指令(如 image.hint),不是读者正文
416
+ }
417
+ _COV_URL_RE = re.compile(r'^(https?://|www\.|data:|#)', re.I)
418
+ _COV_COLOR_RE = re.compile(r'^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$')
419
+ # 纯小写 ASCII 标识符(无空格/CJK/大写):渲染器语义 flag(如 "focus"),不是正文
420
+ _COV_FLAG_RE = re.compile(r'^[a-z][a-z0-9_-]*$')
421
+ # 信息图页型(r_info 故意留"按 infographics 规格绘制"占位、PPTX 走形状通道):
422
+ # 其 chart 数据子树不计入覆盖率(数据在模型与 PPTX 中完整,仅 HTML 待定制信息图)
423
+ _COV_INFO_TYPES = {'sankey', 'treemap', 'boxplot', 'network', 'marimekko', 'streamgraph'}
424
+ _COV_INFO_DATA_KEYS = {'chart', 'labels', 'values', 'groups', 'nodes', 'links', 'edges', 'data',
425
+ 'series', 'dataset', 'cols', 'rows', 'cells'}
426
+ _COV_MIN_RATIO = 0.95 # 覆盖率下限(layout-constants qualityGates.contentCoverage 可覆写)
427
+
428
+
429
+ def _norm_cov(s: str) -> str:
430
+ s = unicodedata.normalize('NFKC', s)
431
+ s = re.sub(r'(?<=\d),(?=\d)', '', s) # 千分位 1,000 → 1000(中文逗号保留)
432
+ s = re.sub(r'\s+', '', s)
433
+ # 标点不计入:内容在、标点异(: vs 无、() vs 无)不算丢失;比的是信息不是排印
434
+ s = ''.join(c for c in s if not unicodedata.category(c).startswith('P'))
435
+ return s
436
+
437
+
438
+ def _model_cov_strings(model) -> list:
439
+ """从 REPORT_MODEL 递归抽取候选正文串(去重、保序)。"""
440
+ out, seen = [], set()
441
+
442
+ def walk(node, skip_sub=False):
443
+ if isinstance(node, dict):
444
+ # 信息图页型:chart 数据子树是故意占位(r_info),不计入
445
+ info_data = isinstance(node.get('type'), str) and node.get('type').lower() in _COV_INFO_TYPES
446
+ for k, v in node.items():
447
+ kl = str(k).lower()
448
+ if kl in _COV_SKIP_KEYS or str(k).startswith('data-'):
449
+ continue
450
+ if info_data and kl in _COV_INFO_DATA_KEYS:
451
+ continue
452
+ walk(v)
453
+ elif isinstance(node, (list, tuple)):
454
+ for v in node:
455
+ walk(v)
456
+ elif isinstance(node, str):
457
+ t = node.strip()
458
+ if len(t) < 4 or _COV_URL_RE.match(t) or _COV_COLOR_RE.match(t):
459
+ return
460
+ if _COV_FLAG_RE.match(t):
461
+ return # 渲染器语义 flag(如 focus),非正文
462
+ if t not in seen:
463
+ seen.add(t)
464
+ out.append(t)
465
+
466
+ walk(model)
467
+ return out
468
+
469
+
470
+ def _visible_cov_text(txt: str) -> str:
471
+ """渲染后可见文本:剔 script(含 REPORT_MODEL JSON 本体)/style/注释/标签后归一化。"""
472
+ t = re.sub(r'<script[\s\S]*?</script>', '', txt, flags=re.I)
473
+ t = re.sub(r'<style[\s\S]*?</style>', '', t, flags=re.I)
474
+ t = re.sub(r'<!--[\s\S]*?-->', '', t)
475
+ t = re.sub(r'<[^>]+>', '', t)
476
+ return _norm_cov(_html.unescape(t))
477
+
478
+
479
+ def _cov_credit(cand: str, rendered: str) -> float:
480
+ """候选串的字符计分:整串命中按全长;否则按 8 字窗口命中率折算。"""
481
+ n = _norm_cov(cand)
482
+ if not n:
483
+ return 0.0
484
+ if n in rendered:
485
+ return float(len(n))
486
+ if len(n) <= 12:
487
+ return 0.0
488
+ win, hits, total = 8, 0, 0
489
+ for i in range(0, len(n), win):
490
+ total += 1
491
+ if n[i:i + win] in rendered:
492
+ hits += 1
493
+ return len(n) * hits / total if total else 0.0
494
+
495
+
496
+ def _check_content_coverage(txt, chk, model) -> None:
497
+ """模型文本 → 渲染文本覆盖率(只 WARN)。"""
498
+ if not isinstance(model, dict):
499
+ return
500
+ try:
501
+ min_ratio = float((load_constants().get("qualityGates") or {}).get("contentCoverage")
502
+ or _COV_MIN_RATIO)
503
+ except Exception:
504
+ min_ratio = _COV_MIN_RATIO
505
+ cands = _model_cov_strings(model)
506
+ if not cands:
507
+ return
508
+ rendered = _visible_cov_text(txt)
509
+ total = sum(len(_norm_cov(c)) for c in cands)
510
+ if not total:
511
+ return
512
+ miss = []
513
+ got = 0.0
514
+ for c in cands:
515
+ cr = _cov_credit(c, rendered)
516
+ got += cr
517
+ if cr < len(_norm_cov(c)) * 0.5:
518
+ miss.append(c[:24])
519
+ ratio = got / total
520
+ chk(f"内容覆盖率(模型文本→渲染文本 ≥{min_ratio:.0%})", ratio >= min_ratio,
521
+ f"覆盖率 {ratio:.1%}({len(cands)} 串),疑似丢失: {';'.join(miss[:3])}" if ratio < min_ratio else "",
522
+ level="WARN")
523
+
524
+
374
525
  def _check_icons(txt, chk):
375
526
  """图标使用:长报告不应全文无图标;含 ≥2 张卡的内容页应有 .card__ico(WARN)。"""
376
527
  if len(_bands(txt)) < 6:
@@ -1801,8 +1952,10 @@ def main():
1801
1952
  _check_mode_layouts(txt, chk, mode)
1802
1953
  if mode != 'architecture':
1803
1954
  _check_icons(txt, chk)
1955
+ _check_icon_refs(txt, chk)
1804
1956
  _check_pptx_export(txt, chk)
1805
1957
  model = _check_model_consistency(txt, chk, mode, style)
1958
+ _check_content_coverage(txt, chk, model)
1806
1959
  _check_type_features(txt, chk, model)
1807
1960
  _check_exhibits(txt, chk, mode)
1808
1961
  _check_research_extras(txt, chk, mode)
@@ -4,15 +4,15 @@
4
4
 
5
5
  A reusable skill for generating cover art for X long-form posts and WeChat articles. Goal: **striking, eye-catching, theme-focused**.
6
6
 
7
- - Version: **v0.1.0** (same tag as `@topmindspace/tms-skills@0.3.9`)
7
+ - Version: **v0.2.0** (same tag as `@topmindspace/tms-skills@0.4.1`)
8
8
 
9
9
  ## Style gallery
10
10
 
11
11
  <p align="center">
12
- <img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover · 8 cover-style overview" width="960" />
12
+ <img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover · 11 cover-style overview" width="960" />
13
13
  </p>
14
14
 
15
- 8 styles (viral dry-goods / giant-type manifesto / brand launch / tutorial steps / fun IP / news flash / minimalist / editorial magazine): use cases, palette stories, abstract design principles, and Chinese+English prompt recipes in [`references/cover-styles.md`](./references/cover-styles.md); full-size per-style shots in [`assets/examples/`](./assets/examples/).
15
+ 11 styles (clean white / background blur / paper collage / news flash / giant-type manifesto / tutorial steps / minimalist / editorial magazine / viral dry-goods / brand launch / fun IP, light-first ordering): use cases, palette stories, abstract design principles, and Chinese+English prompt recipes in [`references/cover-styles.md`](./references/cover-styles.md); full-size per-style shots in [`assets/examples/`](./assets/examples/).
16
16
 
17
17
  ## Install
18
18
 
@@ -22,7 +22,7 @@ npx @topmindspace/tms-skills install topmind-cover
22
22
 
23
23
  ## Usage
24
24
 
25
- 0. **Pick a style**: choose 1 of 8 styles from `references/cover-styles.md` by topic → check the example image to confirm the visual language.
25
+ 0. **Pick a style**: choose 1 of 11 styles from `references/cover-styles.md` by topic (light-first) → check the example image to confirm the visual language.
26
26
  1. **Refine the title**: lock the title copy first (usually ≤ 10 chars) using that style's title rules; rewrite until it lands — no drawing yet.
27
27
  2. **Composition brief**: one-sentence brief (theme / audience / mood / visual metaphor / palette direction) before composing the prompt.
28
28
  3. Input: article title + 3 theme keywords + platform (x / wechat / both, default both).
@@ -4,15 +4,15 @@
4
4
 
5
5
  为 X 长文和公众号文章生成封面图的可复用技能。目标:**震撼、醒目、主题突出**。
6
6
 
7
- - 版本:**v0.1.0**(与 `@topmindspace/tms-skills@0.3.9` 同 tag)
7
+ - 版本:**v0.2.0**(与 `@topmindspace/tms-skills@0.4.1` 同 tag)
8
8
 
9
9
  ## 风格样张
10
10
 
11
11
  <p align="center">
12
- <img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover · 8 封面风格总览" width="960" />
12
+ <img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover · 11 封面风格总览" width="960" />
13
13
  </p>
14
14
 
15
- 8 种风格(爆款干货 / 巨字宣言 / 品牌发布 / 教程步骤 / IP 趣味 / 资讯快报 / 极简留白 / 杂志编辑):适用场景、配色故事、抽象设计原则、中英 prompt 配方见 [`references/cover-styles.md`](./references/cover-styles.md);单风格大图在 [`assets/examples/`](./assets/examples/)。
15
+ 11 种风格(白色清新 / 背景虚化 / 纸感拼贴 / 资讯快报 / 巨字宣言 / 教程步骤 / 极简留白 / 杂志编辑 / 爆款干货 / 品牌发布 / IP 趣味,浅色优先排序):适用场景、配色故事、抽象设计原则、中英 prompt 配方见 [`references/cover-styles.md`](./references/cover-styles.md);单风格大图在 [`assets/examples/`](./assets/examples/)。
16
16
 
17
17
  ## 安装
18
18
 
@@ -22,7 +22,7 @@ npx @topmindspace/tms-skills install topmind-cover
22
22
 
23
23
  ## 用法
24
24
 
25
- 0. **选风格**:按题材从 `references/cover-styles.md` 选 1 种(8 选 1)→ 看示例图确认视觉语言。
25
+ 0. **选风格**:按题材从 `references/cover-styles.md` 选 1 种(11 选 1,浅色优先)→ 看示例图确认视觉语言。
26
26
  1. **标题提炼**:先定标题文案(一般 ≤10 字),用该风格章节的标题写法规范;不满意重写,不先画图。
27
27
  2. **构图简报**:一句话 brief(主题/受众/情绪/视觉隐喻/配色方向),组 prompt 前先写。
28
28
  3. 输入文章标题 + 3 个主题关键词 + 平台(x / wechat / both,默认 both)。
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: topmind-cover
3
- version: 0.1.0
4
- description: "文章封面配图生成:X 长文与公众号共用。震撼、醒目、主题突出;平台尺寸规范、风格模板、命名落盘、成图检查全流程覆盖。Use when 文章封面、封面图、头图、题图、cover。Do NOT use for 正文插图、PPT/报告封面。"
3
+ version: 0.2.0
4
+ description: "文章封面配图生成:X 长文与公众号共用。震撼、醒目、主题突出;平台尺寸规范、11 种风格模板、命名落盘、成图检查全流程覆盖。Use when 文章封面、封面图、头图、题图、cover。Do NOT use for 正文插图、PPT/报告封面。"
5
5
  action_category: write
6
6
  triggers:
7
7
  - 封面
@@ -34,25 +34,43 @@ updated: 2026-09-29
34
34
  标题提炼 → 构图简报 → 风格模板 → 生成 → 冲击力自检 → 裁剪双尺寸 → 落盘命名
35
35
  ```
36
36
 
37
- ## 风格索引
37
+ ## 风格索引(浅色优先:1~8 浅色,9~11 深色/高饱和)
38
38
 
39
- 风格总览图见 `assets/examples/overview.png`(8 宫格,离线可看)。
39
+ 风格总览图见 `assets/examples/overview.png`(11 宫格:3 行 × 4 列,离线可看)。
40
40
 
41
41
  | 风格 | 首选题材 |
42
42
  |------|----------|
43
- | 爆款干货 `gan-huo` | 干货清单、评测、盘点、实测筛选 |
43
+ | 白色清新 `white-clean` | 干货清单、实测盘点、效率/副业/职场 |
44
+ | 背景虚化 `bg-blur` | 生活方式、职场日常、运动健康 |
45
+ | 纸感拼贴 `paper-collage` | 手账、整理术、旧物改造 |
46
+ | 资讯快报 `news-flash` | 资讯快讯、热点解读、揭秘类选题 |
44
47
  | 巨字宣言 `big-type` | 观点评论、深度长文、发布宣言 |
45
- | 品牌发布 `brand-launch` | 产品发布、版本更新、官方白皮书 |
46
48
  | 教程步骤 `tutorial-steps` | 教程、上手指南、分步实操 |
47
- | IP 趣味 `ip-fun` | 实战案例、数据战报、复盘、连载 |
48
- | 资讯快报 `news-flash` | 资讯快讯、热点解读、揭秘类选题 |
49
49
  | 极简留白 `minimal` | 随笔、书评、轻观点 |
50
50
  | 杂志编辑 `magazine` | 深度访谈、人物特写、商业分析 |
51
+ | 爆款干货 `gan-huo` | 干货清单、评测、盘点、实测筛选 |
52
+ | 品牌发布 `brand-launch` | 产品发布、版本更新、官方白皮书 |
53
+ | IP 趣味 `ip-fun` | 实战案例、数据战报、复盘、连载 |
51
54
 
52
55
  适用场景细则、配色故事、prompt 配方见 `references/cover-styles.md`;单风格大图 `assets/examples/<style>.png`。
53
56
 
54
57
  > 示例图为原创演示:只学设计原则,不临摹第三方版式(详见 `references/cover-styles.md` 顶部"原创铁律")。
55
58
 
59
+ ## 意图判断 → 直出 / 讨论(生成前必做)
60
+
61
+ 默认按意图直出;意图模糊/多解/缺关键信息时先与用户确认(三问以内)。
62
+
63
+ | # | 检查项 | 通过标准 | 不通过→追问(给选项,不给问答题) |
64
+ |---|--------|----------|----------------------------------|
65
+ | 1 | 标题确定 | 有明确标题文案(≤10 字),或用户给了原文可直接提炼 | 给 2 个备选标题让用户挑:"用 A 还是 B?" |
66
+ | 2 | 主题明确 | 能说清文章讲什么(3 个主题关键词) | 追问:"这篇的核心主题是?"附 2~3 个关键词备选 |
67
+ | 3 | 风格明确 | 题材对上某风格首选题材,或用户点名了风格 | 给 2~3 个候选风格 + 各一句话差异,让用户选 |
68
+ | 4 | 关键信息有出处 | 数字/品牌/人物/署名等真实可查 | 缺→问;问不到→删掉该元素,**绝不编造** |
69
+
70
+ - **四项全过 → 直接生成**,不问。
71
+ - **任一项模糊/多解 → 先确认再生成**,问题总数 ≤3(风格、标题、内容各至多一问)。
72
+ - 讨论时每个问题附 2~3 个具体备选,用户只做选择题。
73
+
56
74
  ## 尺寸表
57
75
 
58
76
  | 平台 | 尺寸 | 比例 | 备注 |
@@ -64,14 +82,15 @@ updated: 2026-09-29
64
82
 
65
83
  ## 工作流
66
84
 
67
- 0. **选风格(三步,必做)**:① 按题材从 `references/cover-styles.md` 选 1 种(8 选 1)→ ② 看 `assets/examples/<style>.png` 确认视觉语言 → ③ 看该风格章节的标题写法规范,心里有标题雏形。
85
+ 0. **意图判断**(必做):先过上方"意图判断 → 直出 / 讨论"决策流;意图明确→直接生成,模糊→三问以内确认。
86
+ **选风格(三步,必做)**:① 按题材从 `references/cover-styles.md` 选 1 种(11 选 1,浅色优先)→ ② 看 `assets/examples/<style>.png` 确认视觉语言 → ③ 看该风格章节的标题写法规范,心里有标题雏形。
68
87
  1. **标题提炼**(先定文案,不画图):用所选风格在 `cover-styles.md` 对应章节的标题写法规范提炼标题(一般 ≤10 字);不满意就重写,满意再进下一步。
69
88
  - 坏:"关于 Manus 2.0 的一些思考与体验"(长、没钩子)→ 好:"Manus 2.0 实测"(短、有断言)
70
89
  2. **构图简报**(一句话 brief,组 prompt 前先写):主题 + 受众 + 情绪 + 视觉隐喻 + 配色方向。
71
90
  - 例:"给 AI 从业者看的 Manus 2.0 实测封面,情绪'震撼但可信',视觉隐喻是破壳而出的机械手,深空黑底 + 电光蓝强调。"
72
91
  3. **输入与组 prompt**:用步骤 1 定下的标题 + 3 个主题关键词 + 平台(`x` / `wechat` / `both`,默认 both;平台只影响 prompt 侧重,裁剪落盘永远产出双尺寸)。按风格配方组装 prompt,标题逐字写明(防 AI 自造错别字)。
73
92
  4. **生成**:`media.generate_image`,`name` 用 `<slug>-cover`。
74
- 5. **冲击力自检**(必做):必过下方"冲击力自检清单" 10 项;不通过→调整 prompt 重生成,最多 3 次;3 次仍不过→换一种风格,或回步骤 1 重写标题。
93
+ 5. **冲击力自检**(必做):过下方自检清单 9 项;不通过→调整 prompt 重生成,最多 3 次;3 次仍不过→换一种风格,或回步骤 1 重写标题。
75
94
  6. **裁剪落盘**:
76
95
  ```bash
77
96
  python3 scripts/crop-cover.py <主图> --out-dir <包>/images/
@@ -82,27 +101,26 @@ updated: 2026-09-29
82
101
 
83
102
  ## 冲击力自检清单
84
103
 
85
- **生成后必过**:不通过→调整 prompt 重生成,最多 3 次;3 次仍不过→换风格或重写标题。
104
+ **生成后必过**。
86
105
 
87
106
  | # | 检查项 | 不通过怎么改 |
88
107
  |---|--------|--------------|
89
108
  | 1 | 3 秒测试:缩到 120px 宽,3 秒内读出标题并说清"这是什么" | 放大标题,删小字 |
90
- | 2 | 标题字高 ≥ 画面高度 1/4 | 放大标题,其他元素让路 |
109
+ | 2 | 标题字高 ≥ 画面高度 1/4,空间允许时冲击 1/3 | 放大标题,其他元素让路 |
91
110
  | 3 | 对比果断:字色与底色明度差拉满(拒绝灰底白字式低对比) | 底色走极端(极深或极浅) |
92
111
  | 4 | 记忆点:3 秒后能向人描述出一个具体的东西 | 加一个形象/数字/符号/质感记忆点 |
93
112
  | 5 | 质感:背景有纹理、光影或描边,拒绝纯色死平 | 背景层加一层纸纹/噪点/光影 |
94
- | 6 | 标题字逐字正确,无 AI 自造错别字 | 修正标题写法、缩短标题后重生成 |
113
+ | 6 | 标题字逐字正确:无 AI 自造错字/乱码/笔画粘连(含装饰导致) | 有错字/粘连→减装饰、缩短标题或修正标题写法后重生成 |
95
114
  | 7 | 标题与关键主体落在中央垂直 60% 安全区(900×383 裁剪不切字) | 把元素收拢进安全区 |
96
115
  | 8 | `references/impact-language.md` 20 条原则快速勾选 | 按"保守陷阱清单"逐项纠正 |
97
- | 9 | 中文逐字正确(装饰未导致错字、乱码、笔画粘连) | 有错字/粘连→减装饰或缩短标题后重生成 |
98
- | 10 | 装饰手法 ≤ 该风格指定数量(多了即乱;minimal 只许 1 种) | 超量→删掉最弱的一种装饰再生成 |
116
+ | 9 | 装饰手法 ≤ 该风格指定数量(多了即乱;minimal 只许 1 种) | 超量→删掉最弱的一种装饰再生成 |
99
117
 
100
118
  ## 设计铁律
101
119
 
102
120
  - 一图一主题;主体占画面 40% 以上,居中或三分法
103
- - 大标题 ≤10 字,高对比(暗底亮字 / 亮底深字)
104
- - 四周 8% 安全边距,标题不贴边;标题字另须满足中央垂直 60% 安全区(见风格库"安全区铁律")
105
- - 忌:元素堆砌、小字密排、多主体打架、标题字错误
121
+ - 大标题 ≤10 字;对比与字高见冲击力自检 #2/#3
122
+ - 四周 8% 安全边距,标题不贴边(中央 60% 安全区见自检 #7)
123
+ - 忌:元素堆砌、小字密排、多主体打架
106
124
 
107
125
  ## 外部依赖 / 规约来源
108
126
 
@@ -1,19 +1,25 @@
1
1
  # 封面风格示例图
2
2
 
3
- 8 种风格 × 2 种尺寸 = 16 张示例(随 npm 包发布,npx 安装即得),
4
- 另附 `overview.png`(8 宫格总览,2260×806)。
3
+ 26 张示例(随 npm 包发布,npx 安装即得):11 种风格 × 2 种尺寸 = 22 张 + 3 张 alt 样张
4
+ + 1 张 alt 微信尺寸版(`white-clean-alt-wechat.png`),
5
+ 另附 `overview.png`(11 宫格总览:3 行 × 4 列缩略图 + 风格名标注,选风格时先看它)。
5
6
 
6
7
  - `<style>.png`(1200×675,X 长文封面 / 公众号共用主尺寸)
7
8
  - `<style>-wechat.png`(900×383,公众号封面大图,中央裁剪版)
8
- - `overview.png`(8 宫格总览:2 行 × 4 列缩略图 + 风格名标注,选风格时先看它)
9
+ - `<style>-alt.png`(1200×675,同风格第二张演示样张;白色清新 / 背景虚化 / 纸感拼贴
10
+ 三种新风格各有 2 张:主样张与 alt 样张用了不同的优选组合)
11
+ - `<style>-alt-wechat.png`(900×383,alt 样张的公众号尺寸版;目前只有 white-clean 有,即
12
+ `white-clean-alt-wechat.png`,`crop-cover.py` 流程产出双尺寸,新增 alt 样张时一并产出)
13
+ - `overview.png`(11 宫格总览:3 行 × 4 列缩略图 + 风格名标注,选风格时先看它)
9
14
 
10
- 8 种风格(爆款干货 `gan-huo` / 巨字宣言 `big-type` / 品牌发布 `brand-launch` / 教程步骤
11
- `tutorial-steps` / IP 趣味 `ip-fun` / 资讯快报 `news-flash` / 极简留白 `minimal` /
12
- 杂志编辑 `magazine`):适用场景索引与配方见 `../references/cover-styles.md`。
15
+ 11 种风格(白色清新 `white-clean` / 背景虚化 `bg-blur` / 纸感拼贴 `paper-collage` /
16
+ 资讯快报 `news-flash` / 巨字宣言 `big-type` / 教程步骤 `tutorial-steps` /
17
+ 极简留白 `minimal` / 杂志编辑 `magazine` / 爆款干货 `gan-huo` / 品牌发布 `brand-launch` /
18
+ IP 趣味 `ip-fun`,浅色优先排序):适用场景索引与配方见 `../references/cover-styles.md`。
13
19
 
14
20
  ## 原创与虚构声明(重要)
15
21
 
16
- 本目录 16 张示例图均为**原创设计**(只演示抽象设计原则,不临摹任何第三方封面的
22
+ 本目录 26 张示例图均为**原创设计**(只演示抽象设计原则,不临摹任何第三方封面的
17
23
  版式与配色;复用本库设计时亦不得与第三方封面构成实质相似——只学原则,不学版式)。
18
24
  图中标题文案、数字、品牌名、署名均为**虚构演示内容**(如"破晓 6.0"、
19
25
  "@老周带单")——直接复用前请换成自己的真实标题;凡封面上的数字必须在正文中有
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "topmind-cover",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "private": true,
5
- "description": "文章封面配图生成(X 长文 / 公众号共用):震撼醒目主题突出,尺寸规范 + 风格模板 + 裁剪落盘。",
5
+ "description": "文章封面配图生成(X 长文 / 公众号共用):震撼醒目主题突出,尺寸规范 + 11 种风格模板 + 裁剪落盘。",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",