@topmindspace/tms-skills 0.1.6 → 0.1.8
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 +31 -0
- package/README.md +48 -69
- package/package.json +1 -1
- package/top-ppt-html/README.md +25 -6
- package/top-ppt-html/SKILL.md +6 -6
- package/top-ppt-html/agents/openai.yaml +1 -1
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +10 -5
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +10 -5
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +10 -5
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.html +4016 -0
- package/top-ppt-html/assets/examples/2026-09-26-topmind-tms-skills-showcase.model.json +315 -0
- package/top-ppt-html/assets/pptx-export.js +9 -4
- package/top-ppt-html/assets/showcase/showcase-cover.png +0 -0
- package/top-ppt-html/assets/showcase/showcase-gates.png +0 -0
- package/top-ppt-html/assets/showcase/showcase-modes.png +0 -0
- package/top-ppt-html/assets/showcase/showcase-split.png +0 -0
- package/top-ppt-html/assets/showcase/style-business-blue-cover.png +0 -0
- package/top-ppt-html/assets/showcase/style-graphite-cover.png +0 -0
- package/top-ppt-html/assets/showcase/style-mckinsey-cover.png +0 -0
- package/top-ppt-html/assets/templates/architecture.html +10 -5
- package/top-ppt-html/assets/templates/presentation.html +10 -5
- package/top-ppt-html/assets/templates/research.html +10 -5
- 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/package-lock.json +2 -2
- package/top-ppt-html/package.json +1 -1
- package/top-ppt-html/references/playbook.md +1 -1
- package/top-ppt-html/scripts/build_examples.py +4 -3
- package/top-ppt-html/scripts/build_pptx.js +12 -5
- package/top-ppt-html/scripts/package_skill.py +4 -3
- package/top-ppt-html/scripts/smoke_pptx.sh +1 -0
- package/top-ppt-html/scripts/test_feedback_gates.py +96 -0
- package/top-ppt-html/scripts/validate_pptx.py +60 -37
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mode": "presentation",
|
|
3
|
+
"style": "business-blue",
|
|
4
|
+
"theme": "light",
|
|
5
|
+
"title": "TopMind × tms-skills",
|
|
6
|
+
"subtitle": "让 idea 飞 · 把好想法做成可上台的演示文稿",
|
|
7
|
+
"meta": "产品介绍 · 2026-09-26",
|
|
8
|
+
"agenda": [
|
|
9
|
+
[
|
|
10
|
+
"01",
|
|
11
|
+
"TopMind 定位",
|
|
12
|
+
"知识工作空间"
|
|
13
|
+
],
|
|
14
|
+
[
|
|
15
|
+
"02",
|
|
16
|
+
"tms-skills 概览",
|
|
17
|
+
"可安装技能 monorepo"
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
"03",
|
|
21
|
+
"top-ppt-html 特色",
|
|
22
|
+
"HTML + 保真 PPTX"
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
"04",
|
|
26
|
+
"三模式契约",
|
|
27
|
+
"演示 · 研究 · 架构"
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
"05",
|
|
31
|
+
"风格与主题",
|
|
32
|
+
"九风格 × 亮暗"
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
"06",
|
|
36
|
+
"质量门禁",
|
|
37
|
+
"strict 0/0 交付"
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
"07",
|
|
41
|
+
"Fast Mode",
|
|
42
|
+
"少问一句 · 工艺不降"
|
|
43
|
+
]
|
|
44
|
+
],
|
|
45
|
+
"sections": [
|
|
46
|
+
{
|
|
47
|
+
"type": "points",
|
|
48
|
+
"layoutPreset": "P4",
|
|
49
|
+
"eyebrow": "01 · TopMind",
|
|
50
|
+
"title": "TopMind:让 idea 飞的知识工作空间",
|
|
51
|
+
"points": [
|
|
52
|
+
[
|
|
53
|
+
"工作空间,不是工具箱",
|
|
54
|
+
"把想法、材料与产出收拢在同一语境,减少搬运与失真"
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
"知识工艺,克制表达",
|
|
58
|
+
"强调结构、证据与可读性——让好想法被认真看见"
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"面向正式场合",
|
|
62
|
+
"演讲、汇报、路演:材料要上台,不只是堆在文档里"
|
|
63
|
+
]
|
|
64
|
+
],
|
|
65
|
+
"soWhat": "TopMind 把有想法推进到可上台——工艺在结构,不在堆砌。"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "cards",
|
|
69
|
+
"layoutPreset": "P5",
|
|
70
|
+
"eyebrow": "02 · tms-skills",
|
|
71
|
+
"title": "tms-skills:整仓可安装的智能体技能",
|
|
72
|
+
"columns": 3,
|
|
73
|
+
"cards": [
|
|
74
|
+
{
|
|
75
|
+
"title": "Monorepo",
|
|
76
|
+
"points": [
|
|
77
|
+
[
|
|
78
|
+
"一仓多技能",
|
|
79
|
+
"根目录技能包 + 统一安装器"
|
|
80
|
+
],
|
|
81
|
+
[
|
|
82
|
+
"同 tag 发版",
|
|
83
|
+
"安装器与技能整仓对齐"
|
|
84
|
+
]
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"title": "双通道安装",
|
|
89
|
+
"points": [
|
|
90
|
+
[
|
|
91
|
+
"npm 钉版本",
|
|
92
|
+
"npx @topmindspace/tms-skills"
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
"GitHub 跟 HEAD",
|
|
96
|
+
"日常可 clone / 直装"
|
|
97
|
+
]
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"title": "当前主技能",
|
|
102
|
+
"points": [
|
|
103
|
+
[
|
|
104
|
+
"top-ppt-html",
|
|
105
|
+
"正式场合演示文稿"
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"HTML + PPTX",
|
|
109
|
+
"同源模型 · 双交付"
|
|
110
|
+
]
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"footnote": "包名 @topmindspace/tms-skills · 当前线 0.1.x(latest)"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "split",
|
|
118
|
+
"layoutPreset": "P1",
|
|
119
|
+
"eyebrow": "03 · top-ppt-html",
|
|
120
|
+
"title": "一屏一主张:可翻页 HTML,保真可编辑 PPTX",
|
|
121
|
+
"left": {
|
|
122
|
+
"points": [
|
|
123
|
+
[
|
|
124
|
+
"模型单写",
|
|
125
|
+
"只填 REPORT_MODEL,禁手改 HTML 正文"
|
|
126
|
+
],
|
|
127
|
+
[
|
|
128
|
+
"三模式 × 九风格",
|
|
129
|
+
"演示 / 研究 / 架构各有契约"
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
"门禁闭环",
|
|
133
|
+
"validate --strict 0/0 才交付"
|
|
134
|
+
]
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
"right": {
|
|
138
|
+
"type": "bar",
|
|
139
|
+
"cap": "交付关注点(示意权重)",
|
|
140
|
+
"labels": [
|
|
141
|
+
"版式",
|
|
142
|
+
"排版",
|
|
143
|
+
"色彩",
|
|
144
|
+
"内容"
|
|
145
|
+
],
|
|
146
|
+
"values": [
|
|
147
|
+
32,
|
|
148
|
+
28,
|
|
149
|
+
18,
|
|
150
|
+
22
|
|
151
|
+
],
|
|
152
|
+
"unit": "",
|
|
153
|
+
"max": 40,
|
|
154
|
+
"dataTable": "notes"
|
|
155
|
+
},
|
|
156
|
+
"soWhat": "工艺是版式、排版、色彩与内容组织——图表图标克制配文。"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"type": "cards",
|
|
160
|
+
"layoutPreset": "P5",
|
|
161
|
+
"eyebrow": "04 · 三模式",
|
|
162
|
+
"title": "模式先定后写:A 演示 · B 研究 · C 架构",
|
|
163
|
+
"columns": 3,
|
|
164
|
+
"cards": [
|
|
165
|
+
{
|
|
166
|
+
"title": "A · 演示",
|
|
167
|
+
"points": [
|
|
168
|
+
[
|
|
169
|
+
"每屏一主张",
|
|
170
|
+
"标题即行动句,非话题标签"
|
|
171
|
+
],
|
|
172
|
+
[
|
|
173
|
+
"大气留白",
|
|
174
|
+
"证据充分但不堆咨询 dump"
|
|
175
|
+
]
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"title": "B · 研究",
|
|
180
|
+
"points": [
|
|
181
|
+
[
|
|
182
|
+
"咨询密排",
|
|
183
|
+
"Exhibit · 来源 · so-what"
|
|
184
|
+
],
|
|
185
|
+
[
|
|
186
|
+
"结论可核对",
|
|
187
|
+
"数字与口径双向对齐"
|
|
188
|
+
]
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"title": "C · 架构",
|
|
193
|
+
"points": [
|
|
194
|
+
[
|
|
195
|
+
"图为王",
|
|
196
|
+
"拓扑 / 泳道 / 分层"
|
|
197
|
+
],
|
|
198
|
+
[
|
|
199
|
+
"少字多结构",
|
|
200
|
+
"一图说清关系"
|
|
201
|
+
]
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"footnote": "意图线索:路演/汇报/演讲 → A;调研/对标 → B;拓扑/方案图 → C"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"type": "metrics",
|
|
209
|
+
"layoutPreset": "P2",
|
|
210
|
+
"eyebrow": "05 · 风格主题",
|
|
211
|
+
"title": "九风格开场即可见,亮暗主题一键贯穿",
|
|
212
|
+
"metrics": [
|
|
213
|
+
[
|
|
214
|
+
"9",
|
|
215
|
+
"风格套装(商务蓝·麦肯锡·石墨等)"
|
|
216
|
+
],
|
|
217
|
+
[
|
|
218
|
+
"2",
|
|
219
|
+
"亮暗主题(浅色外发 / 深色大屏)"
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
"1",
|
|
223
|
+
"交互画廊 style-gallery"
|
|
224
|
+
],
|
|
225
|
+
[
|
|
226
|
+
"3",
|
|
227
|
+
"主题参考图(演示·研究·架构)"
|
|
228
|
+
]
|
|
229
|
+
],
|
|
230
|
+
"soWhat": "Gate 0 先给参考图;标准模式跳过即不合格。"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"type": "comparison",
|
|
234
|
+
"layoutPreset": "P4",
|
|
235
|
+
"eyebrow": "06 · 质量门禁",
|
|
236
|
+
"title": "散装出稿止步,strict 0/0 才算交付",
|
|
237
|
+
"left": {
|
|
238
|
+
"title": "散装路径 · 风险",
|
|
239
|
+
"points": [
|
|
240
|
+
[
|
|
241
|
+
"手改 HTML",
|
|
242
|
+
"模型与正文双写,一改就漂"
|
|
243
|
+
],
|
|
244
|
+
[
|
|
245
|
+
"无严格校验",
|
|
246
|
+
"截断、同型图、半空卡易漏"
|
|
247
|
+
],
|
|
248
|
+
[
|
|
249
|
+
"口头交付",
|
|
250
|
+
"缺七要素,验收靠感觉"
|
|
251
|
+
]
|
|
252
|
+
]
|
|
253
|
+
},
|
|
254
|
+
"right": {
|
|
255
|
+
"title": "门禁路径 · 目标",
|
|
256
|
+
"points": [
|
|
257
|
+
[
|
|
258
|
+
"模型单写",
|
|
259
|
+
"render 回填,禁手改正文"
|
|
260
|
+
],
|
|
261
|
+
[
|
|
262
|
+
"HTML + PPTX",
|
|
263
|
+
"validate --strict 双侧 0/0"
|
|
264
|
+
],
|
|
265
|
+
[
|
|
266
|
+
"七要素说明",
|
|
267
|
+
"quality_gate --deliver"
|
|
268
|
+
]
|
|
269
|
+
]
|
|
270
|
+
},
|
|
271
|
+
"verdict": "反截断、图表多样性、runtime SHA——门禁是交付的一部分。"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"type": "timeline",
|
|
275
|
+
"layoutPreset": "P6",
|
|
276
|
+
"eyebrow": "07 · Fast Mode",
|
|
277
|
+
"title": "Fast Mode:跳过问询,不跳过工艺",
|
|
278
|
+
"phases": [
|
|
279
|
+
[
|
|
280
|
+
"触发",
|
|
281
|
+
"显式 opt-in",
|
|
282
|
+
"快速模式 / fast / 一键出稿 / 少问一句"
|
|
283
|
+
],
|
|
284
|
+
[
|
|
285
|
+
"推断",
|
|
286
|
+
"默认参数",
|
|
287
|
+
"路演线索→A·business-blue;未点明→B·mckinsey"
|
|
288
|
+
],
|
|
289
|
+
[
|
|
290
|
+
"仍须",
|
|
291
|
+
"质量闭环",
|
|
292
|
+
"最小大纲 → 模型单写 → strict 0/0 → 交付说明"
|
|
293
|
+
]
|
|
294
|
+
],
|
|
295
|
+
"soWhat": "Fast 豁免问询,但反截断与 Mode A craft 一律不降。"
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
"closing": {
|
|
299
|
+
"title": "让好想法被看见",
|
|
300
|
+
"points": [
|
|
301
|
+
[
|
|
302
|
+
"装技能",
|
|
303
|
+
"npx @topmindspace/tms-skills install top-ppt-html"
|
|
304
|
+
],
|
|
305
|
+
[
|
|
306
|
+
"看样张",
|
|
307
|
+
"assets/examples · style-gallery.html"
|
|
308
|
+
],
|
|
309
|
+
[
|
|
310
|
+
"上台交付",
|
|
311
|
+
"HTML 可翻页 · PPTX 可编辑 · strict 0/0"
|
|
312
|
+
]
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -252,6 +252,7 @@ function dataColors(style, theme) {
|
|
|
252
252
|
var LAY = PT.layout || {};
|
|
253
253
|
var CONTENT_TOP = (LAY.contentTop != null) ? LAY.contentTop : 2.5;
|
|
254
254
|
var CONTENT_BOTTOM = (LAY.contentBottom != null) ? LAY.contentBottom : 6.9;
|
|
255
|
+
var CONTENT_BOTTOM_NOTE = (LAY.contentBottomWithNote != null) ? LAY.contentBottomWithNote : 6.4;
|
|
255
256
|
|
|
256
257
|
/* ── 自适应排版工具(与 build_pptx.js 同算法,保证两通道字号/换行一致) ── */
|
|
257
258
|
function estLines(text, widthIn, fontPt) {
|
|
@@ -326,9 +327,12 @@ function fitRowH(avail, n, pref, floor) {
|
|
|
326
327
|
return Math.max(lo, Math.min(pref, avail / Math.max(1, n)));
|
|
327
328
|
}
|
|
328
329
|
function chartBottom(hasSoWhat, hasFootnote) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
330
|
+
/* D8: tightest of soWhat/footnote/contentBottomWithNote — no short-circuit */
|
|
331
|
+
var bot = CONTENT_BOTTOM;
|
|
332
|
+
if (hasSoWhat) bot = Math.min(bot, PT.exhibit.soWhatY - 0.12);
|
|
333
|
+
if (hasFootnote) bot = Math.min(bot, PT.exhibit.footnoteY - 0.12);
|
|
334
|
+
if (hasSoWhat || hasFootnote) bot = Math.min(bot, CONTENT_BOTTOM_NOTE);
|
|
335
|
+
return bot;
|
|
332
336
|
}
|
|
333
337
|
|
|
334
338
|
/* ── XML 工具 ── */
|
|
@@ -1216,7 +1220,7 @@ function slidesOf(model, S) {
|
|
|
1216
1220
|
head(ag, 'AGENDA', '报告大纲');
|
|
1217
1221
|
var colN = items.length > 8 ? 2 : 1;
|
|
1218
1222
|
var perCol = Math.ceil(items.length / colN) || 1;
|
|
1219
|
-
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP) / perCol);
|
|
1223
|
+
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP - 0.25) / Math.max(1, perCol));
|
|
1220
1224
|
var numSz = rowH >= 0.85 ? 30 : (rowH >= 0.65 ? 22 : 18);
|
|
1221
1225
|
var tSz = rowH >= 0.85 ? 16 : 14, dSz = rowH >= 0.85 ? 12 : 11;
|
|
1222
1226
|
items.forEach(function (it, i) {
|
|
@@ -1253,6 +1257,7 @@ function slidesOf(model, S) {
|
|
|
1253
1257
|
flagY = CONTENT_BOTTOM - flagH;
|
|
1254
1258
|
if (sec.footnote) flagY = Math.min(flagY, PT.exhibit.footnoteY - flagH - 0.06);
|
|
1255
1259
|
if (sec.soWhat) flagY = Math.min(flagY, PT.exhibit.soWhatY - flagH - 0.06);
|
|
1260
|
+
if (sec.footnote || sec.soWhat) flagY = Math.min(flagY, CONTENT_BOTTOM_NOTE - flagH);
|
|
1256
1261
|
bodyBottom = Math.min(bodyBottom, flagY - (_F.gap || 0.12));
|
|
1257
1262
|
}
|
|
1258
1263
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1778,7 +1778,7 @@ window.REPORT_MODEL = {
|
|
|
1778
1778
|
|
|
1779
1779
|
/* __TOPPPT_RUNTIME_START__ */
|
|
1780
1780
|
/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
|
|
1781
|
-
/* __TOPPPT_RUNTIME_SHA__:
|
|
1781
|
+
/* __TOPPPT_RUNTIME_SHA__:77ca318e7a510e01 */
|
|
1782
1782
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
1783
1783
|
* TopPPT HTML· 浏览器端 PPTX 预览运行时
|
|
1784
1784
|
* 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
|
|
@@ -2033,6 +2033,7 @@ function dataColors(style, theme) {
|
|
|
2033
2033
|
var LAY = PT.layout || {};
|
|
2034
2034
|
var CONTENT_TOP = (LAY.contentTop != null) ? LAY.contentTop : 2.5;
|
|
2035
2035
|
var CONTENT_BOTTOM = (LAY.contentBottom != null) ? LAY.contentBottom : 6.9;
|
|
2036
|
+
var CONTENT_BOTTOM_NOTE = (LAY.contentBottomWithNote != null) ? LAY.contentBottomWithNote : 6.4;
|
|
2036
2037
|
|
|
2037
2038
|
/* ── 自适应排版工具(与 build_pptx.js 同算法,保证两通道字号/换行一致) ── */
|
|
2038
2039
|
function estLines(text, widthIn, fontPt) {
|
|
@@ -2107,9 +2108,12 @@ function fitRowH(avail, n, pref, floor) {
|
|
|
2107
2108
|
return Math.max(lo, Math.min(pref, avail / Math.max(1, n)));
|
|
2108
2109
|
}
|
|
2109
2110
|
function chartBottom(hasSoWhat, hasFootnote) {
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2111
|
+
/* D8: tightest of soWhat/footnote/contentBottomWithNote — no short-circuit */
|
|
2112
|
+
var bot = CONTENT_BOTTOM;
|
|
2113
|
+
if (hasSoWhat) bot = Math.min(bot, PT.exhibit.soWhatY - 0.12);
|
|
2114
|
+
if (hasFootnote) bot = Math.min(bot, PT.exhibit.footnoteY - 0.12);
|
|
2115
|
+
if (hasSoWhat || hasFootnote) bot = Math.min(bot, CONTENT_BOTTOM_NOTE);
|
|
2116
|
+
return bot;
|
|
2113
2117
|
}
|
|
2114
2118
|
|
|
2115
2119
|
/* ── XML 工具 ── */
|
|
@@ -2997,7 +3001,7 @@ function slidesOf(model, S) {
|
|
|
2997
3001
|
head(ag, 'AGENDA', '报告大纲');
|
|
2998
3002
|
var colN = items.length > 8 ? 2 : 1;
|
|
2999
3003
|
var perCol = Math.ceil(items.length / colN) || 1;
|
|
3000
|
-
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP) / perCol);
|
|
3004
|
+
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP - 0.25) / Math.max(1, perCol));
|
|
3001
3005
|
var numSz = rowH >= 0.85 ? 30 : (rowH >= 0.65 ? 22 : 18);
|
|
3002
3006
|
var tSz = rowH >= 0.85 ? 16 : 14, dSz = rowH >= 0.85 ? 12 : 11;
|
|
3003
3007
|
items.forEach(function (it, i) {
|
|
@@ -3034,6 +3038,7 @@ function slidesOf(model, S) {
|
|
|
3034
3038
|
flagY = CONTENT_BOTTOM - flagH;
|
|
3035
3039
|
if (sec.footnote) flagY = Math.min(flagY, PT.exhibit.footnoteY - flagH - 0.06);
|
|
3036
3040
|
if (sec.soWhat) flagY = Math.min(flagY, PT.exhibit.soWhatY - flagH - 0.06);
|
|
3041
|
+
if (sec.footnote || sec.soWhat) flagY = Math.min(flagY, CONTENT_BOTTOM_NOTE - flagH);
|
|
3037
3042
|
bodyBottom = Math.min(bodyBottom, flagY - (_F.gap || 0.12));
|
|
3038
3043
|
}
|
|
3039
3044
|
|
|
@@ -1788,7 +1788,7 @@ window.REPORT_MODEL = {
|
|
|
1788
1788
|
|
|
1789
1789
|
/* __TOPPPT_RUNTIME_START__ */
|
|
1790
1790
|
/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
|
|
1791
|
-
/* __TOPPPT_RUNTIME_SHA__:
|
|
1791
|
+
/* __TOPPPT_RUNTIME_SHA__:77ca318e7a510e01 */
|
|
1792
1792
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
1793
1793
|
* TopPPT HTML· 浏览器端 PPTX 预览运行时
|
|
1794
1794
|
* 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
|
|
@@ -2043,6 +2043,7 @@ function dataColors(style, theme) {
|
|
|
2043
2043
|
var LAY = PT.layout || {};
|
|
2044
2044
|
var CONTENT_TOP = (LAY.contentTop != null) ? LAY.contentTop : 2.5;
|
|
2045
2045
|
var CONTENT_BOTTOM = (LAY.contentBottom != null) ? LAY.contentBottom : 6.9;
|
|
2046
|
+
var CONTENT_BOTTOM_NOTE = (LAY.contentBottomWithNote != null) ? LAY.contentBottomWithNote : 6.4;
|
|
2046
2047
|
|
|
2047
2048
|
/* ── 自适应排版工具(与 build_pptx.js 同算法,保证两通道字号/换行一致) ── */
|
|
2048
2049
|
function estLines(text, widthIn, fontPt) {
|
|
@@ -2117,9 +2118,12 @@ function fitRowH(avail, n, pref, floor) {
|
|
|
2117
2118
|
return Math.max(lo, Math.min(pref, avail / Math.max(1, n)));
|
|
2118
2119
|
}
|
|
2119
2120
|
function chartBottom(hasSoWhat, hasFootnote) {
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2121
|
+
/* D8: tightest of soWhat/footnote/contentBottomWithNote — no short-circuit */
|
|
2122
|
+
var bot = CONTENT_BOTTOM;
|
|
2123
|
+
if (hasSoWhat) bot = Math.min(bot, PT.exhibit.soWhatY - 0.12);
|
|
2124
|
+
if (hasFootnote) bot = Math.min(bot, PT.exhibit.footnoteY - 0.12);
|
|
2125
|
+
if (hasSoWhat || hasFootnote) bot = Math.min(bot, CONTENT_BOTTOM_NOTE);
|
|
2126
|
+
return bot;
|
|
2123
2127
|
}
|
|
2124
2128
|
|
|
2125
2129
|
/* ── XML 工具 ── */
|
|
@@ -3007,7 +3011,7 @@ function slidesOf(model, S) {
|
|
|
3007
3011
|
head(ag, 'AGENDA', '报告大纲');
|
|
3008
3012
|
var colN = items.length > 8 ? 2 : 1;
|
|
3009
3013
|
var perCol = Math.ceil(items.length / colN) || 1;
|
|
3010
|
-
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP) / perCol);
|
|
3014
|
+
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP - 0.25) / Math.max(1, perCol));
|
|
3011
3015
|
var numSz = rowH >= 0.85 ? 30 : (rowH >= 0.65 ? 22 : 18);
|
|
3012
3016
|
var tSz = rowH >= 0.85 ? 16 : 14, dSz = rowH >= 0.85 ? 12 : 11;
|
|
3013
3017
|
items.forEach(function (it, i) {
|
|
@@ -3044,6 +3048,7 @@ function slidesOf(model, S) {
|
|
|
3044
3048
|
flagY = CONTENT_BOTTOM - flagH;
|
|
3045
3049
|
if (sec.footnote) flagY = Math.min(flagY, PT.exhibit.footnoteY - flagH - 0.06);
|
|
3046
3050
|
if (sec.soWhat) flagY = Math.min(flagY, PT.exhibit.soWhatY - flagH - 0.06);
|
|
3051
|
+
if (sec.footnote || sec.soWhat) flagY = Math.min(flagY, CONTENT_BOTTOM_NOTE - flagH);
|
|
3047
3052
|
bodyBottom = Math.min(bodyBottom, flagY - (_F.gap || 0.12));
|
|
3048
3053
|
}
|
|
3049
3054
|
|
|
@@ -2067,7 +2067,7 @@ window.REPORT_MODEL = {
|
|
|
2067
2067
|
|
|
2068
2068
|
/* __TOPPPT_RUNTIME_START__ */
|
|
2069
2069
|
/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
|
|
2070
|
-
/* __TOPPPT_RUNTIME_SHA__:
|
|
2070
|
+
/* __TOPPPT_RUNTIME_SHA__:77ca318e7a510e01 */
|
|
2071
2071
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2072
2072
|
* TopPPT HTML· 浏览器端 PPTX 预览运行时
|
|
2073
2073
|
* 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
|
|
@@ -2322,6 +2322,7 @@ function dataColors(style, theme) {
|
|
|
2322
2322
|
var LAY = PT.layout || {};
|
|
2323
2323
|
var CONTENT_TOP = (LAY.contentTop != null) ? LAY.contentTop : 2.5;
|
|
2324
2324
|
var CONTENT_BOTTOM = (LAY.contentBottom != null) ? LAY.contentBottom : 6.9;
|
|
2325
|
+
var CONTENT_BOTTOM_NOTE = (LAY.contentBottomWithNote != null) ? LAY.contentBottomWithNote : 6.4;
|
|
2325
2326
|
|
|
2326
2327
|
/* ── 自适应排版工具(与 build_pptx.js 同算法,保证两通道字号/换行一致) ── */
|
|
2327
2328
|
function estLines(text, widthIn, fontPt) {
|
|
@@ -2396,9 +2397,12 @@ function fitRowH(avail, n, pref, floor) {
|
|
|
2396
2397
|
return Math.max(lo, Math.min(pref, avail / Math.max(1, n)));
|
|
2397
2398
|
}
|
|
2398
2399
|
function chartBottom(hasSoWhat, hasFootnote) {
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2400
|
+
/* D8: tightest of soWhat/footnote/contentBottomWithNote — no short-circuit */
|
|
2401
|
+
var bot = CONTENT_BOTTOM;
|
|
2402
|
+
if (hasSoWhat) bot = Math.min(bot, PT.exhibit.soWhatY - 0.12);
|
|
2403
|
+
if (hasFootnote) bot = Math.min(bot, PT.exhibit.footnoteY - 0.12);
|
|
2404
|
+
if (hasSoWhat || hasFootnote) bot = Math.min(bot, CONTENT_BOTTOM_NOTE);
|
|
2405
|
+
return bot;
|
|
2402
2406
|
}
|
|
2403
2407
|
|
|
2404
2408
|
/* ── XML 工具 ── */
|
|
@@ -3286,7 +3290,7 @@ function slidesOf(model, S) {
|
|
|
3286
3290
|
head(ag, 'AGENDA', '报告大纲');
|
|
3287
3291
|
var colN = items.length > 8 ? 2 : 1;
|
|
3288
3292
|
var perCol = Math.ceil(items.length / colN) || 1;
|
|
3289
|
-
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP) / perCol);
|
|
3293
|
+
var rowH = Math.min(1.05, (CONTENT_BOTTOM - CONTENT_TOP - 0.25) / Math.max(1, perCol));
|
|
3290
3294
|
var numSz = rowH >= 0.85 ? 30 : (rowH >= 0.65 ? 22 : 18);
|
|
3291
3295
|
var tSz = rowH >= 0.85 ? 16 : 14, dSz = rowH >= 0.85 ? 12 : 11;
|
|
3292
3296
|
items.forEach(function (it, i) {
|
|
@@ -3323,6 +3327,7 @@ function slidesOf(model, S) {
|
|
|
3323
3327
|
flagY = CONTENT_BOTTOM - flagH;
|
|
3324
3328
|
if (sec.footnote) flagY = Math.min(flagY, PT.exhibit.footnoteY - flagH - 0.06);
|
|
3325
3329
|
if (sec.soWhat) flagY = Math.min(flagY, PT.exhibit.soWhatY - flagH - 0.06);
|
|
3330
|
+
if (sec.footnote || sec.soWhat) flagY = Math.min(flagY, CONTENT_BOTTOM_NOTE - flagH);
|
|
3326
3331
|
bodyBottom = Math.min(bodyBottom, flagY - (_F.gap || 0.12));
|
|
3327
3332
|
}
|
|
3328
3333
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "top-ppt-html",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "top-ppt-html",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.8",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"pptxgenjs": "^4.0.0"
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
Gate 0 参考图 → 六项问询(1 轮)→ 最小大纲(outline-design「轻量最小集」)→ 1 张规划卡 → scaffold_report.py
|
|
47
47
|
→ **只填 REPORT_MODEL** → render_from_model.py --inplace → validate_report.py --strict → 交付
|
|
48
48
|
```
|
|
49
|
-
(Fast Mode 跳过 Gate 0
|
|
49
|
+
(Fast Mode 跳过 Gate 0/六项,仍须最小大纲+strict;默认 **HTML-only**,PPTX 显式 opt-in 走 B 通道;路演/汇报/演讲线索→Mode A;**禁止**手改 HTML 正文与模型双写。)
|
|
50
50
|
|
|
51
51
|
**完整路径**(任一命中)——研究 ≥20 页 / 演示 ≥12 页 / 材料量大且杂 / 含未敲定关键判断 / 用户要看框架。
|
|
52
52
|
```
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
"""TopPPT HTML ·
|
|
3
|
+
"""TopPPT HTML · 黄金样张维护
|
|
4
4
|
|
|
5
|
-
assets/examples/
|
|
5
|
+
assets/examples/ 至少保留 3 份黄金样张(每模式 1):
|
|
6
6
|
presentation-business-blue · research-mckinsey · architecture-graphite-dark
|
|
7
|
+
另可含产品 showcase(如 2026-09-26-topmind-tms-skills-showcase),不替代黄金样张。
|
|
7
8
|
|
|
8
9
|
完整 9 风格染色矩阵旧实现:docs/archive/build_examples.py.full
|
|
9
|
-
|
|
10
|
+
其余历史示例:docs/archive/examples/
|
|
10
11
|
"""
|
|
11
12
|
from __future__ import annotations
|
|
12
13
|
|
|
@@ -573,9 +573,13 @@ function imageLayoutShapes(s, layout, img, items, points, isPh, fit, y0, y1) {
|
|
|
573
573
|
}
|
|
574
574
|
/* 数据图表上下文(供备注与自适应使用) */
|
|
575
575
|
function chartBottom(hasSoWhat, hasFootnote) {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
576
|
+
/* 取最紧下界:so-what / footnote / contentBottomWithNote 并存时不得短路(D8)。
|
|
577
|
+
* 与 ~1630 flagY 的 Math.min 让位同口径;withNote 时对齐 regionOf 的 contentBottomWithNote。 */
|
|
578
|
+
let bot = CONTENT_BOTTOM;
|
|
579
|
+
if (hasSoWhat) bot = Math.min(bot, PT.exhibit.soWhatY - 0.12);
|
|
580
|
+
if (hasFootnote) bot = Math.min(bot, PT.exhibit.footnoteY - 0.12);
|
|
581
|
+
if (hasSoWhat || hasFootnote) bot = Math.min(bot, CONTENT_BOTTOM_NOTE);
|
|
582
|
+
return bot;
|
|
579
583
|
}
|
|
580
584
|
|
|
581
585
|
/* ═══ 原生数据图表(pptxgenjs addChart → 真 chart part + 内嵌 Excel 工作簿)═══
|
|
@@ -1581,8 +1585,9 @@ function addTable(s, tbl, x, y, w, availH, opts) {
|
|
|
1581
1585
|
const items = CONTENT.agenda;
|
|
1582
1586
|
const colN = items.length > 8 ? 2 : 1;
|
|
1583
1587
|
const perCol = Math.ceil(items.length / colN);
|
|
1584
|
-
|
|
1585
|
-
const
|
|
1588
|
+
/* 预留 0.25in,避免末行底边落入 severe-overlap 安全网(无注释页亦勿压进 withNote 带过深) */
|
|
1589
|
+
const availH = CONTENT_BOTTOM - CONTENT_TOP - 0.25;
|
|
1590
|
+
const rowH = Math.min(1.05, availH / Math.max(1, perCol));
|
|
1586
1591
|
const numSize = rowH >= 0.85 ? sz(30) : (rowH >= 0.65 ? sz(22) : sz(18));
|
|
1587
1592
|
const tSize = rowH >= 0.85 ? sz(16) : sz(14);
|
|
1588
1593
|
const dSize = rowH >= 0.85 ? sz(12) : sz(11);
|
|
@@ -1630,6 +1635,8 @@ CONTENT.sections.forEach((sec) => {
|
|
|
1630
1635
|
flagY = CONTENT_BOTTOM - flagH;
|
|
1631
1636
|
if (sec.footnote) flagY = Math.min(flagY, PT.exhibit.footnoteY - flagH - 0.06);
|
|
1632
1637
|
if (sec.soWhat) flagY = Math.min(flagY, PT.exhibit.soWhatY - flagH - 0.06);
|
|
1638
|
+
/* withNote 时 flag 底不得越过 contentBottomWithNote(与 chartBottom / regionOf 同口径) */
|
|
1639
|
+
if (sec.footnote || sec.soWhat) flagY = Math.min(flagY, CONTENT_BOTTOM_NOTE - flagH);
|
|
1633
1640
|
bodyBottom = Math.min(bodyBottom, flagY - (_F.gap || 0.12));
|
|
1634
1641
|
}
|
|
1635
1642
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
README.md 人类视角的简介 / 安装 / 开发 / 打包
|
|
18
18
|
package.json Node 依赖声明(pptxgenjs)与常用命令
|
|
19
19
|
assets/templates/ 三份模式模板 + engine.css / ui.js(公共片段注入源)
|
|
20
|
-
assets/examples/ 3
|
|
20
|
+
assets/examples/ ≥3 黄金样张(每模式 1)+ 可选产品 showcase HTML/model
|
|
21
21
|
assets/pptx-export.js PPTX 预览运行时(注入源)
|
|
22
22
|
assets/style-gallery.html 风格 × 模式 × 亮暗主题交互画廊
|
|
23
23
|
assets/theme-overview*.png 3 张主题参考图(整体 + research + architecture;演示态与整体图相同)
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
────────────────────────────────────────────────────────────────────────
|
|
43
43
|
· SKILL.md frontmatter 含 name / description;name 与分发包目录名一致;
|
|
44
44
|
description 为单行双引号字符串且 ≤ 1024 字符(平台截断阈值)
|
|
45
|
-
· references(含 layout-grammar)、3 份模式模板 + engine.css / ui.js
|
|
45
|
+
· references(含 layout-grammar)、3 份模式模板 + engine.css / ui.js、≥3 组样张、3 张参考图齐全
|
|
46
46
|
· 关键脚本齐全(单源注入 / 审计 / 示例重建 / 回归 / 双校验器 / 精导 / 打包)
|
|
47
47
|
"""
|
|
48
48
|
import fnmatch
|
|
@@ -84,6 +84,7 @@ INCLUDE = [
|
|
|
84
84
|
'assets/theme-overview-architecture.png',
|
|
85
85
|
'assets/templates/*',
|
|
86
86
|
'assets/examples/*',
|
|
87
|
+
'assets/showcase/*',
|
|
87
88
|
'references/*',
|
|
88
89
|
'scripts/*',
|
|
89
90
|
'evals/*',
|
|
@@ -155,7 +156,7 @@ REQUIRED = [
|
|
|
155
156
|
|
|
156
157
|
# 必须达到最小数量的集合(名称含日期,故按数量校验)
|
|
157
158
|
MIN_COUNTS = {
|
|
158
|
-
'assets/examples/*.html': 3, #
|
|
159
|
+
'assets/examples/*.html': 3, # ≥3:每模式黄金样张;可另含 showcase
|
|
159
160
|
'assets/examples/*.model.json': 3,
|
|
160
161
|
'references/*.md': 25, # + page-type-matrix + chart-decision-tree;≥25 防误删
|
|
161
162
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# TopPPT HTML · PPTX 轻量冒烟(Batch 2)
|
|
3
3
|
# extract_model → build_pptx → validate_pptx --strict --model=
|
|
4
4
|
# 用法: bash scripts/smoke_pptx.sh [example.html]
|
|
5
|
+
# CI(ci_skill_gates --with-pptx)必跑 business-blue + research-mckinsey(D13;后者覆盖 soWhat+footnote / D8)
|
|
5
6
|
# 失败时打印短摘要(错误码/页码/消息),完整 JSON 落盘到 TMPDIR。
|
|
6
7
|
set -euo pipefail
|
|
7
8
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|