@topmindspace/tms-skills 0.3.6 → 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.
- package/CHANGELOG.md +153 -0
- package/README.en.md +12 -9
- package/README.md +12 -9
- package/bin/tms-skills.js +153 -13
- package/package.json +1 -1
- package/top-ppt-html/README.en.md +2 -2
- package/top-ppt-html/README.md +1 -1
- package/top-ppt-html/SKILL.md +8 -7
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +58 -184
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.model.json +13 -3
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +58 -337
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.model.json +15 -1
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +58 -930
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.model.json +15 -1
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +141 -31
- package/top-ppt-html/assets/icons/index.json +557 -0
- package/top-ppt-html/assets/icons//344/270/212/344/274/240.png +0 -0
- package/top-ppt-html/assets/icons//344/270/212/344/274/240.svg +1 -0
- package/top-ppt-html/assets/icons//344/270/213/350/275/275.png +0 -0
- package/top-ppt-html/assets/icons//344/270/213/350/275/275.svg +1 -0
- package/top-ppt-html/assets/icons//344/270/213/351/231/215.png +0 -0
- package/top-ppt-html/assets/icons//344/270/213/351/231/215.svg +1 -0
- package/top-ppt-html/assets/icons//344/271/246/347/255/276.png +0 -0
- package/top-ppt-html/assets/icons//344/271/246/347/255/276.svg +1 -0
- package/top-ppt-html/assets/icons//344/272/221.png +0 -0
- package/top-ppt-html/assets/icons//344/272/221.svg +1 -0
- package/top-ppt-html/assets/icons//344/275/215/347/275/256.png +0 -0
- package/top-ppt-html/assets/icons//344/275/215/347/275/256.svg +1 -0
- package/top-ppt-html/assets/icons//344/277/241/346/201/257.png +0 -0
- package/top-ppt-html/assets/icons//344/277/241/346/201/257.svg +1 -0
- package/top-ppt-html/assets/icons//345/210/206/344/272/253.png +0 -0
- package/top-ppt-html/assets/icons//345/210/206/344/272/253.svg +1 -0
- package/top-ppt-html/assets/icons//345/213/276/351/200/211.png +0 -0
- package/top-ppt-html/assets/icons//345/213/276/351/200/211.svg +1 -0
- package/top-ppt-html/assets/icons//345/215/240/346/257/224.png +0 -0
- package/top-ppt-html/assets/icons//345/215/240/346/257/224.svg +1 -0
- package/top-ppt-html/assets/icons//345/233/242/351/230/237.png +0 -0
- package/top-ppt-html/assets/icons//345/233/242/351/230/237.svg +1 -0
- package/top-ppt-html/assets/icons//345/233/276/350/241/250.png +0 -0
- package/top-ppt-html/assets/icons//345/233/276/350/241/250.svg +1 -0
- package/top-ppt-html/assets/icons//345/242/236/351/225/277.png +0 -0
- package/top-ppt-html/assets/icons//345/242/236/351/225/277.svg +1 -0
- package/top-ppt-html/assets/icons//345/256/211/345/205/250.png +0 -0
- package/top-ppt-html/assets/icons//345/256/211/345/205/250.svg +1 -0
- package/top-ppt-html/assets/icons//345/257/271/350/257/235.png +0 -0
- package/top-ppt-html/assets/icons//345/257/271/350/257/235.svg +1 -0
- package/top-ppt-html/assets/icons//345/267/245/345/205/267.png +0 -0
- package/top-ppt-html/assets/icons//345/267/245/345/205/267.svg +1 -0
- package/top-ppt-html/assets/icons//345/276/252/347/216/257.png +0 -0
- package/top-ppt-html/assets/icons//345/276/252/347/216/257.svg +1 -0
- package/top-ppt-html/assets/icons//346/210/220/346/236/234.png +0 -0
- package/top-ppt-html/assets/icons//346/210/220/346/236/234.svg +1 -0
- package/top-ppt-html/assets/icons//346/211/213/346/234/272.png +0 -0
- package/top-ppt-html/assets/icons//346/211/213/346/234/272.svg +1 -0
- package/top-ppt-html/assets/icons//346/225/210/347/216/207.png +0 -0
- package/top-ppt-html/assets/icons//346/225/210/347/216/207.svg +1 -0
- package/top-ppt-html/assets/icons//346/225/260/346/215/256.png +0 -0
- package/top-ppt-html/assets/icons//346/225/260/346/215/256.svg +1 -0
- package/top-ppt-html/assets/icons//346/226/207/344/273/266/345/244/271.png +0 -0
- package/top-ppt-html/assets/icons//346/226/207/344/273/266/345/244/271.svg +1 -0
- package/top-ppt-html/assets/icons//346/226/207/346/241/243.png +0 -0
- package/top-ppt-html/assets/icons//346/226/207/346/241/243.svg +1 -0
- package/top-ppt-html/assets/icons//346/227/227/345/270/234.png +0 -0
- package/top-ppt-html/assets/icons//346/227/227/345/270/234.svg +1 -0
- package/top-ppt-html/assets/icons//346/227/266/351/227/264.png +0 -0
- package/top-ppt-html/assets/icons//346/227/266/351/227/264.svg +1 -0
- package/top-ppt-html/assets/icons//346/230/237/346/240/207.png +0 -0
- package/top-ppt-html/assets/icons//346/230/237/346/240/207.svg +1 -0
- package/top-ppt-html/assets/icons//346/231/272/350/203/275.png +0 -0
- package/top-ppt-html/assets/icons//346/231/272/350/203/275.svg +1 -0
- package/top-ppt-html/assets/icons//346/235/203/351/231/220.png +0 -0
- package/top-ppt-html/assets/icons//346/235/203/351/231/220.svg +1 -0
- package/top-ppt-html/assets/icons//346/243/200/346/237/245.png +0 -0
- package/top-ppt-html/assets/icons//346/243/200/346/237/245.svg +1 -0
- package/top-ppt-html/assets/icons//346/264/236/345/257/237.png +0 -0
- package/top-ppt-html/assets/icons//346/264/236/345/257/237.svg +1 -0
- package/top-ppt-html/assets/icons//346/265/201/347/250/213.png +0 -0
- package/top-ppt-html/assets/icons//346/265/201/347/250/213.svg +1 -0
- package/top-ppt-html/assets/icons//346/270/205/345/215/225.png +0 -0
- package/top-ppt-html/assets/icons//346/270/205/345/215/225.svg +1 -0
- package/top-ppt-html/assets/icons//347/201/253/347/256/255.png +0 -0
- package/top-ppt-html/assets/icons//347/201/253/347/256/255.svg +1 -0
- package/top-ppt-html/assets/icons//347/201/257/346/263/241.png +0 -0
- package/top-ppt-html/assets/icons//347/201/257/346/263/241.svg +1 -0
- package/top-ppt-html/assets/icons//347/224/250/346/210/267.png +0 -0
- package/top-ppt-html/assets/icons//347/224/250/346/210/267.svg +1 -0
- package/top-ppt-html/assets/icons//347/233/256/346/240/207.png +0 -0
- package/top-ppt-html/assets/icons//347/233/256/346/240/207.svg +1 -0
- package/top-ppt-html/assets/icons//347/256/255/345/244/264.png +0 -0
- package/top-ppt-html/assets/icons//347/256/255/345/244/264.svg +1 -0
- package/top-ppt-html/assets/icons//347/273/204/347/273/207.png +0 -0
- package/top-ppt-html/assets/icons//347/273/204/347/273/207.svg +1 -0
- package/top-ppt-html/assets/icons//347/275/227/347/233/230.png +0 -0
- package/top-ppt-html/assets/icons//347/275/227/347/233/230.svg +1 -0
- package/top-ppt-html/assets/icons//350/241/250/346/240/274.png +0 -0
- package/top-ppt-html/assets/icons//350/241/250/346/240/274.svg +1 -0
- package/top-ppt-html/assets/icons//350/256/241/345/210/222.png +0 -0
- package/top-ppt-html/assets/icons//350/256/241/345/210/222.svg +1 -0
- package/top-ppt-html/assets/icons//350/256/276/347/275/256.png +0 -0
- package/top-ppt-html/assets/icons//350/256/276/347/275/256.svg +1 -0
- package/top-ppt-html/assets/icons//350/266/213/345/212/277.png +0 -0
- package/top-ppt-html/assets/icons//350/266/213/345/212/277.svg +1 -0
- package/top-ppt-html/assets/icons//351/202/256/344/273/266.png +0 -0
- package/top-ppt-html/assets/icons//351/202/256/344/273/266.svg +1 -0
- package/top-ppt-html/assets/icons//351/207/221/351/222/261.png +0 -0
- package/top-ppt-html/assets/icons//351/207/221/351/222/261.svg +1 -0
- package/top-ppt-html/assets/icons//351/223/276/346/216/245.png +0 -0
- package/top-ppt-html/assets/icons//351/223/276/346/216/245.svg +1 -0
- package/top-ppt-html/assets/icons//351/227/252/347/224/265.png +0 -0
- package/top-ppt-html/assets/icons//351/227/252/347/224/265.svg +1 -0
- package/top-ppt-html/assets/icons//351/243/216/351/231/251.png +0 -0
- package/top-ppt-html/assets/icons//351/243/216/351/231/251.svg +1 -0
- package/top-ppt-html/assets/pptx-export.js +44 -15
- package/top-ppt-html/assets/style-gallery.html +2 -2
- package/top-ppt-html/assets/templates/architecture.html +59 -17
- package/top-ppt-html/assets/templates/engine.css +12 -0
- package/top-ppt-html/assets/templates/presentation.html +59 -17
- package/top-ppt-html/assets/templates/research.html +59 -17
- package/top-ppt-html/package-lock.json +2 -2
- package/top-ppt-html/package.json +2 -2
- package/top-ppt-html/references/icons.md +22 -19
- package/top-ppt-html/references/layout-variants.md +69 -0
- package/top-ppt-html/references/style-pack.md +40 -0
- package/top-ppt-html/scripts/audit_css.py +1 -1
- package/top-ppt-html/scripts/build_pptx.js +228 -50
- package/top-ppt-html/scripts/check_icons.py +119 -0
- package/top-ppt-html/scripts/hydrate_charts.py +60 -5
- package/top-ppt-html/scripts/icon_lib.js +66 -37
- package/top-ppt-html/scripts/layout-constants.json +92 -5
- package/top-ppt-html/scripts/make_icon_pack.py +172 -0
- package/top-ppt-html/scripts/model-schema.json +4 -1
- package/top-ppt-html/scripts/regression.py +3 -3
- package/top-ppt-html/scripts/render_compare.py +1 -1
- package/top-ppt-html/scripts/render_from_model.py +116 -55
- package/top-ppt-html/scripts/scaffold_report.py +1 -1
- package/top-ppt-html/scripts/sync_runtime.py +14 -14
- package/top-ppt-html/scripts/validate_pptx.py +1 -0
- package/top-ppt-html/scripts/validate_report.py +157 -0
- package/topmind-cover/README.en.md +4 -4
- package/topmind-cover/README.md +4 -4
- package/topmind-cover/SKILL.md +36 -16
- package/topmind-cover/assets/examples/README.md +13 -7
- package/topmind-cover/assets/examples/bg-blur-alt.png +0 -0
- package/topmind-cover/assets/examples/bg-blur-wechat.png +0 -0
- package/topmind-cover/assets/examples/bg-blur.png +0 -0
- package/topmind-cover/assets/examples/big-type-wechat.png +0 -0
- package/topmind-cover/assets/examples/big-type.png +0 -0
- package/topmind-cover/assets/examples/brand-launch-wechat.png +0 -0
- package/topmind-cover/assets/examples/brand-launch.png +0 -0
- package/topmind-cover/assets/examples/gan-huo-wechat.png +0 -0
- package/topmind-cover/assets/examples/gan-huo.png +0 -0
- package/topmind-cover/assets/examples/ip-fun-wechat.png +0 -0
- package/topmind-cover/assets/examples/ip-fun.png +0 -0
- package/topmind-cover/assets/examples/magazine-wechat.png +0 -0
- package/topmind-cover/assets/examples/magazine.png +0 -0
- package/topmind-cover/assets/examples/minimal-wechat.png +0 -0
- package/topmind-cover/assets/examples/minimal.png +0 -0
- package/topmind-cover/assets/examples/news-flash-wechat.png +0 -0
- package/topmind-cover/assets/examples/news-flash.png +0 -0
- package/topmind-cover/assets/examples/overview.png +0 -0
- package/topmind-cover/assets/examples/paper-collage-alt.png +0 -0
- package/topmind-cover/assets/examples/paper-collage-wechat.png +0 -0
- package/topmind-cover/assets/examples/paper-collage.png +0 -0
- package/topmind-cover/assets/examples/tutorial-steps-wechat.png +0 -0
- package/topmind-cover/assets/examples/tutorial-steps.png +0 -0
- package/topmind-cover/assets/examples/white-clean-alt-wechat.png +0 -0
- package/topmind-cover/assets/examples/white-clean-alt.png +0 -0
- package/topmind-cover/assets/examples/white-clean-wechat.png +0 -0
- package/topmind-cover/assets/examples/white-clean.png +0 -0
- package/topmind-cover/package.json +2 -2
- package/topmind-cover/references/cover-styles.md +210 -35
- package/topmind-cover/references/impact-language.md +43 -2
- package/topmind-cover/references/ref-white-clean-1.png +0 -0
- package/topmind-cover/references/ref-white-clean-2.png +0 -0
- package/topmind-cover/scripts/crop-cover.py +19 -13
- package/topmind-wechat-post/README.en.md +2 -2
- package/topmind-wechat-post/README.md +2 -2
- package/topmind-wechat-post/SKILL.md +1 -1
- package/topmind-wechat-post/scripts/md2wechat.py +142 -30
- package/topmind-wechat-post/scripts/negative_tests.py +74 -0
- package/topmind-x-article/README.en.md +1 -1
- package/topmind-x-article/README.md +1 -1
- package/topmind-x-article/scripts/md2x.py +25 -5
- package/topmind-x-article/scripts/negative_tests.py +17 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,158 @@
|
|
|
1
|
+
## [0.4.1] - 2026-09-29
|
|
2
|
+
|
|
3
|
+
> **本版备发**(tag v0.4.1 待打;npm 待发布;commit = 本轮审计报告落盘时的 `git log` 首条)。
|
|
4
|
+
> 根包 0.4.0 → **0.4.1**(patch);技能版本:top-ppt-html 0.2.0 → **0.2.1**(修技能数据 bug 则 patch)、
|
|
5
|
+
> topmind-cover 保持 0.2.0(仅换样张图+描述文案,无功能变更)、topmind-wechat-post / topmind-x-article 保持 0.1.0。
|
|
6
|
+
> 本轮是第十三轮集成轮(A 文档抛光 + B 示例与描述 + C 新代码复审),改动最小、无新功能。
|
|
7
|
+
> 另含第十四轮集成轮(wechat-post/x-article 真 bug 修复 + installer 测试扩展):**不 bump 版本**,全部并入 0.4.1。
|
|
8
|
+
|
|
9
|
+
### 安装器 bug 修复(高危 · Worker C 复审发现)
|
|
10
|
+
|
|
11
|
+
- `uninstall`/`install` 的 `assertDestOutsideSource` 守卫被符号链接绕过:`path.resolve` 不解析软链,
|
|
12
|
+
`--to <软链指向包根>` 会跟随链接 `rmSync` 删掉包内技能源目录(已实测验证旧代码确会删源)
|
|
13
|
+
- 修复:`bin/tms-skills.js` 改用 `realpath` 归一化比对(`realOrResolved()`:dest 不存在时向上找最深存在祖先),+25/−4
|
|
14
|
+
- `scripts/test_installer_cli.js` 新增 case11/case12(uninstall/install 经软链指包根 → 拒绝、源目录完好),12 用例全过
|
|
15
|
+
|
|
16
|
+
### top-ppt-html 0.2.1(Worker C 复审发现 · 低危数据 bug)
|
|
17
|
+
|
|
18
|
+
- `assets/icons/index.json`:「组织」图标关键词含裸「架构」,会把「系统架构」类标题配上人物组织图 → 已收窄为「组织架构」
|
|
19
|
+
|
|
20
|
+
### 文档抛光(Worker A)
|
|
21
|
+
|
|
22
|
+
- topmind-cover/SKILL.md:冲击力自检清单 10→9(合并逐字正确项)、设计铁律去重
|
|
23
|
+
- impact-language.md:删除与 cover-styles.md 重复的「白色清新」章节(只在 cover-styles 保留,出处回指用户参考图)
|
|
24
|
+
- 根 README 中英:封面技能描述 8 种风格 → 11 种;top-ppt-html README 中英版本口径改为与 `@topmindspace/tms-skills@0.4.1` 同 tag
|
|
25
|
+
|
|
26
|
+
### 示例与描述(Worker B)
|
|
27
|
+
|
|
28
|
+
- `white-clean-alt.png`(white-clean-2)已重生成:标题「极简收纳全攻略」摆正、逐字正确;配套
|
|
29
|
+
`white-clean-alt-wechat.png`(900×383)新增落盘并纳入 git;示例目录 README 计数同步为 26 张
|
|
30
|
+
- 4 处 description 更新(cover package.json + SKILL frontmatter 加「11 种风格模板」;ppt-html package.json + SKILL frontmatter 加「48 图标 + 弹性版式」);overview alt 文案 8→11
|
|
31
|
+
- cover 安装文案复核:`list` 输出已准确,未动安装器
|
|
32
|
+
|
|
33
|
+
### 第十四轮集成(Worker A/B/C)——不 bump 版本,全部并入 0.4.1
|
|
34
|
+
|
|
35
|
+
- **topmind-wechat-post 修 6 真 bug**(`scripts/md2wechat.py`,Worker A 专审发现):
|
|
36
|
+
- yaml/diff 代码块高亮正则在分支内误用 `(?m)` → `re.error` 崩溃(编译期统一 `re.M|re.S`,分支内去掉)
|
|
37
|
+
- URL 含平衡括号被截断 → 新增括号嵌套匹配扫描器替代旧正则
|
|
38
|
+
- `[文字](url "title")` 带 title 链接认不出 → 链接解析支持 title
|
|
39
|
+
- 脚注 URL 的 `&` 被转义两次 → 修正转义顺序
|
|
40
|
+
- 坏主题 JSON 的 Traceback → 干净报错;目录当输入的报错文案修正
|
|
41
|
+
- 嵌套围栏被提前闭合 → 围栏匹配支持嵌套
|
|
42
|
+
- `scripts/negative_tests.py` 新增 6 个 case,15/15 绿
|
|
43
|
+
- **topmind-x-article 修嵌套围栏**(`scripts/md2x.py`,Worker A 专审发现);
|
|
44
|
+
`scripts/negative_tests.py` 新增 2 个 case,8/8 绿
|
|
45
|
+
- **installer 回归测试扩展**(Worker C):`scripts/test_installer_cli.js` 新增 case13–22,
|
|
46
|
+
覆盖 symlink 守卫纵深(realpath 归一化)与 installer 回归,72 断言全绿;`bin/` 未动,无真实绕过
|
|
47
|
+
- **分发体积与性能**(Worker B):无真问题。0.4.1 tarball 解包 29.1MB(0.3.9 18.4MB,
|
|
48
|
+
+10.7MB 系封面示例画廊预期增量);top10 大文件全合法素材;48 图标 PNG 最大 27.4KB 无异常;
|
|
49
|
+
install 耗时 0.3s 不需优化;`sync_npm_files.js --check` 通过
|
|
50
|
+
- 技能版本号保持:wechat-post / x-article 保持 0.1.0(纯 bug 修复按技能版本规则不 bump);
|
|
51
|
+
cover 保持 0.2.0、ppt-html 保持 0.2.1、根包保持 0.4.1
|
|
52
|
+
|
|
53
|
+
## [0.4.0] - 2026-09-29
|
|
54
|
+
|
|
55
|
+
> **本版备发**(tag v0.4.0 待打;npm 待发布;commit = 本轮审计报告落盘时的 `git log` 首条)。
|
|
56
|
+
> 根包 0.3.9 → **0.4.0**(minor,本轮是功能轮);技能版本:top-ppt-html 0.1.19 → **0.2.0**、topmind-cover 0.1.0 → **0.2.0**、topmind-wechat-post / topmind-x-article 保持 0.1.0。
|
|
57
|
+
> 本轮是"对标业界+浅色封面+图标包版式"的功能轮(第十二轮)。
|
|
58
|
+
|
|
59
|
+
### 安装器(Worker A)
|
|
60
|
+
|
|
61
|
+
- 新增 `uninstall <id> [--to]` 命令:卸载已安装技能,`--to` 指向文件/缺目录时干净报错 exit 1
|
|
62
|
+
- `install` 已装版本感知:已装同版本拒绝安装并给出三行摘要(当前版本/来源/提示 uninstall 或覆盖),不再静默覆盖
|
|
63
|
+
- `scripts/test_installer_cli.js`:10 用例 38 断言,覆盖 install/uninstall/list/负向输入
|
|
64
|
+
- `--help` 更新、根 README.md/README.en.md 安装章节重写(`github:` 口径、钉版本示例同步 0.4.0)
|
|
65
|
+
- `.github/workflows/ci.yml` 新增 "Installer CLI tests" step
|
|
66
|
+
|
|
67
|
+
### topmind-cover 0.2.0(Worker B)
|
|
68
|
+
|
|
69
|
+
- 新增 3 个浅色风格:`white-clean`(排第一,标题冲击目标 1/3 字高)、`bg-blur`(背景虚化突出前景)、`paper-collage`(纸拼贴质感)
|
|
70
|
+
- `cover-styles.md` 11 风格重排为浅色优先;`impact-language.md` 补条目;SKILL.md 新增"直出/讨论"决策流
|
|
71
|
+
- 6 张新风格样张 + `overview.png` 重建;`references/ref-white-clean-1/2.png` 新增参考图
|
|
72
|
+
|
|
73
|
+
### top-ppt-html 0.2.0(Worker C)
|
|
74
|
+
|
|
75
|
+
- 内置原创图标包 `assets/icons/`:48 SVG + 48 PNG + `index.json` 映射,7 个默认图标兜底;`scripts/check_icons.py`(`--strict`)做图标一致性门禁;`references/icons.md` 文档化
|
|
76
|
+
- 3 种 layout variant:bento-grid / timeline / 2-col-feature(`references/layout-variants.md`);`references/style-pack.md` 风格包文档化
|
|
77
|
+
- `validate_report.py` 新增内容覆盖率检查(<95% WARN);随门禁修复 6 个真实丢字 bug
|
|
78
|
+
- `scripts/layout-constants.json` 加 adaptiveText 弹性文本规则;HTML/PPTX 弹性适配减少溢出截断
|
|
79
|
+
|
|
80
|
+
## [0.3.9] - 2026-09-29
|
|
81
|
+
|
|
82
|
+
> **本版备发**(tag v0.3.9 待打;npm 待发布;commit = 本轮审计报告落盘时的 `git log` 首条)。
|
|
83
|
+
> 注:0.3.7、0.3.8 未发布,全部内容已并入本版。
|
|
84
|
+
> 根包 0.3.8 → **0.3.9**(patch);4 个技能 `version` 保持不动(top-ppt-html 0.1.19,其余 0.1.0)。
|
|
85
|
+
> 本轮是"新鲜眼睛"横扫(第十一轮):只找前十轮没覆盖的盲区,改动最小。
|
|
86
|
+
|
|
87
|
+
### 代码异味横扫(第十一轮 Worker A)
|
|
88
|
+
|
|
89
|
+
- TODO 注释 6 命中 → 0 真遗留(均为有意为之:文档纪律说明/scaffold 指导注释/校验正则/示例代称)
|
|
90
|
+
- 死代码:全仓 Python + top-ppt-html JS 逐函数交叉 grep,零死函数;12 个 CLI 参数逐个验证全部在用
|
|
91
|
+
- 跨技能一致性修复:19 处错误信息半角冒号 `错误:` → 全角 `错误:`(多数派 47 处);`validate_report.py` 加 `-h/--help` 早退(exit 0),与其他 argparse CLI 一致
|
|
92
|
+
- 重复逻辑(仅记录,不重构):`esc()` HTML 转义三处逐字相同、`read_frontmatter()` 跨技能同构、`load_constants()` 各自实现——均为四技能同构门禁的有意设计
|
|
93
|
+
|
|
94
|
+
### 对抗输入测试(第十一轮 Worker B:5 真崩溃全部修复)
|
|
95
|
+
|
|
96
|
+
- `bin/tms-skills.js`:`--to` 指向已存在文件时 `mkdirSync` 抛未捕获堆栈 → try/catch 干净报错 exit 1
|
|
97
|
+
- `md2wechat.py`:`resolve_image` 的 `shutil.copy2`/`os.makedirs` 未捕获 OSError(磁盘满/目录当图片)→ 干净报错 exit 1
|
|
98
|
+
- `md2x.py`:输出写入 `mkdir`+`write_text` 未捕获 OSError → 干净报错 exit 1;目录当输入的报错文案修正("找不到输入文件"→"输入是目录不是文件")
|
|
99
|
+
- `crop-cover.py`:`out_dir.mkdir` 与渲染循环 `out.save` 未捕获 OSError(磁盘满→截断 PNG)→ 干净报错 exit 1
|
|
100
|
+
- 对抗矩阵:100KB 单行/emoji+零宽+混合换行/非法 UTF-8/空文件/纯标题/48MB 图片,其余全部干净通过
|
|
101
|
+
|
|
102
|
+
### 文档一致性(第十一轮 Worker C)
|
|
103
|
+
|
|
104
|
+
- 审计结论抽查 5 处全部为真(architecture 归一化/SKILL.md 13KB 预算/cover 触发词/ip-fun 原位垫色块补丁/footer 移出 content 标记)
|
|
105
|
+
- SKILL.md vs --help 漂移修复 1 处:wechat-post SKILL.md 注释声称 `--workspace` 参数,全仓无此参数 → 改为 `--base`
|
|
106
|
+
- README 示例 10/10 实跑通过(/tmp 干净目录,本地包安装)
|
|
107
|
+
|
|
108
|
+
## [0.3.8] - 2026-09-29
|
|
109
|
+
|
|
110
|
+
> **本版未发布**(未打 tag、未推 npm;0.3.8 全部内容已并入 0.3.9)。
|
|
111
|
+
> 根包 0.3.6 → **0.3.8**(patch);4 个技能 `version` 保持不动(top-ppt-html 0.1.19,其余 0.1.0)。
|
|
112
|
+
> 本轮只动 top-ppt-html + 文档:渲染产出目检修复(A)+ PPTX 双引擎保真修复 11 bug(B)+ 文档修正(C)。
|
|
113
|
+
|
|
114
|
+
### 模板 footer 修复(第十轮 Worker A:渲染产出目检)
|
|
115
|
+
|
|
116
|
+
- `top-ppt-html/assets/templates/{presentation,research,architecture}.html`:`<footer>` 移出 `__TOPPPT_CONTENT_START__`/`__TOPPPT_CONTENT_END__` 标记之外——此前自动渲染取 content 区间时会连带删除页脚,目检确认已修复。
|
|
117
|
+
|
|
118
|
+
### PPTX 双引擎保真修复(第十轮 Worker B:PPTX 实检,11 bug 全部像素复验)
|
|
119
|
+
|
|
120
|
+
- `top-ppt-html/scripts/build_pptx.js` + `assets/pptx-export.js`(双端同规则):
|
|
121
|
+
- 图表数据标签小数位:按模型数值实际小数位(上限 2 位)生成 format code,修复小数标签被截断
|
|
122
|
+
- hbar 条形图:类目轴自下而上绘制,反转数据使首项居顶;单系列颜色按数据点分配(跟随数据归属,与 A 通道一致)
|
|
123
|
+
- streamgraph 退化:相邻 ribbon quad 沿走向微叠 0.02in,消除拼接处抗锯齿发丝缝
|
|
124
|
+
- boxplot:min 标签默认移到须线帽下方,不再被组标签带压住叠印
|
|
125
|
+
- marimekko:单元格归一化兼容裸数值或 `[标签,数值]` 对(裸数值沿用旧行为),修复 NaN 崩坏
|
|
126
|
+
- pyramid:标题列宽按层内宽比例(labelFrac≈0.3)分配,顶层窄时改单框混排,修复窄层标题/说明叠印
|
|
127
|
+
- KPI:第 4 个起的支撑指标不再静默截断——容量按最小允许行高计算、行高按全部指标自适应压缩,超容显式告警
|
|
128
|
+
- donut 图例:百分比列 x(`donut.legendPctX` 5.3 → 10.8)右移,修复图例数值被圆环覆盖
|
|
129
|
+
- table:内容高度逐格预估、超高全表收字号,字号触底仍装不下则显式告警(不再撑高行压脚注)
|
|
130
|
+
- exhibit 徽标:纯编号自动补 `Exhibit ` 前缀(与 HTML 视觉一致),已带前缀的不重复
|
|
131
|
+
- sankey/streamgraph note:note 与 footnote 均参与 `chartBottom` 结算,修复 note 重叠
|
|
132
|
+
- `top-ppt-html/scripts/layout-constants.json`:`donut.legendPctX` 5.3 → 10.8(单源),已由 `sync_runtime.py` 同步至 `pptx-export.js`、画廊、`templates/*.html`、示例的内联副本与 `__TOPPPT_RUNTIME_SHA__` 戳
|
|
133
|
+
|
|
134
|
+
### 文档修正(第十轮 Worker C)
|
|
135
|
+
|
|
136
|
+
- 根 README(中英):当前线 0.2.x → 0.3.x;`topmind-cover` "17 张双尺寸" → "16 张双尺寸 + 1 张风格总览图"
|
|
137
|
+
- `docs/PUBLISHING.md`:`latest` 指向 0.3.1 → 0.3.6
|
|
138
|
+
- `topmind-wechat-post/README`(中英):二级标题编号示例 `01` → `1`
|
|
139
|
+
|
|
140
|
+
## [0.3.7] - 2026-09-29
|
|
141
|
+
|
|
142
|
+
> **本版未发布**(未打 tag、未推 npm;0.3.7 全部内容已并入 0.3.8)。
|
|
143
|
+
> 根包 0.3.6 → **0.3.7**(patch);4 个技能 `version` 保持不动(top-ppt-html 0.1.19,其余 0.1.0)。
|
|
144
|
+
> 本轮只动 topmind-cover:文字排印与装饰系统(第九轮)。
|
|
145
|
+
|
|
146
|
+
### 文字排印与装饰系统(第九轮)
|
|
147
|
+
|
|
148
|
+
- `topmind-cover/references/impact-language.md`:新增第七节"文字装饰系统"(+38 行):6 种可靠装饰(关键词变色/字号对比/色块衬底/轻微阴影立体/手绘划线圈注箭头/小元素旋转≤8°)各给效果/风险/适用风格/提示词写法四列 + 8 风格各 2~3 种必用装饰指定 + 7 条装饰禁令(禁大标题透视/一句话超 3 色/三重叠加/竖排+旋转/色块吞字/装饰压笔画/装饰超量)
|
|
149
|
+
- `topmind-cover/references/cover-styles.md`(316→359 行):8 风格提示词新增"文字特效"段(中英双语,全部含色号与量化参数,如"钩子词放大 1.5 倍""色块高 1.2 倍字高""投影偏移 1/10 字高");各风格"绝不"清单追加装饰禁令;news-flash 单色铁律放宽为"纯黑打底+爆点词朱红点睛"(仍 ≤3 色,与参考图布局/配色/文字结构全错开);brand-launch 品牌词发光描边改为荧光绿块衬底
|
|
150
|
+
- `topmind-cover/SKILL.md`(114→116 行):冲击力自检清单追加第 9/10 条——中文逐字正确(装饰未导致错字/乱码/笔画粘连)、装饰手法 ≤ 该风格指定数量(minimal 只许 1 种);"必过 8 项"同步为"必过 10 项"
|
|
151
|
+
- 16 张样张全部重生成(标题沿用第八轮):三重目检通过——中文逐字正确(装饰是错字重灾区,逐字核对)、每张 ≥2 种装饰生效且不乱(minimal 仅 1 种)、与 7 张参考图无实质相似;返工 1 次(magazine 首版比例错误)
|
|
152
|
+
|
|
1
153
|
## [0.3.6] - 2026-09-29
|
|
2
154
|
|
|
155
|
+
> **本版已发布**(commit 5dc0bb8,tag v0.3.6,GitHub Release + npm @0.3.6,latest 已切换)。
|
|
3
156
|
> 根包 0.3.5 → **0.3.6**(patch);4 个技能 `version` 保持不动(top-ppt-html 0.1.19,其余 0.1.0)。
|
|
4
157
|
> 本轮只动 topmind-cover:冲击力升级(第八轮)。
|
|
5
158
|
|
package/README.en.md
CHANGED
|
@@ -39,14 +39,14 @@ npx @topmindspace/tms-skills install topmind-x-article
|
|
|
39
39
|
|
|
40
40
|
### topmind-cover · Cover art generation
|
|
41
41
|
|
|
42
|
-
Shared cover art for X long-form and WeChat: striking, eye-catching, theme-focused. **Pick a style → check the example → compose the prompt from the recipe**, then one-click crop to both platform sizes with `crop-cover.py` (X 1200×675, WeChat 900×383).
|
|
42
|
+
Shared cover art for X long-form and WeChat: striking, eye-catching, theme-focused. **Pick a style → check the example → compose the prompt from the recipe**, then one-click crop to both platform sizes with `crop-cover.py` (X 1200×675, WeChat 900×383). 11-style index and recipes: [`references/cover-styles.md`](./topmind-cover/references/cover-styles.md).
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
npx @topmindspace/tms-skills install topmind-cover
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
<p align="center">
|
|
49
|
-
<img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover ·
|
|
49
|
+
<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" />
|
|
50
50
|
</p>
|
|
51
51
|
|
|
52
52
|
> Let ideas fly — make good thinking visible.
|
|
@@ -55,18 +55,18 @@ npx @topmindspace/tms-skills install topmind-cover
|
|
|
55
55
|
<img src="docs/assets/tms-skills-banner.png" alt="tms-skills · top-ppt-html — formal business presentations" width="960" />
|
|
56
56
|
</p>
|
|
57
57
|
|
|
58
|
-
> **Warning**: do not install `@topmindspace/tms-skills@^2` (2.0.0–2.1.1 deprecated). Current line is **0.
|
|
58
|
+
> **Warning**: do not install `@topmindspace/tms-skills@^2` (2.0.0–2.1.1 deprecated). Current line is **0.3.x** (`latest`).
|
|
59
59
|
|
|
60
60
|
## Skills
|
|
61
61
|
|
|
62
62
|
| Skill | Version | What it does |
|
|
63
63
|
|-------|---------|--------------|
|
|
64
|
-
| [`top-ppt-html`](./top-ppt-html/) | **0.1
|
|
64
|
+
| [`top-ppt-html`](./top-ppt-html/) | **0.2.1** | Formal business decks: paginated HTML + editable 16:9 PPTX; dual delivery · MD3-inspired density; 3 modes × 9 styles; strict 0/0 |
|
|
65
65
|
| [`topmind-wechat-post`](./topmind-wechat-post/) | **0.1.0** | WeChat article lifecycle: package, review, 3 quality gates, inline typography & publish checklist |
|
|
66
66
|
| [`topmind-x-article`](./topmind-x-article/) | **0.1.0** | X long-form one-click publish: Markdown → paste-ready plain text + cover + checklist |
|
|
67
|
-
| [`topmind-cover`](./topmind-cover/) | **0.
|
|
67
|
+
| [`topmind-cover`](./topmind-cover/) | **0.2.0** | Cover art for X / WeChat: striking, theme-focused; 11-style cover style library + 26 example images (incl. 3 alt samples) + 1 style overview |
|
|
68
68
|
|
|
69
|
-
Installer [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) is **0.
|
|
69
|
+
Installer [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) is **0.4.1** (whole-repo same-tag releases).
|
|
70
70
|
|
|
71
71
|
## Install
|
|
72
72
|
|
|
@@ -76,7 +76,8 @@ Installer [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspa
|
|
|
76
76
|
npx @topmindspace/tms-skills list
|
|
77
77
|
npx @topmindspace/tms-skills install top-ppt-html
|
|
78
78
|
npx @topmindspace/tms-skills install top-ppt-html --to ./.claude/skills
|
|
79
|
-
npx @topmindspace/tms-skills@0.
|
|
79
|
+
npx @topmindspace/tms-skills@0.4.1 install top-ppt-html # pin
|
|
80
|
+
npx @topmindspace/tms-skills uninstall top-ppt-html --to ./.claude/skills
|
|
80
81
|
```
|
|
81
82
|
|
|
82
83
|
```bash
|
|
@@ -84,7 +85,9 @@ npx @topmindspace/tms-skills@0.3.6 install top-ppt-html # pin
|
|
|
84
85
|
npx github:topmindspace/tms-skills install top-ppt-html
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
Default probe order: `./.agents` → `./.claude` → `./.cursor` → `./.codex` → `./.mimocode`, then user-level `~/.claude`, etc. Or pass `--to`. Do not `npm install top-ppt-html` (skill id is not a standalone package).
|
|
88
|
+
Default probe order: `./.agents` → `./.claude` → `./.cursor` → `./.codex` → `./.mimocode`, then user-level `~/.claude`, etc. Or pass `--to`. When `--to` is omitted, the install summary explicitly prints the auto-detected target directory. Do not `npm install top-ppt-html` (skill id is not a standalone package).
|
|
89
|
+
|
|
90
|
+
`install` details: if a same-named skill already exists, the installed version is reported and overwriting is refused — pass `--force` to replace (or `uninstall` first). On success, a three-line summary is printed: where it was installed / installed skill version and installer version / next steps.
|
|
88
91
|
|
|
89
92
|
PPTX export needs `npm install` in the skill folder (pptxgenjs). HTML generation uses Python stdlib only.
|
|
90
93
|
|
|
@@ -93,7 +96,7 @@ PPTX export needs `npm install` in the skill folder (pptxgenjs). HTML generation
|
|
|
93
96
|
```
|
|
94
97
|
tms-skills/
|
|
95
98
|
├─ top-ppt-html/ # skill (SKILL.md + assets + references + scripts)
|
|
96
|
-
├─ bin/tms-skills.js # CLI: list / install
|
|
99
|
+
├─ bin/tms-skills.js # CLI: list / install / uninstall
|
|
97
100
|
├─ docs/ # publishing · showcase shots · banner · Pages source
|
|
98
101
|
├─ scripts/ # repo gates / privacy scan
|
|
99
102
|
├─ package.json # @topmindspace/tms-skills
|
package/README.md
CHANGED
|
@@ -37,14 +37,14 @@ npx @topmindspace/tms-skills install topmind-x-article
|
|
|
37
37
|
|
|
38
38
|
### topmind-cover · 封面配图生成
|
|
39
39
|
|
|
40
|
-
X 长文与公众号共用的封面图:震撼、醒目、主题突出。**选风格 → 看示例 → 按配方组 prompt** 三步出图,`crop-cover.py` 一键裁出双平台尺寸(X 1200×675、公众号 900×383)。
|
|
40
|
+
X 长文与公众号共用的封面图:震撼、醒目、主题突出。**选风格 → 看示例 → 按配方组 prompt** 三步出图,`crop-cover.py` 一键裁出双平台尺寸(X 1200×675、公众号 900×383)。11 种风格索引与配方见 [`references/cover-styles.md`](./topmind-cover/references/cover-styles.md)。
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
43
|
npx @topmindspace/tms-skills install topmind-cover
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
<p align="center">
|
|
47
|
-
<img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover ·
|
|
47
|
+
<img src="https://github.com/topmindspace/tms-skills/raw/main/topmind-cover/assets/examples/overview.png" alt="topmind-cover · 11 封面风格总览" width="960" />
|
|
48
48
|
</p>
|
|
49
49
|
|
|
50
50
|
> 让 idea 飞,好想法被看见。
|
|
@@ -53,18 +53,18 @@ npx @topmindspace/tms-skills install topmind-cover
|
|
|
53
53
|
<img src="docs/assets/tms-skills-banner.png" alt="tms-skills · top-ppt-html — formal business presentations" width="960" />
|
|
54
54
|
</p>
|
|
55
55
|
|
|
56
|
-
> **警告**:不要安装 `@topmindspace/tms-skills@^2`(2.0.0–2.1.1 已弃用)。当前线 **0.
|
|
56
|
+
> **警告**:不要安装 `@topmindspace/tms-skills@^2`(2.0.0–2.1.1 已弃用)。当前线 **0.3.x**(`latest`)。
|
|
57
57
|
|
|
58
58
|
## 技能一览
|
|
59
59
|
|
|
60
60
|
| 技能 | 版本 | 做什么 |
|
|
61
61
|
|------|------|--------|
|
|
62
|
-
| [`top-ppt-html`](./top-ppt-html/) | **0.1
|
|
62
|
+
| [`top-ppt-html`](./top-ppt-html/) | **0.2.1** | 正式商务演示:HTML 可翻页 + 16:9 可编辑 PPTX;双交付 · MD3 密度克制;三模式 × 九风格;strict 0/0 |
|
|
63
63
|
| [`topmind-wechat-post`](./topmind-wechat-post/) | **0.1.0** | 公众号文章全生命周期:交付包、审校改写、质量三关、微信内联排版与发布清单 |
|
|
64
64
|
| [`topmind-x-article`](./topmind-x-article/) | **0.1.0** | X 长文一键发布:Markdown 原稿转可直接粘贴的纯文本 + 封面图 + 发布清单 |
|
|
65
|
-
| [`topmind-cover`](./topmind-cover/) | **0.
|
|
65
|
+
| [`topmind-cover`](./topmind-cover/) | **0.2.0** | 文章封面配图(X / 公众号共用):震撼醒目主题突出;11 风格封面风格库 + 26 张示例图(含 3 张 alt 样张) + 1 张风格总览图 |
|
|
66
66
|
|
|
67
|
-
安装器 [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) 为 **0.
|
|
67
|
+
安装器 [`@topmindspace/tms-skills`](https://www.npmjs.com/package/@topmindspace/tms-skills) 为 **0.4.1**(整仓同 tag 发版)。
|
|
68
68
|
|
|
69
69
|
> SKILL.md frontmatter 除标准 `name`/`description` 外,本仓库扩展了 `action_category` / `triggers` / `triggers_cn` / `updated` 字段供安装器与路由使用。
|
|
70
70
|
|
|
@@ -76,7 +76,8 @@ npx @topmindspace/tms-skills install topmind-cover
|
|
|
76
76
|
npx @topmindspace/tms-skills list
|
|
77
77
|
npx @topmindspace/tms-skills install top-ppt-html
|
|
78
78
|
npx @topmindspace/tms-skills install top-ppt-html --to ./.claude/skills
|
|
79
|
-
npx @topmindspace/tms-skills@0.
|
|
79
|
+
npx @topmindspace/tms-skills@0.4.1 install top-ppt-html # 钉版本
|
|
80
|
+
npx @topmindspace/tms-skills uninstall top-ppt-html --to ./.claude/skills
|
|
80
81
|
```
|
|
81
82
|
|
|
82
83
|
```bash
|
|
@@ -84,7 +85,9 @@ npx @topmindspace/tms-skills@0.3.6 install top-ppt-html # 钉版本
|
|
|
84
85
|
npx github:topmindspace/tms-skills install top-ppt-html
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
默认探测:`./.agents` → `./.claude` → `./.cursor` → `./.codex` → `./.mimocode`,再用户级 `~/.claude` 等;也可用 `--to
|
|
88
|
+
默认探测:`./.agents` → `./.claude` → `./.cursor` → `./.codex` → `./.mimocode`,再用户级 `~/.claude` 等;也可用 `--to`。未给 `--to` 时安装摘要会明确打印探测到的目标目录。不要 `npm install top-ppt-html`(技能 id 不是独立包)。
|
|
89
|
+
|
|
90
|
+
`install` 细节:若同名技能已存在,会报出已装版本并拒绝覆盖,需加 `--force` 才替换(或先 `uninstall` 再装)。安装成功后打印三行摘要:装到哪里 / 装的技能版本与安装器版本 / 下一步。
|
|
88
91
|
|
|
89
92
|
PPTX 精导需在技能目录 `npm install`(pptxgenjs)。HTML 生成仅 Python 标准库。
|
|
90
93
|
|
|
@@ -93,7 +96,7 @@ PPTX 精导需在技能目录 `npm install`(pptxgenjs)。HTML 生成仅 Pyth
|
|
|
93
96
|
```
|
|
94
97
|
tms-skills/
|
|
95
98
|
├─ top-ppt-html/ # 技能(SKILL.md + assets + references + scripts)
|
|
96
|
-
├─ bin/tms-skills.js # CLI:list / install
|
|
99
|
+
├─ bin/tms-skills.js # CLI:list / install / uninstall
|
|
97
100
|
├─ docs/ # 发布规范 · showcase 截图 · banner · Pages 源
|
|
98
101
|
├─ scripts/ # 仓库级门禁 / 隐私扫描
|
|
99
102
|
├─ package.json # @topmindspace/tms-skills
|
package/bin/tms-skills.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* npx @topmindspace/tms-skills install top-ppt-html
|
|
11
11
|
* npx @topmindspace/tms-skills install top-ppt-html --to ./skills-out
|
|
12
12
|
* npx @topmindspace/tms-skills install top-ppt-html --force
|
|
13
|
+
* npx @topmindspace/tms-skills uninstall top-ppt-html --to ./skills-out
|
|
13
14
|
* npx github:topmindspace/tms-skills install top-ppt-html # follow repo HEAD
|
|
14
15
|
*/
|
|
15
16
|
'use strict';
|
|
@@ -69,6 +70,30 @@ function readSkillMeta(skillId) {
|
|
|
69
70
|
return { id: skillId, description: String(desc).slice(0, 120) };
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/** 读技能目录下 SKILL.md frontmatter 的 version 字段(读不到返回 '',调用方兜底)。 */
|
|
74
|
+
function readSkillVersion(skillPath) {
|
|
75
|
+
try {
|
|
76
|
+
const p = path.join(skillPath, 'SKILL.md');
|
|
77
|
+
if (!fs.existsSync(p)) return '';
|
|
78
|
+
const text = fs.readFileSync(p, 'utf8');
|
|
79
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
80
|
+
if (!m) return '';
|
|
81
|
+
const v = m[1].match(/^version:\s*(.+?)\s*$/m);
|
|
82
|
+
return v ? v[1] : '';
|
|
83
|
+
} catch {
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function installerVersion() {
|
|
89
|
+
try {
|
|
90
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
|
|
91
|
+
return pkg.version || 'unknown';
|
|
92
|
+
} catch {
|
|
93
|
+
return 'unknown';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
72
97
|
function resolveDefaultTarget() {
|
|
73
98
|
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
74
99
|
const candidates = [
|
|
@@ -112,15 +137,34 @@ function normPath(p) {
|
|
|
112
137
|
return process.platform === 'win32' ? s.toLowerCase() : s;
|
|
113
138
|
}
|
|
114
139
|
|
|
140
|
+
/** realpath 能解析就解析(跟符号链接),失败回退 path.resolve。
|
|
141
|
+
* dest 可能还不存在(install 流程):往上找最深存在的祖先解析后再拼回。
|
|
142
|
+
* 否则 --to 经符号链接指向包内时,词法比对会被绕过(rmSync 会跟链接删掉源)。 */
|
|
143
|
+
function realOrResolved(p) {
|
|
144
|
+
let cur = path.resolve(p);
|
|
145
|
+
const tail = [];
|
|
146
|
+
for (;;) {
|
|
147
|
+
try {
|
|
148
|
+
return path.join(fs.realpathSync(cur), ...tail);
|
|
149
|
+
} catch {
|
|
150
|
+
const parent = path.dirname(cur);
|
|
151
|
+
if (parent === cur) return path.join(cur, ...tail);
|
|
152
|
+
tail.unshift(path.basename(cur));
|
|
153
|
+
cur = parent;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
115
158
|
/** 安装目标守卫(审计 严重-2):
|
|
116
159
|
* dest == 技能源目录 → --force 会先 rmSync 删掉源目录,再"成功"装出空目录(数据丢失 + 虚假成功);
|
|
117
160
|
* dest 在源目录内部 → copyDir 无限递归复制直至 ENAMETOOLONG,并留下垃圾目录树。
|
|
118
|
-
*
|
|
161
|
+
* realpath 归一化后比对(dest === src,或 dest 以 src + 路径分隔符开头),
|
|
162
|
+
* 防止 --to 经符号链接指向包内绕过词法比对;
|
|
119
163
|
* Windows 下额外做大小写归一。无论是否 --force,一律拒绝。
|
|
120
164
|
*/
|
|
121
165
|
function assertDestOutsideSource(src, dest) {
|
|
122
|
-
const absSrc = normPath(src);
|
|
123
|
-
const absDest = normPath(dest);
|
|
166
|
+
const absSrc = normPath(realOrResolved(src));
|
|
167
|
+
const absDest = normPath(realOrResolved(dest));
|
|
124
168
|
if (absDest === absSrc || absDest.startsWith(absSrc + path.sep)) {
|
|
125
169
|
die(
|
|
126
170
|
`Refusing to install into the skill's own directory tree.\n` +
|
|
@@ -132,7 +176,7 @@ function assertDestOutsideSource(src, dest) {
|
|
|
132
176
|
}
|
|
133
177
|
}
|
|
134
178
|
|
|
135
|
-
function install(skillId, targetRoot, { force = false } = {}) {
|
|
179
|
+
function install(skillId, targetRoot, { force = false, defaultTarget = false } = {}) {
|
|
136
180
|
assertSkillId(skillId);
|
|
137
181
|
const src = skillDir(skillId);
|
|
138
182
|
if (!fs.existsSync(path.join(src, 'SKILL.md'))) {
|
|
@@ -140,25 +184,85 @@ function install(skillId, targetRoot, { force = false } = {}) {
|
|
|
140
184
|
}
|
|
141
185
|
const dest = path.join(targetRoot, skillId);
|
|
142
186
|
assertDestOutsideSource(src, dest);
|
|
143
|
-
|
|
187
|
+
try {
|
|
188
|
+
fs.mkdirSync(targetRoot, { recursive: true });
|
|
189
|
+
} catch (e) {
|
|
190
|
+
die(
|
|
191
|
+
`Cannot create install directory: ${targetRoot}\n` +
|
|
192
|
+
` reason: ${e.message}\n` +
|
|
193
|
+
'Choose a --to directory that can be created (not a file, not unwritable).'
|
|
194
|
+
);
|
|
195
|
+
}
|
|
144
196
|
if (fs.existsSync(dest)) {
|
|
145
197
|
if (!force) {
|
|
198
|
+
// 已装过:报出已装版本,要求 --force 才覆盖(不静默覆盖)。
|
|
199
|
+
const installedVer = readSkillVersion(dest) || 'unknown';
|
|
200
|
+
const packageVer = readSkillVersion(src) || 'unknown';
|
|
146
201
|
die(
|
|
147
|
-
`
|
|
148
|
-
|
|
202
|
+
`Already installed: ${dest}\n` +
|
|
203
|
+
` installed version: ${installedVer} (this package ships ${packageVer})\n` +
|
|
204
|
+
'Refusing to overwrite. Pass --force (or -f) to replace, or remove it first:\n' +
|
|
205
|
+
` tms-skills uninstall ${skillId} --to ${targetRoot}`
|
|
149
206
|
);
|
|
150
207
|
}
|
|
151
208
|
fs.rmSync(dest, { recursive: true, force: true });
|
|
152
209
|
}
|
|
153
210
|
copyDir(src, dest);
|
|
211
|
+
// 安装摘要三行:装到哪里 / 装了什么版本 / 下一步。
|
|
212
|
+
const toNote = defaultTarget ? ' (default, auto-detected — no --to given)' : '';
|
|
213
|
+
const skillVer = readSkillVersion(dest) || 'unknown';
|
|
154
214
|
console.log(`Installed ${skillId}`);
|
|
155
|
-
console.log(`
|
|
156
|
-
console.log(`
|
|
215
|
+
console.log(` to: ${dest}${toNote}`);
|
|
216
|
+
console.log(` version: skill ${skillVer} (installer ${installerVersion()})`);
|
|
217
|
+
console.log(` next: ${nextStep(skillId, dest)}`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function nextStep(skillId, dest) {
|
|
157
221
|
if (skillId === 'top-ppt-html') {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
222
|
+
return `optional (PPTX export only): cd "${dest}" && npm install — then restart your agent so it picks up the skill`;
|
|
223
|
+
}
|
|
224
|
+
return 'restart your agent so it picks up the skill';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** 列出目标根目录下已安装的技能(有 SKILL.md 的子目录)。 */
|
|
228
|
+
function listInstalledIds(targetRoot) {
|
|
229
|
+
try {
|
|
230
|
+
return fs
|
|
231
|
+
.readdirSync(targetRoot, { withFileTypes: true })
|
|
232
|
+
.filter((d) => d.isDirectory() && fs.existsSync(path.join(targetRoot, d.name, 'SKILL.md')))
|
|
233
|
+
.map((d) => d.name)
|
|
234
|
+
.sort();
|
|
235
|
+
} catch {
|
|
236
|
+
return [];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function uninstall(skillId, targetRoot) {
|
|
241
|
+
assertSkillId(skillId);
|
|
242
|
+
const src = skillDir(skillId);
|
|
243
|
+
const dest = path.join(targetRoot, skillId);
|
|
244
|
+
// 守卫:--to 指到包内时,dest 会命中安装器自带的技能源目录 → 一律拒绝,
|
|
245
|
+
// 防止把仓库自身的技能目录删掉(同 install 的 assertDestOutsideSource)。
|
|
246
|
+
if (fs.existsSync(path.join(src, 'SKILL.md'))) {
|
|
247
|
+
assertDestOutsideSource(src, dest);
|
|
248
|
+
}
|
|
249
|
+
if (!fs.existsSync(dest)) {
|
|
250
|
+
const installed = listInstalledIds(targetRoot);
|
|
251
|
+
die(
|
|
252
|
+
`Nothing to uninstall: ${dest}\n` +
|
|
253
|
+
` skill '${skillId}' is not installed under ${targetRoot}.` +
|
|
254
|
+
(installed.length ? `\n installed here: ${installed.join(', ')}` : '')
|
|
255
|
+
);
|
|
161
256
|
}
|
|
257
|
+
if (!fs.existsSync(path.join(dest, 'SKILL.md'))) {
|
|
258
|
+
die(
|
|
259
|
+
`Refusing to uninstall: ${dest}\n` +
|
|
260
|
+
` not a skill directory (missing SKILL.md) — will not delete arbitrary folders.`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
264
|
+
console.log(`Uninstalled ${skillId}`);
|
|
265
|
+
console.log(` from ${dest}`);
|
|
162
266
|
}
|
|
163
267
|
|
|
164
268
|
function usageText() {
|
|
@@ -167,16 +271,33 @@ function usageText() {
|
|
|
167
271
|
Usage:
|
|
168
272
|
tms-skills list|ls
|
|
169
273
|
tms-skills install <skill-id> [--to|-t <dir>] [--force|-f]
|
|
274
|
+
tms-skills uninstall <skill-id> [--to|-t <dir>]
|
|
170
275
|
tms-skills help
|
|
171
276
|
|
|
277
|
+
Behavior:
|
|
278
|
+
install copies <skill-id>/ into <dir>/<skill-id>/. If the skill is already
|
|
279
|
+
installed, the installed version is reported and --force is required
|
|
280
|
+
to overwrite. Prints where/what-version/next-steps when done.
|
|
281
|
+
uninstall removes <dir>/<skill-id>/ (refuses: not installed, not a skill
|
|
282
|
+
directory, or the package's own skill source).
|
|
283
|
+
No --to: the target directory is auto-detected (probe order below) and
|
|
284
|
+
printed explicitly in the install summary.
|
|
285
|
+
|
|
286
|
+
Target probe order (no --to): ./.agents/skills, ./.claude/skills,
|
|
287
|
+
./.cursor/skills, ./.codex/skills, ./.mimocode/skills, then
|
|
288
|
+
~/.claude/skills, ~/.agents/skills, ~/.cursor/skills, ~/.codex/skills.
|
|
289
|
+
|
|
172
290
|
Examples (npm recommended when published):
|
|
173
291
|
npx @topmindspace/tms-skills list
|
|
174
292
|
npx @topmindspace/tms-skills install top-ppt-html
|
|
175
293
|
npx @topmindspace/tms-skills install top-ppt-html --to ./.agents/skills
|
|
176
294
|
npx @topmindspace/tms-skills install top-ppt-html --force
|
|
295
|
+
npx @topmindspace/tms-skills uninstall top-ppt-html --to ./.agents/skills
|
|
177
296
|
|
|
178
297
|
# Follow repo HEAD:
|
|
179
298
|
npx github:topmindspace/tms-skills install top-ppt-html
|
|
299
|
+
|
|
300
|
+
Privacy: the installer is fully local — it never collects or uploads anything.
|
|
180
301
|
`;
|
|
181
302
|
}
|
|
182
303
|
|
|
@@ -225,7 +346,26 @@ function main(argv) {
|
|
|
225
346
|
}
|
|
226
347
|
}
|
|
227
348
|
const targetRoot = to ? path.resolve(to) : resolveDefaultTarget();
|
|
228
|
-
install(skillId, targetRoot, { force });
|
|
349
|
+
install(skillId, targetRoot, { force, defaultTarget: !to });
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (cmd === 'uninstall') {
|
|
354
|
+
const skillId = args[1];
|
|
355
|
+
if (!skillId || skillId.startsWith('-')) {
|
|
356
|
+
die('Missing skill id.\n\n' + usageText());
|
|
357
|
+
}
|
|
358
|
+
let to = null;
|
|
359
|
+
for (let i = 2; i < args.length; i++) {
|
|
360
|
+
if (args[i] === '--to' || args[i] === '-t') {
|
|
361
|
+
to = args[++i];
|
|
362
|
+
if (!to) die('Option --to requires a directory path.');
|
|
363
|
+
} else {
|
|
364
|
+
die(`Unknown option: ${args[i]}\n\n` + usageText());
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const targetRoot = to ? path.resolve(to) : resolveDefaultTarget();
|
|
368
|
+
uninstall(skillId, targetRoot);
|
|
229
369
|
return;
|
|
230
370
|
}
|
|
231
371
|
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
**Let ideas fly — make good thinking visible.** A high-craft skill for **demo reports / formal business presentations**: **HTML + PPT dual delivery** — day-to-day, present with paginated HTML like slides; export **layout-faithful editable PPTX** when needed. **MD3-inspired**: fitting information density, restrained type / shapes / color. Core craft is layout, typography, color, and content structure — not gadget soup.
|
|
11
11
|
|
|
12
12
|
- Skill id: `top-ppt-html`; brand: **TopPPT HTML**
|
|
13
|
-
- Version: **v0.1
|
|
13
|
+
- Version: **v0.2.1** (same tag as `@topmindspace/tms-skills@0.4.1`)
|
|
14
14
|
- **Agent entry**: `SKILL.md` → `references/playbook.md` (L1) → L2 on demand
|
|
15
15
|
- **Human maintainers**: this README (install / commands / layout); do not treat it as the generation spec
|
|
16
16
|
|
|
@@ -55,7 +55,7 @@ Also: arrow-key paging; **Esc** closes modals. After style/theme change, re-run
|
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
57
|
npx @topmindspace/tms-skills install top-ppt-html
|
|
58
|
-
npx @topmindspace/tms-skills@0.
|
|
58
|
+
npx @topmindspace/tms-skills@0.4.1 install top-ppt-html
|
|
59
59
|
npx github:topmindspace/tms-skills install top-ppt-html
|
|
60
60
|
```
|
|
61
61
|
|
package/top-ppt-html/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
**让 idea 飞,好想法被看见。** 为**演示报告 / 正式商务演示**而生的高品质演示文稿技能:**HTML + PPT 双交付**——日常用可翻页 HTML 等同幻灯片;需要时再导出**版式保真可编辑 PPTX**。参考 **MD3**:合适信息密度、克制文字/图形/颜色。核心工艺是版式、排版、色彩与内容组织——不是 gadget 堆砌。
|
|
11
11
|
|
|
12
12
|
- 技能标识:`top-ppt-html`;品牌名:**TopPPT HTML**
|
|
13
|
-
- 版本:**v0.1
|
|
13
|
+
- 版本:**v0.2.1**(与 `@topmindspace/tms-skills@0.4.1` 同 tag)
|
|
14
14
|
- **智能体入口**:`SKILL.md` → `references/playbook.md`(L1)→ L2 按需
|
|
15
15
|
- **人类维护者**:本 README(安装 / 命令 / 目录);勿把本文件当生成规范
|
|
16
16
|
|