@topmindspace/tms-skills 0.1.0 → 0.1.2
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 +76 -0
- package/README.md +9 -3
- package/bin/tms-skills.js +200 -160
- package/package.json +12 -9
- package/top-ppt-html/README.md +162 -254
- package/top-ppt-html/SKILL.md +126 -111
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +3926 -3926
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.model.json +167 -167
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +4325 -4325
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.model.json +320 -320
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +5527 -5527
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.model.json +913 -913
- package/top-ppt-html/assets/pptx-export.js +1944 -1944
- package/top-ppt-html/assets/style-gallery.html +589 -589
- package/top-ppt-html/assets/templates/architecture.html +3728 -3728
- package/top-ppt-html/assets/templates/engine.css +840 -840
- package/top-ppt-html/assets/templates/presentation.html +3738 -3738
- package/top-ppt-html/assets/templates/research.html +4017 -4017
- package/top-ppt-html/assets/templates/ui.js +520 -520
- package/top-ppt-html/assets/theme-overview-architecture.png +0 -0
- package/top-ppt-html/assets/theme-overview-research.png +0 -0
- package/top-ppt-html/assets/theme-overview.png +0 -0
- package/top-ppt-html/evals/prompts.csv +15 -15
- package/top-ppt-html/evals/rubric.schema.json +25 -25
- package/top-ppt-html/evals/run_evals.py +220 -220
- package/top-ppt-html/evals/trace.example.json +16 -16
- package/top-ppt-html/package-lock.json +186 -0
- package/top-ppt-html/package.json +11 -11
- package/top-ppt-html/references/charts-basic.md +624 -624
- package/top-ppt-html/references/charts-discipline.md +110 -108
- package/top-ppt-html/references/charts-extended.md +482 -482
- package/top-ppt-html/references/charts.md +37 -28
- package/top-ppt-html/references/components-atoms.md +624 -624
- package/top-ppt-html/references/components.md +30 -30
- package/top-ppt-html/references/content-rules.md +510 -490
- package/top-ppt-html/references/default-surface.md +61 -0
- package/top-ppt-html/references/design-system.md +478 -478
- package/top-ppt-html/references/failure-modes.md +227 -214
- package/top-ppt-html/references/high-fidelity.md +127 -127
- package/top-ppt-html/references/icons.md +176 -397
- package/top-ppt-html/references/infographics-stats.md +308 -308
- package/top-ppt-html/references/infographics-structure.md +226 -226
- package/top-ppt-html/references/infographics.md +43 -43
- package/top-ppt-html/references/layout-grammar.md +325 -315
- package/top-ppt-html/references/layouts-architecture.md +108 -108
- package/top-ppt-html/references/layouts-combo.md +600 -600
- package/top-ppt-html/references/layouts-research.md +160 -160
- package/top-ppt-html/references/modes.md +259 -254
- package/top-ppt-html/references/outline-design.md +275 -275
- package/top-ppt-html/references/playbook.md +284 -266
- package/top-ppt-html/references/pptx-export.md +227 -209
- package/top-ppt-html/references/presentation-craft.md +69 -0
- package/top-ppt-html/references/styles.md +370 -370
- package/top-ppt-html/references/tech-design.md +138 -138
- package/top-ppt-html/scripts/audit_css.py +109 -109
- package/top-ppt-html/scripts/audit_docs.py +176 -176
- package/top-ppt-html/scripts/audit_skill.py +231 -220
- package/top-ppt-html/scripts/audit_styles.py +351 -351
- package/top-ppt-html/scripts/build_examples.py +55 -2276
- package/top-ppt-html/scripts/build_pptx.js +2386 -2380
- package/top-ppt-html/scripts/capture_theme_overview.js +79 -78
- package/top-ppt-html/scripts/checks_html.py +166 -127
- package/top-ppt-html/scripts/cross_verify.py +298 -294
- package/top-ppt-html/scripts/env_probe.py +158 -158
- package/top-ppt-html/scripts/extract_model.py +210 -210
- package/top-ppt-html/scripts/extract_snippet.py +374 -374
- package/top-ppt-html/scripts/gen_channel_a.js +214 -214
- package/top-ppt-html/scripts/layout-constants.json +111 -18
- package/top-ppt-html/scripts/lib_layout_regions.js +410 -412
- package/top-ppt-html/scripts/measure_height.py +178 -178
- package/top-ppt-html/scripts/negative_tests.py +433 -307
- package/top-ppt-html/scripts/package_skill.py +294 -291
- package/top-ppt-html/scripts/prepare_images.py +341 -341
- package/top-ppt-html/scripts/probe_image_export.py +187 -188
- package/top-ppt-html/scripts/quality_gate.py +309 -301
- package/top-ppt-html/scripts/recommend_layout.py +384 -0
- package/top-ppt-html/scripts/regression.py +308 -308
- package/top-ppt-html/scripts/render_compare.py +275 -275
- package/top-ppt-html/scripts/render_from_model.py +698 -698
- package/top-ppt-html/scripts/scaffold_report.py +1054 -1054
- package/top-ppt-html/scripts/section-file-map.json +104 -104
- package/top-ppt-html/scripts/smoke_pptx.sh +30 -0
- package/top-ppt-html/scripts/sync_runtime.py +659 -662
- package/top-ppt-html/scripts/validate_pptx.py +1579 -1510
- package/top-ppt-html/scripts/validate_report.py +1755 -1456
- package/top-ppt-html/assets/examples/2026-09-09-architecture-spectrum.html +0 -3926
- package/top-ppt-html/assets/examples/2026-09-09-architecture-spectrum.model.json +0 -168
- package/top-ppt-html/assets/examples/2026-09-09-presentation-apple-mono.html +0 -4325
- package/top-ppt-html/assets/examples/2026-09-09-presentation-apple-mono.model.json +0 -321
- package/top-ppt-html/assets/examples/2026-09-09-presentation-brand-red.html +0 -4325
- package/top-ppt-html/assets/examples/2026-09-09-presentation-brand-red.model.json +0 -321
- package/top-ppt-html/assets/examples/2026-09-09-research-deep-teal.html +0 -5527
- package/top-ppt-html/assets/examples/2026-09-09-research-deep-teal.model.json +0 -914
- package/top-ppt-html/assets/examples/2026-09-09-research-indigo-violet.html +0 -5527
- package/top-ppt-html/assets/examples/2026-09-09-research-indigo-violet.model.json +0 -914
- package/top-ppt-html/assets/examples/2026-09-09-research-warm-sand.html +0 -5527
- package/top-ppt-html/assets/examples/2026-09-09-research-warm-sand.model.json +0 -914
- package/top-ppt-html/assets/theme-overview-presentation.png +0 -0
- package/top-ppt-html/references/design-system-engine.md +0 -235
- package/top-ppt-html/references/industry-benchmark.md +0 -105
- package/top-ppt-html/references/reform-plan.md +0 -252
- package/top-ppt-html/scripts/layout_slots.json +0 -830
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,81 @@
|
|
|
1
|
+
## Unreleased
|
|
2
|
+
|
|
3
|
+
## 0.1.2 — 2026-09-24
|
|
4
|
+
|
|
5
|
+
### top-ppt-html · P2 cleanup(advanced 按需 · Mode A 次级骨架 · icons 压缩)
|
|
6
|
+
|
|
7
|
+
- **Advanced charts 按需**:默认读面 = `charts-discipline` + 核图 8;`charts-extended.md` **禁止预读**,仅意图命中 `extract_snippet.py --chart`。`charts.variety.preferCoreFirst` + validate WARN(A/B);advanced **计入** `minTypes`(不降 `presentation=4`,不缩 registry)。
|
|
8
|
+
- **Mode A 骨架分层**:主力 P1–P4+P6/P10;次级 P7–P9/P11–P12(`layoutSystem.modeSkels` + layout-grammar / default-surface / recommend_layout 同口径);画廊侧重主力。
|
|
9
|
+
- **icons.md 压缩**:语义表 + 禁区 + 尺寸档 + 高频 20 SVG(~8.7KB);完整枚举 → `docs/archive/refs/icons-catalog.md`;package 仍 REQUIRED。
|
|
10
|
+
- **docs 对齐**:SKILL / playbook / presentation-craft / modes / charts 门面同步;Fast Mode + 长文溢出序保持不变。
|
|
11
|
+
|
|
12
|
+
### Installer
|
|
13
|
+
|
|
14
|
+
- 安装器 `@topmindspace/tms-skills` → **0.1.2**(随技能包内容更新)。
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### top-ppt-html · Long-text / Quality round(反截断 + 门禁加深)
|
|
19
|
+
|
|
20
|
+
- **反截断政策**:Mode A / content-rules / presentation-craft「长文与信息承载」——溢出顺序固定为 重构→拆页/分章→换形态→有限 fontShrink;**禁止**静默截断 / 砍 so-what / 为疏朗删实质。单页字数改预警(presentation char 1800),不为「字多」单独 FAIL。
|
|
21
|
+
- **结构引导取代硬砍刀**:列表/卡片 `maxItemChars` 等改为引导 + prefer;checklist 同步。
|
|
22
|
+
- **layout-qa 加深**:`LAYOUT_QA_TRUNCATION` / `OVERFLOW_NO_SPLIT` / `HALF_EMPTY` / `ALIGN_RHYTHM`;presentation `--strict` 仍自动 layout-qa。负例 L4–L6。
|
|
23
|
+
- **recommend_layout**:高容量意图 → 多页序列(议程→主张→证据卡→明细),禁一页塞爆。
|
|
24
|
+
- **P1-3 charts facade**:纪律优先 → 核图 8 → extended 按需;**不降** `minTypes.presentation=4`。
|
|
25
|
+
- **P1-4 会场字号**:pptx-export venue 表(小会议室 / 默认 / 礼堂)。
|
|
26
|
+
- **P1-6 chrome**:跨页页脚 y 漂移 `CHROME_DRIFT` WARN + 文档说明。
|
|
27
|
+
|
|
28
|
+
### top-ppt-html · Presentation Craft(Mode A 工艺)
|
|
29
|
+
|
|
30
|
+
- **P0-1 图表多样性(用户明确保留)**:**不降** `minTypes.presentation`(仍为 **4**);registry/advanced 图种保留。纪律改为「按内容选型拉开多样」+ 禁反模式(简单全幅 / 极偏 donut / 为过门禁硬上冷门图);playbook §五 / layout-qa 同步。
|
|
31
|
+
- **P0-2 default-surface**:升为 Mode A / Fast 演示主读面(12 页型 + 8 核图 + V1–V4;P5–P12/advanced 按需);SKILL L2 索引指向。
|
|
32
|
+
- **P0-3 layout-qa 默认**:`validate_report --strict` 在 presentation 下自动 `--layout-qa`;`quality_gate` 同口径;B/C 不强制。
|
|
33
|
+
- **P0-4 主张标题**:Mode A action/claim title(禁话题标签)写入 content-rules / modes;校验 WARN。
|
|
34
|
+
- **P0-5 `presentation-craft.md`**:中英术语一页纸清单(one idea / 3s / whitespace / CRAP / motion=none / WCAG…);package REQUIRED。
|
|
35
|
+
- **P1**:fillTarget A 58–75% + intentional whitespace 豁免;`recommend_layout` 偏 V1–V4、降 donut 默认权重;Fast 路演/汇报/发布/演讲/demo→A;motion=none 铁律短句。
|
|
36
|
+
|
|
37
|
+
### top-ppt-html · Batch 3(瘦身)
|
|
38
|
+
|
|
39
|
+
- **归档 L2**:`industry-benchmark.md` / `design-system-engine.md` → `docs/archive/refs/`(生成路径不读)。
|
|
40
|
+
- **layoutSlots 单源**:删除 `scripts/layout_slots.json`;`lib_layout_regions.js` / `sync_runtime.py` 只读 `layout-constants.layoutSlots`。
|
|
41
|
+
- **示例**:`assets/examples/` 仅留 3 份黄金样张(每模式 1);其余 → `docs/archive/examples/`;`build_examples.py` 瘦身为自检(全量脚本归档)。
|
|
42
|
+
- **主题 PNG**:`theme-overview*.png` 量化压缩约 −70%。
|
|
43
|
+
- **default-surface.md**:12 页型 + 8 图 + V1–V4 速查;playbook §五标注默认 8 核心图。
|
|
44
|
+
- **package**:MIN refs ≥20、examples ≥3;`recommend_layout.py` 入 REQUIRED;README 缩为安装+命令索引。
|
|
45
|
+
|
|
46
|
+
### top-ppt-html · Batch 2(布局选型 + layout-qa + PPTX 对齐)
|
|
47
|
+
|
|
48
|
+
- **recommend_layout.py**:`--mode A|B|C` + `--intent` / `--from-model` / `--stdin` → `{pageType,skel,chart,rationale,v?}`(V1–V4 / 极偏禁 donut / sizeByComplexity)。
|
|
49
|
+
- **validate_report.py --layout-qa**:缺 data-skel、连续同骨架、极偏 donut、演示简单全幅、V 契约;negative_tests 增 L1–L3。
|
|
50
|
+
- **cross_verify.py** 默认 SKIP,`--full-ab` 才跑;regression 同口径。
|
|
51
|
+
- **build_pptx.js** 尊重 `layoutPreset`(缺省由 pageToPreset 回填,写入备注)。
|
|
52
|
+
- **smoke_pptx.sh** + CI skill-gates 冒烟:extract_model → build_pptx → validate_pptx --strict。
|
|
53
|
+
|
|
1
54
|
# Changelog
|
|
2
55
|
|
|
56
|
+
## Unreleased
|
|
57
|
+
|
|
58
|
+
### top-ppt-html 0.1.1 — Batch 1(工作流单写 · Fast Mode)
|
|
59
|
+
|
|
60
|
+
- **模型单写统一**:playbook / SKILL / pptx-export 命令链均为 scaffold → 只填 `REPORT_MODEL` → `render_from_model --inplace` → `validate_report --strict`(禁 HTML/模型双写)。
|
|
61
|
+
- **`render_from_model.py` 纳入 package REQUIRED**;references 最小篇数注释对齐实有数量(≥24)。
|
|
62
|
+
- **Fast Mode**:触发词跳过 Gate 0 + 六项;默认 B/mckinsey/light 等;标准路径仍为硬门禁;`audit_skill` 适配豁免声明。
|
|
63
|
+
- **归档** `references/reform-plan.md` → `docs/archive/reform-plan.md`;硬门禁改指 `qualityGates` + `failure-modes`。
|
|
64
|
+
- 技能 `package.json` 版本对齐仓库叙事 `0.1.1`(LC 仍为 `0.1`)。
|
|
65
|
+
|
|
66
|
+
## 0.1.1 — 2026-09-24
|
|
67
|
+
|
|
68
|
+
### Fixes (P0 / P1)
|
|
69
|
+
|
|
70
|
+
- **Release 顺序与稳健性**:Privacy → 技能门禁 → Package → Collect → GitHub Release → **npm publish(已发布则跳过,避免 E409)** → 再 Prune。
|
|
71
|
+
- **Prune 策略**:只删旧 GitHub Release(保留 2 个);**不再删除 git tags**。
|
|
72
|
+
- **多技能发现**:`scripts/discover_skills.js` + CI/Release 动态打包/门禁;`npm run sync:files` 同步 `package.json` `files`。
|
|
73
|
+
- **CLI**:校验 skill id;目标目录已存在时须 `--force`;文档口径与 README 对齐(npm 推荐 / GitHub 跟 HEAD)。
|
|
74
|
+
- **python3**:根与技能 `package.json`、workflows 统一 `python3`。
|
|
75
|
+
- **打包门禁**:`references/layout-grammar.md` 纳入 REQUIRED;去掉与 `theme-overview.png` 完全重复的 `theme-overview-presentation.png`。
|
|
76
|
+
- **Lockfile**:提交 `top-ppt-html/package-lock.json`;CI 优先 `npm ci --omit=dev`。
|
|
77
|
+
- **npm 2.x**:文档警告勿装 `^2`;提供 `scripts/deprecate-npm-2x.sh`(须维护者本地 npm 登录后执行)。
|
|
78
|
+
|
|
3
79
|
## 0.1.0 — 2026-09-24
|
|
4
80
|
|
|
5
81
|
首个公开版本。
|
package/README.md
CHANGED
|
@@ -18,6 +18,12 @@
|
|
|
18
18
|
|
|
19
19
|
两条通道,装出来同一套技能。**npm = 钉版本快照**;**GitHub = 跟仓库 HEAD**。
|
|
20
20
|
|
|
21
|
+
|
|
22
|
+
> **警告 / Warning**:不要安装 `@topmindspace/tms-skills@^2`。npm 上残留的 **2.0.0–2.1.1** 是仓库重置前的过时线;当前线是 **0.1.x**(`latest` 亦指向 0.1.x)。维护者登录 npm 后可运行 `scripts/deprecate-npm-2x.sh` 标记弃用。
|
|
23
|
+
>
|
|
24
|
+
> Do **not** install `^2`. Versions 2.0.0–2.1.1 are obsolete after the repo reset; use **0.1.x**. Maintainers with npm auth should run `scripts/deprecate-npm-2x.sh`.
|
|
25
|
+
|
|
26
|
+
|
|
21
27
|
### npm(推荐)
|
|
22
28
|
|
|
23
29
|
```bash
|
|
@@ -74,7 +80,7 @@ tms-skills/
|
|
|
74
80
|
| tag `vX.Y.Z` | Release + zip | **自动 publish** |
|
|
75
81
|
|
|
76
82
|
- **push 不会更新 npm**;必须 bump 版本并打 tag。
|
|
77
|
-
- **Release 只保留最近 2 个**(CI
|
|
83
|
+
- **Release 只保留最近 2 个**(CI 只删旧 Release,**git tags 保留**);npm 可钉任意历史版本。
|
|
78
84
|
- 安装器与技能 **版本各自独立**;默认 patch/minor,major 仅破坏性变更。
|
|
79
85
|
|
|
80
86
|
详见 [docs/PUBLISHING.md](./docs/PUBLISHING.md)。
|
|
@@ -84,7 +90,7 @@ tms-skills/
|
|
|
84
90
|
| 工作流 | 触发 | 做什么 |
|
|
85
91
|
|--------|------|--------|
|
|
86
92
|
| `ci.yml` | push / PR | 打包门禁、审计、隐私扫描、CLI 冒烟 |
|
|
87
|
-
| `release.yml` | tag `v*` |
|
|
93
|
+
| `release.yml` | tag `v*` | 门禁 → zip → Release → npm publish(已存在则跳过)→ prune Release 留 2(tags 保留) |
|
|
88
94
|
|
|
89
95
|
```bash
|
|
90
96
|
npm run check && npm run audit && npm run privacy
|
|
@@ -95,7 +101,7 @@ npm run check && npm run audit && npm run privacy
|
|
|
95
101
|
1. 根目录建 `<skill-id>/`,`SKILL.md` 的 `name` 与目录一致。
|
|
96
102
|
2. 人类说明写 `README.md`;智能体入口保持 `SKILL.md`。
|
|
97
103
|
3. 发布前 `scripts/package_skill.py --check`。
|
|
98
|
-
4. 登记:根 README、`
|
|
104
|
+
4. 登记:根 README、`npm run sync:files`、`CHANGELOG.md`(CI 按发现的技能跑门禁,无需再硬编码)。
|
|
99
105
|
|
|
100
106
|
## 许可证
|
|
101
107
|
|
package/bin/tms-skills.js
CHANGED
|
@@ -1,160 +1,200 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* tms-skills — TopMindspace agent skills installer
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* npx @topmindspace/tms-skills
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
`
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* tms-skills — TopMindspace agent skills installer
|
|
4
|
+
*
|
|
5
|
+
* Recommended channel (when published): npm @topmindspace/tms-skills
|
|
6
|
+
* GitHub npx remains available for HEAD / offline clone.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* npx @topmindspace/tms-skills list
|
|
10
|
+
* npx @topmindspace/tms-skills install top-ppt-html
|
|
11
|
+
* npx @topmindspace/tms-skills install top-ppt-html --to ./skills-out
|
|
12
|
+
* npx @topmindspace/tms-skills install top-ppt-html --force
|
|
13
|
+
* npx github:topmindspace/tms-skills install top-ppt-html # follow repo HEAD
|
|
14
|
+
*/
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
|
|
20
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
21
|
+
// Skills live at repo root (one directory per skill with SKILL.md).
|
|
22
|
+
const INFRA_DIRS = new Set(['bin', 'docs', 'scripts', 'node_modules', 'dist', 'release-assets']);
|
|
23
|
+
const SKILL_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
24
|
+
|
|
25
|
+
function die(msg, code = 1) {
|
|
26
|
+
console.error(msg);
|
|
27
|
+
process.exit(code);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function skillDir(skillId) {
|
|
31
|
+
return path.join(ROOT, skillId);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function assertSkillId(skillId) {
|
|
35
|
+
if (!skillId || typeof skillId !== 'string') {
|
|
36
|
+
die('Missing skill id.\n\n' + usageText());
|
|
37
|
+
}
|
|
38
|
+
if (
|
|
39
|
+
skillId.includes('..') ||
|
|
40
|
+
skillId.includes('/') ||
|
|
41
|
+
skillId.includes('\\') ||
|
|
42
|
+
path.isAbsolute(skillId) ||
|
|
43
|
+
!SKILL_ID_RE.test(skillId)
|
|
44
|
+
) {
|
|
45
|
+
die(
|
|
46
|
+
`Invalid skill id: ${JSON.stringify(skillId)}\n` +
|
|
47
|
+
'Skill ids must match ^[a-z0-9]+(?:-[a-z0-9]+)*$ (no paths, dots, or slashes).'
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function listSkillIds() {
|
|
53
|
+
return fs
|
|
54
|
+
.readdirSync(ROOT, { withFileTypes: true })
|
|
55
|
+
.filter((d) => d.isDirectory() && !INFRA_DIRS.has(d.name) && !d.name.startsWith('.'))
|
|
56
|
+
.filter((d) => fs.existsSync(path.join(ROOT, d.name, 'SKILL.md')))
|
|
57
|
+
.map((d) => d.name)
|
|
58
|
+
.sort();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function readSkillMeta(skillId) {
|
|
62
|
+
const skillPath = skillDir(skillId);
|
|
63
|
+
const skillMd = path.join(skillPath, 'SKILL.md');
|
|
64
|
+
if (!fs.existsSync(skillMd)) return { id: skillId, description: '' };
|
|
65
|
+
const text = fs.readFileSync(skillMd, 'utf8');
|
|
66
|
+
const m = text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
67
|
+
if (!m) return { id: skillId, description: '' };
|
|
68
|
+
const desc = (m[1].match(/^description:\s*"(.*)"\s*$/m) || m[1].match(/^description:\s*(.+)\s*$/m) || [])[1] || '';
|
|
69
|
+
return { id: skillId, description: String(desc).slice(0, 120) };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function resolveDefaultTarget() {
|
|
73
|
+
const candidates = [
|
|
74
|
+
path.join(process.cwd(), '.agents', 'skills'),
|
|
75
|
+
path.join(process.cwd(), '.claude', 'skills'),
|
|
76
|
+
path.join(process.cwd(), '.mimocode', 'skills'),
|
|
77
|
+
path.join(process.env.HOME || process.env.USERPROFILE || '', '.claude', 'skills'),
|
|
78
|
+
path.join(process.env.HOME || process.env.USERPROFILE || '', '.agents', 'skills'),
|
|
79
|
+
];
|
|
80
|
+
for (const dir of candidates) {
|
|
81
|
+
if (dir && fs.existsSync(path.dirname(dir))) {
|
|
82
|
+
return dir;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return path.join(process.cwd(), '.agents', 'skills');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function copyDir(src, dest) {
|
|
89
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
90
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
91
|
+
const s = path.join(src, entry.name);
|
|
92
|
+
const d = path.join(dest, entry.name);
|
|
93
|
+
if (entry.isDirectory()) {
|
|
94
|
+
if (entry.name === 'node_modules' || entry.name === 'dist' || entry.name === '__pycache__') continue;
|
|
95
|
+
copyDir(s, d);
|
|
96
|
+
} else if (entry.isFile()) {
|
|
97
|
+
if (entry.name.endsWith('.pyc')) continue;
|
|
98
|
+
fs.copyFileSync(s, d);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function install(skillId, targetRoot, { force = false } = {}) {
|
|
104
|
+
assertSkillId(skillId);
|
|
105
|
+
const src = skillDir(skillId);
|
|
106
|
+
if (!fs.existsSync(path.join(src, 'SKILL.md'))) {
|
|
107
|
+
die(`Skill not found: ${skillId}\nAvailable: ${listSkillIds().join(', ') || '(none)'}`);
|
|
108
|
+
}
|
|
109
|
+
const dest = path.join(targetRoot, skillId);
|
|
110
|
+
fs.mkdirSync(targetRoot, { recursive: true });
|
|
111
|
+
if (fs.existsSync(dest)) {
|
|
112
|
+
if (!force) {
|
|
113
|
+
die(
|
|
114
|
+
`Destination already exists: ${dest}\n` +
|
|
115
|
+
'Refusing to overwrite. Pass --force (or -f) to replace.'
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
fs.rmSync(dest, { recursive: true, force: true });
|
|
119
|
+
}
|
|
120
|
+
copyDir(src, dest);
|
|
121
|
+
console.log(`Installed ${skillId}`);
|
|
122
|
+
console.log(` from ${src}`);
|
|
123
|
+
console.log(` to ${dest}`);
|
|
124
|
+
console.log('');
|
|
125
|
+
console.log('Optional (PPTX export only):');
|
|
126
|
+
console.log(` cd "${dest}" && npm install`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function usageText() {
|
|
130
|
+
return `tms-skills — install TopMindspace agent skills
|
|
131
|
+
|
|
132
|
+
Usage:
|
|
133
|
+
tms-skills list
|
|
134
|
+
tms-skills install <skill-id> [--to <dir>] [--force|-f]
|
|
135
|
+
tms-skills help
|
|
136
|
+
|
|
137
|
+
Examples (npm recommended when published):
|
|
138
|
+
npx @topmindspace/tms-skills list
|
|
139
|
+
npx @topmindspace/tms-skills install top-ppt-html
|
|
140
|
+
npx @topmindspace/tms-skills install top-ppt-html --to ./.agents/skills
|
|
141
|
+
npx @topmindspace/tms-skills install top-ppt-html --force
|
|
142
|
+
|
|
143
|
+
# Follow repo HEAD:
|
|
144
|
+
npx github:topmindspace/tms-skills install top-ppt-html
|
|
145
|
+
`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function usage() {
|
|
149
|
+
console.log(usageText());
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function main(argv) {
|
|
153
|
+
const args = argv.slice(2);
|
|
154
|
+
const cmd = args[0];
|
|
155
|
+
|
|
156
|
+
if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
|
|
157
|
+
usage();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (cmd === 'list' || cmd === 'ls') {
|
|
162
|
+
const ids = listSkillIds();
|
|
163
|
+
if (!ids.length) {
|
|
164
|
+
console.log('No skills found in package.');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
for (const id of ids) {
|
|
168
|
+
const meta = readSkillMeta(id);
|
|
169
|
+
console.log(`${id}`);
|
|
170
|
+
if (meta.description) console.log(` ${meta.description}…`);
|
|
171
|
+
}
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (cmd === 'install') {
|
|
176
|
+
const skillId = args[1];
|
|
177
|
+
if (!skillId || skillId.startsWith('-')) {
|
|
178
|
+
die('Missing skill id.\n\n' + usageText());
|
|
179
|
+
}
|
|
180
|
+
let to = null;
|
|
181
|
+
let force = false;
|
|
182
|
+
for (let i = 2; i < args.length; i++) {
|
|
183
|
+
if (args[i] === '--to' || args[i] === '-t') {
|
|
184
|
+
to = args[++i];
|
|
185
|
+
if (!to) die('Option --to requires a directory path.');
|
|
186
|
+
} else if (args[i] === '--force' || args[i] === '-f') {
|
|
187
|
+
force = true;
|
|
188
|
+
} else {
|
|
189
|
+
die(`Unknown option: ${args[i]}\n\n` + usageText());
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const targetRoot = to ? path.resolve(to) : resolveDefaultTarget();
|
|
193
|
+
install(skillId, targetRoot, { force });
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
die(`Unknown command: ${cmd}\n\n` + usageText());
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
main(process.argv);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topmindspace/tms-skills",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "TopMindspace 智能体技能 monorepo — 通过 GitHub npx 安装技能(top-ppt-html 等)。",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "TopMindspace 智能体技能 monorepo — 通过 npm / GitHub npx 安装技能(top-ppt-html 等)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "TopMindspace",
|
|
7
7
|
"repository": {
|
|
@@ -26,21 +26,24 @@
|
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"bin",
|
|
29
|
-
"top-ppt-html",
|
|
30
29
|
"README.md",
|
|
31
30
|
"LICENSE",
|
|
32
|
-
"CHANGELOG.md"
|
|
31
|
+
"CHANGELOG.md",
|
|
32
|
+
"top-ppt-html"
|
|
33
33
|
],
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": ">=18"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"list": "node bin/tms-skills.js list",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
39
|
+
"discover": "node scripts/discover_skills.js",
|
|
40
|
+
"sync:files": "node scripts/sync_npm_files.js",
|
|
41
|
+
"prepack": "node scripts/sync_npm_files.js",
|
|
42
|
+
"install:skills": "node -e \"const {discoverSkills}=require('./scripts/discover_skills'); const {spawnSync}=require('child_process'); for (const id of discoverSkills()) { const r=spawnSync(process.execPath,['bin/tms-skills.js','install',id],{stdio:'inherit'}); if(r.status) process.exit(r.status||1); }\"",
|
|
43
|
+
"check": "node scripts/run_skill_gates.js check",
|
|
44
|
+
"privacy": "python3 scripts/ci_privacy_scan.py",
|
|
45
|
+
"audit": "node scripts/run_skill_gates.js audit",
|
|
46
|
+
"package:skill": "node scripts/run_skill_gates.js package"
|
|
44
47
|
},
|
|
45
48
|
"publishConfig": {
|
|
46
49
|
"access": "public"
|