dsh-ppt-studio 1.1.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +5 -2
  2. package/docs/00-/350/256/276/350/256/241/346/272/220.md +4 -0
  3. package/docs/02-/346/212/200/346/234/257/346/212/245/345/221/212.md +114 -1
  4. package/docs/03-/346/233/264/346/226/260/346/227/245/345/277/227.md +171 -0
  5. package/docs/05-/350/277/255/344/273/243/346/265/201/347/250/213.md +24 -1
  6. package/docs/06-/350/257/204/345/256/241/344/270/216/346/265/213/350/257/225.md +2 -1
  7. package/docs/07-/345/244/215/346/235/202/345/233/276/350/203/275/345/212/233/347/253/213/351/241/271/344/270/216/351/243/216/351/231/251/347/231/273/350/256/260.md +319 -0
  8. package/docs/08-/351/230/266/346/256/265A/350/256/276/350/256/241/350/257/264/346/230/216-/347/273/223/346/236/204/345/205/263/347/263/273/344/270/216/345/233/276/344/270/223/345/261/236/346/240/241/351/252/214.md +306 -0
  9. package/docs/09-/344/273/243/347/240/201/345/234/260/345/233/276/344/270/216/346/250/241/345/235/227/350/201/214/350/264/243.md +148 -0
  10. package/docs/10-/345/256/277/344/270/273/350/200/246/345/220/210/347/202/271/346/270/205/345/215/225.md +49 -0
  11. package/docs/11-/346/234/257/350/257/255/350/241/250.md +42 -0
  12. package/docs/12-/345/244/215/346/235/202/345/233/276/351/200/232/350/267/257/347/232/204/351/200/211/346/213/251/344/270/216/351/252/214/346/224/266.md +65 -0
  13. package/docs/13-/345/217/221/347/211/210/345/207/206/345/244/207/350/256/241/345/210/222.md +79 -0
  14. package/docs/14-/345/217/221/345/270/203/346/270/205/345/215/225/357/274/210/350/215/211/347/250/277/357/274/211.md +37 -0
  15. package/docs/17-/346/211/213/347/224/27313/351/241/265/350/255/246/345/221/212/351/200/220/346/235/241/345/244/204/347/275/256.md +102 -0
  16. package/examples/fx/fx-pro/preview/layout.json +12 -0
  17. package/examples/fx/fx-pro/preview/measured.json +1 -1
  18. package/examples/fx/fx-pro.pptx +0 -0
  19. package/examples/fx/seed.pptx +0 -0
  20. package/examples/fx/single.pptx +0 -0
  21. package/examples/fx/spliced.pptx +0 -0
  22. package/examples/smoke/imported/preview-rt/layout.json +3 -0
  23. package/examples/smoke/imported/source.pptx +0 -0
  24. package/examples/smoke/out-smoke.pptx +0 -0
  25. package/examples/smoke/preview/layout.json +3 -0
  26. package/lib/group-render.js +177 -0
  27. package/lib/msrender.js +27 -12
  28. package/lib/pptd/blocks.js +52 -0
  29. package/lib/pptd/export-pptx.js +266 -11
  30. package/lib/pptd/layout.js +54 -3
  31. package/lib/pptd/line-rules.js +259 -0
  32. package/lib/pptd/line-text-rule.js +90 -0
  33. package/lib/pptd/relations.js +615 -0
  34. package/lib/pptd/render-html.js +19 -1
  35. package/lib/pptd/route-geometry.js +120 -0
  36. package/lib/pptd/schema.js +146 -11
  37. package/lib/pptd/style-profile.js +133 -0
  38. package/lib/router.js +2 -2
  39. package/lib/scaffold.js +54 -1
  40. package/lib/tools.js +22 -4
  41. package/lib/verify.js +69 -1
  42. package/package.json +20 -3
  43. package/scripts/audit-manual-facts.mjs +15 -3
  44. package/scripts/bench-diagram-scale.mjs +165 -0
  45. package/scripts/check-generators.mjs +22 -0
  46. package/scripts/check-lib-sync.mjs +33 -0
  47. package/scripts/check-line-text.mjs +30 -0
  48. package/scripts/check-package.mjs +60 -0
  49. package/scripts/check-removed-traces.mjs +37 -0
  50. package/scripts/check-syntax.mjs +44 -0
  51. package/scripts/check-unknown-keys.mjs +114 -0
  52. package/scripts/fixtures/handdrawn-baseline.json +177 -0
  53. package/scripts/fixtures/prompt-cost-baseline.json +178 -0
  54. package/scripts/fixtures/workflow-baseline.json +20 -15
  55. package/scripts/handdrawn-option-probe.mjs +78 -0
  56. package/scripts/probe-prompt-cost.mjs +127 -0
  57. package/scripts/red-probe.mjs +75 -0
  58. package/scripts/render-group.mjs +72 -0
  59. package/scripts/smoke.mjs +183 -12
  60. package/scripts/test-fast.mjs +108 -0
  61. package/scripts/test-map.mjs +162 -0
  62. package/scripts/test-release.mjs +64 -0
  63. package/scripts/verify-diagram-relations.mjs +405 -0
  64. package/scripts/verify-handdrawn.mjs +115 -0
  65. package/scripts/verify-handwritten.mjs +203 -0
  66. package/scripts/verify-native-charts.mjs +25 -10
  67. package/scripts/verify-primitives.mjs +714 -0
  68. package/scripts/verify-products.mjs +37 -0
  69. package/scripts/verify-shape.mjs +84 -0
  70. package/scripts/visual-pair-batch.mjs +77 -0
  71. package/skills/diagram-drawing/SKILL.md +23 -0
  72. package/skills/diagram-drawing/capability-matrix.md +22 -0
  73. package/skills/diagram-drawing/composition.md +22 -0
  74. package/skills/diagram-drawing/mechanisms.md +141 -0
  75. package/skills/diagram-drawing/pitfalls.md +89 -0
  76. package/skills/diagram-drawing/routing.md +17 -0
  77. package/skills/diagram-drawing/text-and-spacing.md +16 -0
  78. package/skills/diagram-drawing/verify.md +50 -0
  79. package/skills/diagrams/compare.md +24 -0
  80. package/skills/diagrams/flow.md +24 -0
  81. package/skills/diagrams/funnel.md +25 -0
  82. package/skills/diagrams/layers.md +18 -0
  83. package/skills/diagrams/loop.md +25 -0
  84. package/skills/diagrams/matrix.md +23 -0
  85. package/skills/diagrams/sequence.md +17 -0
  86. package/skills/diagrams/state.md +34 -0
  87. package/skills/diagrams/steps-ring.md +24 -0
  88. package/skills/diagrams/swimlane.md +23 -0
  89. package/skills/diagrams/timeline.md +24 -0
  90. package/skills/diagrams/tree.md +24 -0
  91. package/skills/ppt-studio-manual/SKILL.md +2 -2
  92. package/templates/academic-white/preview.png +0 -0
  93. package/templates/business-blue/preview.png +0 -0
  94. package/templates/pitch-bold/preview.png +0 -0
  95. package/templates/tech-dark/preview.png +0 -0
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `unknown-key` 检查:页面级/元素级**未知键** ⇒ 报 warning(**不阻断** ✓)。
4
+ *
5
+ * 为什么需要:写错/残留的键过去会被静默忽略 ⇒ 表面"出图了",其实是空页或漏项。
6
+ *
7
+ * 白名单来源(**不手写猜测** ✓):
8
+ * · 页面级:从 `src/pptd/schema.js` 的 `validatePage` 里**真正被访问的 `page.<键>`** 推导;
9
+ * · 元素级:`ELEMENT_KEYS`(类型专属)+ 通用键(`elementId/elementType/bounds/...`)+ `path`(custGeom 路径)。
10
+ * 防漂移:默认模式扫**本仓自带示例**,一旦发现未知键就**判失败** ⇒ 白名单漏项会立刻在 `npm test` 暴露 ✓
11
+ * (宁可在 CI 里发现自己漏了键,也不能对用户误报)。
12
+ *
13
+ * 用法:
14
+ * node scripts/check-unknown-keys.mjs # 扫 examples/hand-drawn + examples/smoke(必须 0 命中)
15
+ * node scripts/check-unknown-keys.mjs --fixture <dir> # 扫指定夹具(至少 1 命中才算红样本通过)
16
+ */
17
+ import { readdirSync, readFileSync, existsSync } from 'node:fs'
18
+ import { join } from 'node:path'
19
+
20
+ const ROOT = new URL('..', import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, '$1')
21
+
22
+ // ── 白名单(来源见文件头注释;改 schema 消费点时同步这里)──
23
+ const PAGE_KEYS = new Set([
24
+ 'version', 'pageType', 'title', 'elements', 'notes', 'groups', 'expectedOverlaps',
25
+ 'background', 'blocks', 'contrastExempt', 'expectedOutOfSafeArea', 'overlapMode',
26
+ 'rowBounds', 'safeArea', 'source',
27
+ ])
28
+ const EL_COMMON = new Set([
29
+ 'elementId', 'elementType', 'bounds', 'role', 'roleReason', 'contains', 'badgeOf',
30
+ 'expectedOverlaps', 'rotation',
31
+ ])
32
+ const EL_BY_TYPE = {
33
+ text: ['content'],
34
+ shape: ['kind', 'fill', 'line', 'path'],
35
+ line: ['points', 'arrow', 'line', 'attach', 'dash'],
36
+ image: ['src', 'fit'],
37
+ table: ['cols', 'rows', 'header'],
38
+ chart: ['chart'],
39
+ }
40
+ const elAllowed = (type) => new Set([...EL_COMMON, ...(EL_BY_TYPE[type] ?? [])])
41
+
42
+ // ── 收集待检 YAML ──
43
+ const collect = (dir) => {
44
+ const out = []
45
+ const rec = (d) => {
46
+ for (const e of readdirSync(d, { withFileTypes: true })) {
47
+ const p = join(d, e.name)
48
+ if (/preview$|\.tmp/.test(p)) continue
49
+ if (e.isDirectory()) rec(p)
50
+ else if (/^pages?\/.*\.ya?ml$|pages\/.*\.ya?ml$/.test(p.replace(/\\/g, '/')) || /\.ya?ml$/.test(e.name)) out.push(p)
51
+ }
52
+ }
53
+ rec(dir)
54
+ return out.filter((p) => !/deck\.ya?ml$/.test(p)) // deck.yaml 是 deck 级(另有 schema 校验)
55
+ }
56
+
57
+ // ── 极简 YAML 顶层/元素键扫描(只认结构,不做完整解析)──
58
+ const scanPage = (file) => {
59
+ const text = readFileSync(file, 'utf8')
60
+ const lines = text.split('\n')
61
+ const found = []
62
+ let inElements = false
63
+ let curEl = null
64
+ const flushEl = () => {
65
+ if (!curEl) return
66
+ const allowed = elAllowed(curEl.type)
67
+ for (const k of Object.keys(curEl.keys)) if (!allowed.has(k)) found.push({ scope: '元素 ' + (curEl.id ?? '?'), key: k })
68
+ curEl = null
69
+ }
70
+ for (let i = 0; i < lines.length; i++) {
71
+ const raw = lines[i]
72
+ const line = raw.replace(/\s+#.*$/, '')
73
+ if (!line.trim() || /^\s*#/.test(line)) continue
74
+ const top = line.match(/^([A-Za-z_][\w]*):/)
75
+ if (top) {
76
+ if (top[1] === 'elements') { inElements = true; continue }
77
+ if (!PAGE_KEYS.has(top[1])) found.push({ scope: '页面', key: top[1] })
78
+ continue
79
+ }
80
+ if (!inElements) continue
81
+ const elStart = line.match(/^ {2}- elementId:\s*(\S+)/)
82
+ if (elStart) { flushEl(); curEl = { id: elStart[1].replace(/['"]/g, ''), type: null, keys: {} }; continue }
83
+ if (!curEl) continue
84
+ const kv = line.match(/^ {4}([A-Za-z_][\w]*):\s*(.*)$/)
85
+ if (!kv) continue
86
+ const [, k, v] = kv
87
+ if (k === 'elementType') curEl.type = v.trim().replace(/['"]/g, '')
88
+ else curEl.keys[k] = true
89
+ }
90
+ flushEl()
91
+ return found
92
+ }
93
+
94
+ // ── 主流程 ──
95
+ const args = process.argv.slice(2)
96
+ const fixtureIdx = args.indexOf('--fixture')
97
+ const targets = fixtureIdx >= 0 ? [join(ROOT, args[fixtureIdx + 1])] : [join(ROOT, 'examples', 'hand-drawn'), join(ROOT, 'examples', 'smoke')]
98
+ const hits = []
99
+ for (const t of targets) {
100
+ if (!existsSync(t)) continue
101
+ for (const f of collect(t)) for (const h of scanPage(f)) hits.push({ file: f.replace(ROOT + '/', ''), ...h })
102
+ }
103
+ if (fixtureIdx >= 0) {
104
+ console.log('unknown-key 红样本:[fixture] 命中 ' + hits.length + ' 处' + (hits.length > 0 ? ' ✓' : ' ✗'))
105
+ for (const h of hits) console.log(' [警告][unknown-key] ' + h.file + ' — ' + h.scope + ' 出现未知键 "' + h.key + '"')
106
+ process.exit(hits.length > 0 ? 0 : 1)
107
+ }
108
+ console.log('unknown-key 零误报自证:扫 ' + targets.length + ' 个目录|未知键 ' + hits.length + ' 处')
109
+ for (const h of hits.slice(0, 12)) console.log(' · ' + h.file + ' ' + h.scope + ' → ' + h.key)
110
+ if (hits.length) {
111
+ console.log('✗ 本仓示例出现未知键 ⇒ 要么页面写错(应修页面),要么白名单漏了合法键(应补白名单)——两者都必须处理')
112
+ process.exit(1)
113
+ }
114
+ console.log('✓ 本仓示例 0 未知键(白名单与真实用法一致)')
@@ -0,0 +1,177 @@
1
+ {
2
+ "savedAt": "2026-09-30T04:24:38.618Z",
3
+ "head": "55f17ad08101da726b73a9001134a6746ae86299",
4
+ "digest": "f675371b5e56d694d80e4915cc443ccd0aa3e88b7c97d367aceaf5539ae35fbd",
5
+ "perPage": [
6
+ {
7
+ "page": "01",
8
+ "els": 23,
9
+ "errors": 0,
10
+ "errorCodes": [],
11
+ "warns": 3,
12
+ "warnCodes": [
13
+ "hotspot"
14
+ ],
15
+ "digest": "cc0400aa6eb74da595cc69ee555418d2123c408eaebc739b389ba4ee142c1d17"
16
+ },
17
+ {
18
+ "page": "02",
19
+ "els": 19,
20
+ "errors": 0,
21
+ "errorCodes": [],
22
+ "warns": 1,
23
+ "warnCodes": [
24
+ "density"
25
+ ],
26
+ "digest": "fb901a860b2812aa8dc00b34e8d0f48b87b25fecc0eec6471cea92fa637d272c"
27
+ },
28
+ {
29
+ "page": "03",
30
+ "els": 27,
31
+ "errors": 0,
32
+ "errorCodes": [],
33
+ "warns": 5,
34
+ "warnCodes": [
35
+ "density",
36
+ "hotspot",
37
+ "line-end-off-edge"
38
+ ],
39
+ "digest": "82603d08ddeed43514ceca9dca6a26a72cff87bdd5009651c3444d6bd3d5b700"
40
+ },
41
+ {
42
+ "page": "04",
43
+ "els": 31,
44
+ "errors": 0,
45
+ "errorCodes": [],
46
+ "warns": 7,
47
+ "warnCodes": [
48
+ "arrow-tip-inside-shape",
49
+ "density",
50
+ "hotspot"
51
+ ],
52
+ "digest": "4ba29ae26b06e837e647c6c9ffe88139c8e853c637b78b1808c8a2c60512aad1"
53
+ },
54
+ {
55
+ "page": "05",
56
+ "els": 23,
57
+ "errors": 0,
58
+ "errorCodes": [],
59
+ "warns": 3,
60
+ "warnCodes": [
61
+ "density",
62
+ "hotspot"
63
+ ],
64
+ "digest": "08c7d4dc3efce9f743a96cd25489b94dbfd0d8ea03efb8650432769860fa5dd3"
65
+ },
66
+ {
67
+ "page": "06",
68
+ "els": 17,
69
+ "errors": 0,
70
+ "errorCodes": [],
71
+ "warns": 4,
72
+ "warnCodes": [
73
+ "line-diagonal-segment"
74
+ ],
75
+ "digest": "dc9bafef54b12d21bed5e158541f1338189ece093592d89b3534a024bb60956a"
76
+ },
77
+ {
78
+ "page": "07",
79
+ "els": 10,
80
+ "errors": 0,
81
+ "errorCodes": [],
82
+ "warns": 0,
83
+ "warnCodes": [],
84
+ "digest": "7dd49bca1f4d720972e5540ab00c08d11f1e543d0b50151126c0fee5944d22c8"
85
+ },
86
+ {
87
+ "page": "08",
88
+ "els": 23,
89
+ "errors": 0,
90
+ "errorCodes": [],
91
+ "warns": 6,
92
+ "warnCodes": [
93
+ "line-diagonal-segment"
94
+ ],
95
+ "digest": "e6955cc6d03591df46be9312201f2a5088c1c26a64248304ed1d00d1a48030d4"
96
+ },
97
+ {
98
+ "page": "09",
99
+ "els": 29,
100
+ "errors": 0,
101
+ "errorCodes": [],
102
+ "warns": 1,
103
+ "warnCodes": [
104
+ "line-crossing"
105
+ ],
106
+ "digest": "3bd30c8dc70278153553e829575e05818449883b8a1a101f5f4025c4660a5711"
107
+ },
108
+ {
109
+ "page": "10",
110
+ "els": 27,
111
+ "errors": 0,
112
+ "errorCodes": [],
113
+ "warns": 2,
114
+ "warnCodes": [
115
+ "density",
116
+ "hotspot"
117
+ ],
118
+ "digest": "475fbd6aaa18735c00a211387a89a5eabc45e90294dbc36e480611c1554a8dc7"
119
+ },
120
+ {
121
+ "page": "11",
122
+ "els": 18,
123
+ "errors": 0,
124
+ "errorCodes": [],
125
+ "warns": 0,
126
+ "warnCodes": [],
127
+ "digest": "45e04425fe4a65830f3850c66f166efc492befee277862c3d62837f9d764a55a"
128
+ },
129
+ {
130
+ "page": "12",
131
+ "els": 29,
132
+ "errors": 0,
133
+ "errorCodes": [],
134
+ "warns": 1,
135
+ "warnCodes": [
136
+ "density"
137
+ ],
138
+ "digest": "6c29eaebbde6714ad9b54e10cfa078070aab86a7c581f2f985424f873a8e16a6"
139
+ },
140
+ {
141
+ "page": "13",
142
+ "els": 25,
143
+ "errors": 0,
144
+ "errorCodes": [],
145
+ "warns": 7,
146
+ "warnCodes": [
147
+ "attach-override",
148
+ "density",
149
+ "hotspot"
150
+ ],
151
+ "digest": "e4d6fc9e7aa69febc5af53cb659a3553f70655a0e2bafb85e2476ecb98ec6ee4"
152
+ }
153
+ ],
154
+ "pngs": {
155
+ "01-层级树(手画).png": "e58fadc991edb4b57b6832cad9830ed28aa62f34fb8097e7ef56352fee915855",
156
+ "02-矩阵(手画).png": "f72c62f4215b4f09643c90221adbd97ee8d725b3d55e8b7ca7f88ee25dee1a66",
157
+ "03-时间轴(手画).png": "df7bd35389ab379c6cabdfac2ae82ebec29aebb2bdfd5b5ce82f895fd897adb5",
158
+ "04-泳道(手画).png": "ee642e5989c1c4f09a079e26e82b1b720449910f3a92d8d6fdbebf5a23b888af",
159
+ "05-左右对比(手画).png": "afa2caf3a16bcebc8cb1d3ead09a5dc5b3eaed6ca682281d8268402d50d0bd71",
160
+ "06-闭环(手画).png": "f5b8cf822c503fbe1669fea5fc109fb84d946a87ddb35b6bd6a12ed90acf8bbd",
161
+ "07-漏斗(手画).png": "f00e0251aef97510aec6336fe2a32fcd8f5acb0c5b2c1e361be95598909d72b1",
162
+ "08-步骤环(手画).png": "50e1c1f175fea024c0c5b956cfb919dc44fa7e8329646199343097c538943d31",
163
+ "09-时序(手画).png": "1cc278d9a41f5f3e2217f0913af954b264a2e01a6326723fcce4584fdbe20331",
164
+ "10-状态机(手画).png": "9a84e28cabacf631118633e0c50ca4ef4a402fb659da0c8310b80c421a9ff36e",
165
+ "11-流程图(手画).png": "dcf2887e1824496448bfaf2be3757fb7087a989e63a8f2eb55e3be150c5727ab",
166
+ "12-分层架构(手画).png": "69989c267bf13a89279f4d192e752f8aff918d49b0583c1e0888a60ea22e37a0",
167
+ "13-平台架构(手画).png": "05a454b19ffd2aac351e2e343d4a545aeeb630f1bd5eda0183fe3fe2fb09c100"
168
+ },
169
+ "history": [
170
+ {
171
+ "at": "2026-09-30T04:24:38.616Z",
172
+ "from": "f675371b5e56d694d80e4915cc443ccd0aa3e88b7c97d367aceaf5539ae35fbd",
173
+ "to": "f675371b5e56d694d80e4915cc443ccd0aa3e88b7c97d367aceaf5539ae35fbd",
174
+ "reason": "摘要未变(重采): P2-3 补采:为基线补写变更沿革(history 断言上线前的一次留痕)"
175
+ }
176
+ ]
177
+ }
@@ -0,0 +1,178 @@
1
+ {
2
+ "measuredAt": "2026-09-27",
3
+ "estimator": "CJK=1 token/字;其余=4 字节/token",
4
+ "toolCount": 22,
5
+ "tools": [
6
+ {
7
+ "name": "ppt_verify",
8
+ "chars": 860,
9
+ "bytes": 1467,
10
+ "tokens": 436
11
+ },
12
+ {
13
+ "name": "ppt_patch",
14
+ "chars": 767,
15
+ "bytes": 1283,
16
+ "tokens": 380
17
+ },
18
+ {
19
+ "name": "ppt_visual",
20
+ "chars": 733,
21
+ "bytes": 1208,
22
+ "tokens": 355
23
+ },
24
+ {
25
+ "name": "ppt_template_add",
26
+ "chars": 795,
27
+ "bytes": 1211,
28
+ "tokens": 353
29
+ },
30
+ {
31
+ "name": "ppt_splice",
32
+ "chars": 677,
33
+ "bytes": 1071,
34
+ "tokens": 310
35
+ },
36
+ {
37
+ "name": "ppt_export",
38
+ "chars": 637,
39
+ "bytes": 955,
40
+ "tokens": 279
41
+ },
42
+ {
43
+ "name": "ppt_template_styleaudit",
44
+ "chars": 573,
45
+ "bytes": 853,
46
+ "tokens": 244
47
+ },
48
+ {
49
+ "name": "ppt_crosscheck",
50
+ "chars": 425,
51
+ "bytes": 761,
52
+ "tokens": 233
53
+ },
54
+ {
55
+ "name": "ppt_new",
56
+ "chars": 524,
57
+ "bytes": 712,
58
+ "tokens": 202
59
+ },
60
+ {
61
+ "name": "ppt_shot",
62
+ "chars": 533,
63
+ "bytes": 711,
64
+ "tokens": 199
65
+ },
66
+ {
67
+ "name": "ppt_slice",
68
+ "chars": 459,
69
+ "bytes": 657,
70
+ "tokens": 188
71
+ },
72
+ {
73
+ "name": "ppt_measure",
74
+ "chars": 407,
75
+ "bytes": 629,
76
+ "tokens": 182
77
+ },
78
+ {
79
+ "name": "ppt_templates",
80
+ "chars": 354,
81
+ "bytes": 580,
82
+ "tokens": 172
83
+ },
84
+ {
85
+ "name": "ppt_template_remove",
86
+ "chars": 352,
87
+ "bytes": 534,
88
+ "tokens": 157
89
+ },
90
+ {
91
+ "name": "ppt_preview",
92
+ "chars": 287,
93
+ "bytes": 443,
94
+ "tokens": 129
95
+ },
96
+ {
97
+ "name": "ppt_import",
98
+ "chars": 318,
99
+ "bytes": 410,
100
+ "tokens": 114
101
+ },
102
+ {
103
+ "name": "ppt_render",
104
+ "chars": 315,
105
+ "bytes": 399,
106
+ "tokens": 110
107
+ },
108
+ {
109
+ "name": "ppt_check",
110
+ "chars": 284,
111
+ "bytes": 380,
112
+ "tokens": 107
113
+ },
114
+ {
115
+ "name": "ppt_media",
116
+ "chars": 254,
117
+ "bytes": 340,
118
+ "tokens": 96
119
+ },
120
+ {
121
+ "name": "ppt_schema",
122
+ "chars": 214,
123
+ "bytes": 292,
124
+ "tokens": 83
125
+ },
126
+ {
127
+ "name": "ppt_state",
128
+ "chars": 249,
129
+ "bytes": 303,
130
+ "tokens": 83
131
+ },
132
+ {
133
+ "name": "ppt_status",
134
+ "chars": 213,
135
+ "bytes": 283,
136
+ "tokens": 80
137
+ }
138
+ ],
139
+ "skills": [
140
+ {
141
+ "name": "ppt-studio-manual",
142
+ "chars": 201,
143
+ "bytes": 403,
144
+ "tokens": 125
145
+ },
146
+ {
147
+ "name": "ppt-studio-data",
148
+ "chars": 127,
149
+ "bytes": 331,
150
+ "tokens": 107
151
+ },
152
+ {
153
+ "name": "ppt-studio-copy",
154
+ "chars": 131,
155
+ "bytes": 319,
156
+ "tokens": 102
157
+ },
158
+ {
159
+ "name": "ppt-studio-craft",
160
+ "chars": 121,
161
+ "bytes": 307,
162
+ "tokens": 99
163
+ }
164
+ ],
165
+ "workflow": {
166
+ "tokens": 4409,
167
+ "chars": 6941,
168
+ "quickTokens": 575,
169
+ "quickChars": 836,
170
+ "note": ""
171
+ },
172
+ "totals": {
173
+ "tools": 4492,
174
+ "skills": 433,
175
+ "workflow": 4409,
176
+ "all": 9334
177
+ }
178
+ }
@@ -35,9 +35,10 @@
35
35
  "7. 交付前:S4 全通过 + S6 导出 .pptx + 交付说明(素材来源、未视觉审阅项、修改指引)。**内容审阅(M3 重写 2026-09-18)**:有具体数字/事实主张的稿子,交付前用 `ppt_crosscheck` 生成「审阅材料包」(全页正文 + 素材清单 + 审阅协议)→ 再按协议做一次内容审阅:**默认用独立子代理**(全新上下文、只给材料包与素材文件;**用户明确禁止子代理时改自审并标注「自审(同上下文)」**),逐条判\"一致 / 冲突 / 无来源支撑 / 无法核实\",重点核对同一指标跨页值是否一致、数字是否有依据、结论是否强于数据;**没有外部素材时只能判\"无法核实\",不得报绿**。该工具**只汇总材料、不做判定、不构成门禁**(旧版 grounded/unmapped 状态与跨页数字分组已废除)。制作进程中**供用户看稿优先用 ppt_preview(dir)**(返回同源预览链接,用户点击即看,附在交付信息里);导出前/后均可预览。**修改既有精美 PPT 的某一页(edit/augment 高频场景)**:ppt_import 参考层读真身 → 改工作区页并审阅清零 → **`ppt_splice`**(只把该页替换进原稿:保留源母版横幅/页脚/备注关系/媒体,其余页条目 SHA256 逐字节一致——不要整册近似重渲伤及其他页)→ 交付整册副本;用户要\"单页独立版\"再 **`ppt_slice`**;抽查该页观感用 **`ppt_visual pages=N`**(按页真渲染,不必整册);\"看起来就是模板原样\"用 `ppt_patch`(手术贴模板)。",
36
36
  "8. 版式系统(审美基线,用户风格优先):写页面之前先定版式规则——默认基线:8px 网格对齐、3-4 级字号阶梯、4-5 色主题(只在 $theme 内取色)、统一间距节奏(8/16/24px)、左右外边界一致、构图重心居中;**用户对风格有要求(字体/字号/配色/密度)一律优先,默认基线仅为未指定时的风格参考**。文字:短句化(每块 ≤60 字为默认参考,可依内容放宽),**文本最小字号以用户指令为准**(hardConstraints;未给下限不设强制),长句在语义断点显式 \\\\n 换行。",
37
37
  "9. 审美建议(ppt_verify 输出的 [·] 建议)不是门禁,但请逐条斟酌采纳;overlap/out-of-page/text-overflow 错误仍必须清零(审美改进不得引入元素区块冲突)。",
38
- "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;图表矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
38
+ "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表同为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
39
39
  "11. 质量档 audit(/ppt quality audit,从严门禁):禁 autoDeclare(工具已拦);每页必须 ppt_shot + 读图视觉审阅(无读图能力则降级结构 Lint 并在交付说明标注\"未经视觉审阅\");导出报告必须包含并核对 audit 回读断言(页数/尺寸/最小字号 ≥ minFontSize);有 Office 时导出后自动 **Office 真渲染**(成品视觉审核,逐页 read_image);交付说明含素材来源与数据脱敏/假设标注。",
40
- "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。"
40
+ "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。",
41
+ "13. **改既有 PPT 的两条纪律**:① **就地手术优先**——任务若是\"改某几页 / 改一处文字 / 换一张图\",优先 `ppt_splice`(把工作区某一页替换进原稿,**其余页逐字节不变**;用户要\"单页独立版\"用 `ppt_slice`;要\"看起来就是模板原样\"用 `ppt_patch`),不要图省事整册重渲。`ppt_import` 会给出**页码/元素级**的\"无法保真特性\"清单(工程内 `loss-audit.json` + 一行结论),并按 ✓/⚠/ℹ 三档区分:✓ 干净、⚠ 有会丢的可见特性(动画/阴影/超链接/切换/SmartArt/EMF 等)、ℹ 仅主题样式表里的渐变模板未被引用(不影响观感);**⚠ 命中时\"只改某几页\"必须走 `ppt_splice`,并在交付说明里写明\"整册重渲会丢 <类别 N 处>\"**。② **Excel 素材的数字要么重算、要么标注**:从 xlsx 取数时公式的缓存值可能陈旧或缺失;探测到捆绑 LibreOffice kit 就用它的 `recalculate` 重算,做不到时必须在交付说明里写明\"公式值未重算(可能陈旧)\",别把旧缓存值当已核对的数据。"
41
42
  ]
42
43
  },
43
44
  {
@@ -74,9 +75,10 @@
74
75
  "7. 交付前:S4 全通过 + S6 导出 .pptx + 交付说明(素材来源、未视觉审阅项、修改指引)。**内容审阅(M3 重写 2026-09-18)**:有具体数字/事实主张的稿子,交付前用 `ppt_crosscheck` 生成「审阅材料包」(全页正文 + 素材清单 + 审阅协议)→ 再按协议做一次内容审阅:**默认用独立子代理**(全新上下文、只给材料包与素材文件;**用户明确禁止子代理时改自审并标注「自审(同上下文)」**),逐条判\"一致 / 冲突 / 无来源支撑 / 无法核实\",重点核对同一指标跨页值是否一致、数字是否有依据、结论是否强于数据;**没有外部素材时只能判\"无法核实\",不得报绿**。该工具**只汇总材料、不做判定、不构成门禁**(旧版 grounded/unmapped 状态与跨页数字分组已废除)。制作进程中**供用户看稿优先用 ppt_preview(dir)**(返回同源预览链接,用户点击即看,附在交付信息里);导出前/后均可预览。**修改既有精美 PPT 的某一页(edit/augment 高频场景)**:ppt_import 参考层读真身 → 改工作区页并审阅清零 → **`ppt_splice`**(只把该页替换进原稿:保留源母版横幅/页脚/备注关系/媒体,其余页条目 SHA256 逐字节一致——不要整册近似重渲伤及其他页)→ 交付整册副本;用户要\"单页独立版\"再 **`ppt_slice`**;抽查该页观感用 **`ppt_visual pages=N`**(按页真渲染,不必整册);\"看起来就是模板原样\"用 `ppt_patch`(手术贴模板)。",
75
76
  "8. 版式系统(审美基线,用户风格优先):写页面之前先定版式规则——默认基线:8px 网格对齐、3-4 级字号阶梯、4-5 色主题(只在 $theme 内取色)、统一间距节奏(8/16/24px)、左右外边界一致、构图重心居中;**用户对风格有要求(字体/字号/配色/密度)一律优先,默认基线仅为未指定时的风格参考**。文字:短句化(每块 ≤60 字为默认参考,可依内容放宽),**文本最小字号以用户指令为准**(hardConstraints;未给下限不设强制),长句在语义断点显式 \\\\n 换行。",
76
77
  "9. 审美建议(ppt_verify 输出的 [·] 建议)不是门禁,但请逐条斟酌采纳;overlap/out-of-page/text-overflow 错误仍必须清零(审美改进不得引入元素区块冲突)。",
77
- "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;图表矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
78
+ "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表同为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
78
79
  "11. 质量档 audit(/ppt quality audit,从严门禁):禁 autoDeclare(工具已拦);每页必须 ppt_shot + 读图视觉审阅(无读图能力则降级结构 Lint 并在交付说明标注\"未经视觉审阅\");导出报告必须包含并核对 audit 回读断言(页数/尺寸/最小字号 ≥ minFontSize);有 Office 时导出后自动 **Office 真渲染**(成品视觉审核,逐页 read_image);交付说明含素材来源与数据脱敏/假设标注。",
79
- "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。"
80
+ "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。",
81
+ "13. **改既有 PPT 的两条纪律**:① **就地手术优先**——任务若是\"改某几页 / 改一处文字 / 换一张图\",优先 `ppt_splice`(把工作区某一页替换进原稿,**其余页逐字节不变**;用户要\"单页独立版\"用 `ppt_slice`;要\"看起来就是模板原样\"用 `ppt_patch`),不要图省事整册重渲。`ppt_import` 会给出**页码/元素级**的\"无法保真特性\"清单(工程内 `loss-audit.json` + 一行结论),并按 ✓/⚠/ℹ 三档区分:✓ 干净、⚠ 有会丢的可见特性(动画/阴影/超链接/切换/SmartArt/EMF 等)、ℹ 仅主题样式表里的渐变模板未被引用(不影响观感);**⚠ 命中时\"只改某几页\"必须走 `ppt_splice`,并在交付说明里写明\"整册重渲会丢 <类别 N 处>\"**。② **Excel 素材的数字要么重算、要么标注**:从 xlsx 取数时公式的缓存值可能陈旧或缺失;探测到捆绑 LibreOffice kit 就用它的 `recalculate` 重算,做不到时必须在交付说明里写明\"公式值未重算(可能陈旧)\",别把旧缓存值当已核对的数据。"
80
82
  ]
81
83
  },
82
84
  {
@@ -113,9 +115,10 @@
113
115
  "7. 交付前:S4 全通过 + S6 导出 .pptx + 交付说明(素材来源、未视觉审阅项、修改指引)。**内容审阅(M3 重写 2026-09-18)**:有具体数字/事实主张的稿子,交付前用 `ppt_crosscheck` 生成「审阅材料包」(全页正文 + 素材清单 + 审阅协议)→ 再按协议做一次内容审阅:**默认用独立子代理**(全新上下文、只给材料包与素材文件;**用户明确禁止子代理时改自审并标注「自审(同上下文)」**),逐条判\"一致 / 冲突 / 无来源支撑 / 无法核实\",重点核对同一指标跨页值是否一致、数字是否有依据、结论是否强于数据;**没有外部素材时只能判\"无法核实\",不得报绿**。该工具**只汇总材料、不做判定、不构成门禁**(旧版 grounded/unmapped 状态与跨页数字分组已废除)。制作进程中**供用户看稿优先用 ppt_preview(dir)**(返回同源预览链接,用户点击即看,附在交付信息里);导出前/后均可预览。**修改既有精美 PPT 的某一页(edit/augment 高频场景)**:ppt_import 参考层读真身 → 改工作区页并审阅清零 → **`ppt_splice`**(只把该页替换进原稿:保留源母版横幅/页脚/备注关系/媒体,其余页条目 SHA256 逐字节一致——不要整册近似重渲伤及其他页)→ 交付整册副本;用户要\"单页独立版\"再 **`ppt_slice`**;抽查该页观感用 **`ppt_visual pages=N`**(按页真渲染,不必整册);\"看起来就是模板原样\"用 `ppt_patch`(手术贴模板)。",
114
116
  "8. 版式系统(审美基线,用户风格优先):写页面之前先定版式规则——默认基线:8px 网格对齐、3-4 级字号阶梯、4-5 色主题(只在 $theme 内取色)、统一间距节奏(8/16/24px)、左右外边界一致、构图重心居中;**用户对风格有要求(字体/字号/配色/密度)一律优先,默认基线仅为未指定时的风格参考**。文字:短句化(每块 ≤60 字为默认参考,可依内容放宽),**文本最小字号以用户指令为准**(hardConstraints;未给下限不设强制),长句在语义断点显式 \\\\n 换行。",
115
117
  "9. 审美建议(ppt_verify 输出的 [·] 建议)不是门禁,但请逐条斟酌采纳;overlap/out-of-page/text-overflow 错误仍必须清零(审美改进不得引入元素区块冲突)。",
116
- "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;图表矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
118
+ "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表同为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
117
119
  "11. 质量档 audit(/ppt quality audit,从严门禁):禁 autoDeclare(工具已拦);每页必须 ppt_shot + 读图视觉审阅(无读图能力则降级结构 Lint 并在交付说明标注\"未经视觉审阅\");导出报告必须包含并核对 audit 回读断言(页数/尺寸/最小字号 ≥ minFontSize);有 Office 时导出后自动 **Office 真渲染**(成品视觉审核,逐页 read_image);交付说明含素材来源与数据脱敏/假设标注。",
118
- "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。"
120
+ "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。",
121
+ "13. **改既有 PPT 的两条纪律**:① **就地手术优先**——任务若是\"改某几页 / 改一处文字 / 换一张图\",优先 `ppt_splice`(把工作区某一页替换进原稿,**其余页逐字节不变**;用户要\"单页独立版\"用 `ppt_slice`;要\"看起来就是模板原样\"用 `ppt_patch`),不要图省事整册重渲。`ppt_import` 会给出**页码/元素级**的\"无法保真特性\"清单(工程内 `loss-audit.json` + 一行结论),并按 ✓/⚠/ℹ 三档区分:✓ 干净、⚠ 有会丢的可见特性(动画/阴影/超链接/切换/SmartArt/EMF 等)、ℹ 仅主题样式表里的渐变模板未被引用(不影响观感);**⚠ 命中时\"只改某几页\"必须走 `ppt_splice`,并在交付说明里写明\"整册重渲会丢 <类别 N 处>\"**。② **Excel 素材的数字要么重算、要么标注**:从 xlsx 取数时公式的缓存值可能陈旧或缺失;探测到捆绑 LibreOffice kit 就用它的 `recalculate` 重算,做不到时必须在交付说明里写明\"公式值未重算(可能陈旧)\",别把旧缓存值当已核对的数据。"
119
122
  ]
120
123
  },
121
124
  {
@@ -152,9 +155,10 @@
152
155
  "7. 交付前:S4 全通过 + S6 导出 .pptx + 交付说明(素材来源、未视觉审阅项、修改指引)。**内容审阅(M3 重写 2026-09-18)**:有具体数字/事实主张的稿子,交付前用 `ppt_crosscheck` 生成「审阅材料包」(全页正文 + 素材清单 + 审阅协议)→ 再按协议做一次内容审阅:**默认用独立子代理**(全新上下文、只给材料包与素材文件;**用户明确禁止子代理时改自审并标注「自审(同上下文)」**),逐条判\"一致 / 冲突 / 无来源支撑 / 无法核实\",重点核对同一指标跨页值是否一致、数字是否有依据、结论是否强于数据;**没有外部素材时只能判\"无法核实\",不得报绿**。该工具**只汇总材料、不做判定、不构成门禁**(旧版 grounded/unmapped 状态与跨页数字分组已废除)。制作进程中**供用户看稿优先用 ppt_preview(dir)**(返回同源预览链接,用户点击即看,附在交付信息里);导出前/后均可预览。**修改既有精美 PPT 的某一页(edit/augment 高频场景)**:ppt_import 参考层读真身 → 改工作区页并审阅清零 → **`ppt_splice`**(只把该页替换进原稿:保留源母版横幅/页脚/备注关系/媒体,其余页条目 SHA256 逐字节一致——不要整册近似重渲伤及其他页)→ 交付整册副本;用户要\"单页独立版\"再 **`ppt_slice`**;抽查该页观感用 **`ppt_visual pages=N`**(按页真渲染,不必整册);\"看起来就是模板原样\"用 `ppt_patch`(手术贴模板)。",
153
156
  "8. 版式系统(审美基线,用户风格优先):写页面之前先定版式规则——默认基线:8px 网格对齐、3-4 级字号阶梯、4-5 色主题(只在 $theme 内取色)、统一间距节奏(8/16/24px)、左右外边界一致、构图重心居中;**用户对风格有要求(字体/字号/配色/密度)一律优先,默认基线仅为未指定时的风格参考**。文字:短句化(每块 ≤60 字为默认参考,可依内容放宽),**文本最小字号以用户指令为准**(hardConstraints;未给下限不设强制),长句在语义断点显式 \\\\n 换行。",
154
157
  "9. 审美建议(ppt_verify 输出的 [·] 建议)不是门禁,但请逐条斟酌采纳;overlap/out-of-page/text-overflow 错误仍必须清零(审美改进不得引入元素区块冲突)。",
155
- "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;图表矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
158
+ "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表同为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
156
159
  "11. 质量档 audit(/ppt quality audit,从严门禁):禁 autoDeclare(工具已拦);每页必须 ppt_shot + 读图视觉审阅(无读图能力则降级结构 Lint 并在交付说明标注\"未经视觉审阅\");导出报告必须包含并核对 audit 回读断言(页数/尺寸/最小字号 ≥ minFontSize);有 Office 时导出后自动 **Office 真渲染**(成品视觉审核,逐页 read_image);交付说明含素材来源与数据脱敏/假设标注。",
157
- "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。"
160
+ "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。",
161
+ "13. **改既有 PPT 的两条纪律**:① **就地手术优先**——任务若是\"改某几页 / 改一处文字 / 换一张图\",优先 `ppt_splice`(把工作区某一页替换进原稿,**其余页逐字节不变**;用户要\"单页独立版\"用 `ppt_slice`;要\"看起来就是模板原样\"用 `ppt_patch`),不要图省事整册重渲。`ppt_import` 会给出**页码/元素级**的\"无法保真特性\"清单(工程内 `loss-audit.json` + 一行结论),并按 ✓/⚠/ℹ 三档区分:✓ 干净、⚠ 有会丢的可见特性(动画/阴影/超链接/切换/SmartArt/EMF 等)、ℹ 仅主题样式表里的渐变模板未被引用(不影响观感);**⚠ 命中时\"只改某几页\"必须走 `ppt_splice`,并在交付说明里写明\"整册重渲会丢 <类别 N 处>\"**。② **Excel 素材的数字要么重算、要么标注**:从 xlsx 取数时公式的缓存值可能陈旧或缺失;探测到捆绑 LibreOffice kit 就用它的 `recalculate` 重算,做不到时必须在交付说明里写明\"公式值未重算(可能陈旧)\",别把旧缓存值当已核对的数据。"
158
162
  ]
159
163
  },
160
164
  {
@@ -191,9 +195,10 @@
191
195
  "7. 交付前:S4 全通过 + S6 导出 .pptx + 交付说明(素材来源、未视觉审阅项、修改指引)。**内容审阅(M3 重写 2026-09-18)**:有具体数字/事实主张的稿子,交付前用 `ppt_crosscheck` 生成「审阅材料包」(全页正文 + 素材清单 + 审阅协议)→ 再按协议做一次内容审阅:**默认用独立子代理**(全新上下文、只给材料包与素材文件;**用户明确禁止子代理时改自审并标注「自审(同上下文)」**),逐条判\"一致 / 冲突 / 无来源支撑 / 无法核实\",重点核对同一指标跨页值是否一致、数字是否有依据、结论是否强于数据;**没有外部素材时只能判\"无法核实\",不得报绿**。该工具**只汇总材料、不做判定、不构成门禁**(旧版 grounded/unmapped 状态与跨页数字分组已废除)。制作进程中**供用户看稿优先用 ppt_preview(dir)**(返回同源预览链接,用户点击即看,附在交付信息里);导出前/后均可预览。**修改既有精美 PPT 的某一页(edit/augment 高频场景)**:ppt_import 参考层读真身 → 改工作区页并审阅清零 → **`ppt_splice`**(只把该页替换进原稿:保留源母版横幅/页脚/备注关系/媒体,其余页条目 SHA256 逐字节一致——不要整册近似重渲伤及其他页)→ 交付整册副本;用户要\"单页独立版\"再 **`ppt_slice`**;抽查该页观感用 **`ppt_visual pages=N`**(按页真渲染,不必整册);\"看起来就是模板原样\"用 `ppt_patch`(手术贴模板)。",
192
196
  "8. 版式系统(审美基线,用户风格优先):写页面之前先定版式规则——默认基线:8px 网格对齐、3-4 级字号阶梯、4-5 色主题(只在 $theme 内取色)、统一间距节奏(8/16/24px)、左右外边界一致、构图重心居中;**用户对风格有要求(字体/字号/配色/密度)一律优先,默认基线仅为未指定时的风格参考**。文字:短句化(每块 ≤60 字为默认参考,可依内容放宽),**文本最小字号以用户指令为准**(hardConstraints;未给下限不设强制),长句在语义断点显式 \\\\n 换行。",
193
197
  "9. 审美建议(ppt_verify 输出的 [·] 建议)不是门禁,但请逐条斟酌采纳;overlap/out-of-page/text-overflow 错误仍必须清零(审美改进不得引入元素区块冲突)。",
194
- "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;图表矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
198
+ "10. 引擎:**PPT 制作唯一通道 = pptd**(`deck.yaml` + `pages/*.yaml`;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘)。pptd 硬失败时自动回退 python-pptx(报告醒目标注降级;其图表同为**原生可编辑图表 + 内嵌数据工作簿**);python-pptx 仅用户显式指定时使用。**不要**用 python-pptx 或官方 `office-pptx` 技能从零拼版来绕过本工作流的门禁——它们只适合**读取**既有 pptx、或作为上面的兜底(能不能用由 `ppt_state` 的 `capabilities` 如实报告)。除非用户要求,不要自行切换引擎。",
195
199
  "11. 质量档 audit(/ppt quality audit,从严门禁):禁 autoDeclare(工具已拦);每页必须 ppt_shot + 读图视觉审阅(无读图能力则降级结构 Lint 并在交付说明标注\"未经视觉审阅\");导出报告必须包含并核对 audit 回读断言(页数/尺寸/最小字号 ≥ minFontSize);有 Office 时导出后自动 **Office 真渲染**(成品视觉审核,逐页 read_image);交付说明含素材来源与数据脱敏/假设标注。",
196
- "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。"
200
+ "12. **真渲染抽检铁律(P1 事故教训)**:有 Office 时,真渲染抽查**必须覆盖所有含 table/chart/image/custGeom 的页**(每类至少一页,其余页轮换)——不要只挑\"美观重点页\";抽查后逐页 read_image(渲染图已带 1px=1pt 比例标注水印,降低坐标误判)。导出报告会给出建议覆盖页清单(P8 行)。",
201
+ "13. **改既有 PPT 的两条纪律**:① **就地手术优先**——任务若是\"改某几页 / 改一处文字 / 换一张图\",优先 `ppt_splice`(把工作区某一页替换进原稿,**其余页逐字节不变**;用户要\"单页独立版\"用 `ppt_slice`;要\"看起来就是模板原样\"用 `ppt_patch`),不要图省事整册重渲。`ppt_import` 会给出**页码/元素级**的\"无法保真特性\"清单(工程内 `loss-audit.json` + 一行结论),并按 ✓/⚠/ℹ 三档区分:✓ 干净、⚠ 有会丢的可见特性(动画/阴影/超链接/切换/SmartArt/EMF 等)、ℹ 仅主题样式表里的渐变模板未被引用(不影响观感);**⚠ 命中时\"只改某几页\"必须走 `ppt_splice`,并在交付说明里写明\"整册重渲会丢 <类别 N 处>\"**。② **Excel 素材的数字要么重算、要么标注**:从 xlsx 取数时公式的缓存值可能陈旧或缺失;探测到捆绑 LibreOffice kit 就用它的 `recalculate` 重算,做不到时必须在交付说明里写明\"公式值未重算(可能陈旧)\",别把旧缓存值当已核对的数据。"
197
202
  ]
198
203
  },
199
204
  {
@@ -212,7 +217,7 @@
212
217
  "4. 页数:≤8 页(用户指定除外);每页文本精简(每块 ≤40 字为默认参考,用户要求可放宽)。",
213
218
  "5. 审阅:ppt_render + ppt_verify 必跑——内容互压/出界/文本溢出/预期外重叠(设计意图声明制)必须清零;出界分级同标准模式(超页面不可声明;安全区外有意元素逐项加 expectedOutOfSafeArea);autoDeclare 后附一句意图说明;跳过截图视觉审阅与美学迭代。",
214
219
  "6. 交付:ppt_export(引擎 auto=pptd)→ 交付说明标注\"快速模式:未经视觉审阅\"。",
215
- "7. 引擎:auto 默认 = pptd(自研主引擎,图表矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
220
+ "7. 引擎:auto 默认 = pptd(自研主引擎;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表同为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
216
221
  "8. 用户明确要求始终优先;回到完整模式:/ppt normal。"
217
222
  ]
218
223
  },
@@ -232,7 +237,7 @@
232
237
  "4. 页数:≤8 页(用户指定除外);每页文本精简(每块 ≤40 字为默认参考,用户要求可放宽)。",
233
238
  "5. 审阅:ppt_render + ppt_verify 必跑——内容互压/出界/文本溢出/预期外重叠(设计意图声明制)必须清零;出界分级同标准模式(超页面不可声明;安全区外有意元素逐项加 expectedOutOfSafeArea);autoDeclare 后附一句意图说明;跳过截图视觉审阅与美学迭代。",
234
239
  "6. 交付:ppt_export(引擎 auto=pptd)→ 交付说明标注\"快速模式:未经视觉审阅\"。",
235
- "7. 引擎:auto 默认 = pptd(自研主引擎,图表矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
240
+ "7. 引擎:auto 默认 = pptd(自研主引擎;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表同为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
236
241
  "8. 用户明确要求始终优先;回到完整模式:/ppt normal。"
237
242
  ]
238
243
  },
@@ -252,7 +257,7 @@
252
257
  "4. 页数:≤8 页(用户指定除外);每页文本精简(每块 ≤40 字为默认参考,用户要求可放宽)。",
253
258
  "5. 审阅:ppt_render + ppt_verify 必跑——内容互压/出界/文本溢出/预期外重叠(设计意图声明制)必须清零;出界分级同标准模式(超页面不可声明;安全区外有意元素逐项加 expectedOutOfSafeArea);autoDeclare 后附一句意图说明;跳过截图视觉审阅与美学迭代。",
254
259
  "6. 交付:ppt_export(引擎 auto=pptd)→ 交付说明标注\"快速模式:未经视觉审阅\"。",
255
- "7. 引擎:auto 默认 = pptd(自研主引擎,图表矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
260
+ "7. 引擎:auto 默认 = pptd(自研主引擎;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表同为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
256
261
  "8. 用户明确要求始终优先;回到完整模式:/ppt normal。"
257
262
  ]
258
263
  },
@@ -272,7 +277,7 @@
272
277
  "4. 页数:≤8 页(用户指定除外);每页文本精简(每块 ≤40 字为默认参考,用户要求可放宽)。",
273
278
  "5. 审阅:ppt_render + ppt_verify 必跑——内容互压/出界/文本溢出/预期外重叠(设计意图声明制)必须清零;出界分级同标准模式(超页面不可声明;安全区外有意元素逐项加 expectedOutOfSafeArea);autoDeclare 后附一句意图说明;跳过截图视觉审阅与美学迭代。",
274
279
  "6. 交付:ppt_export(引擎 auto=pptd)→ 交付说明标注\"快速模式:未经视觉审阅\"。",
275
- "7. 引擎:auto 默认 = pptd(自研主引擎,图表矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
280
+ "7. 引擎:auto 默认 = pptd(自研主引擎;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表同为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
276
281
  "8. 用户明确要求始终优先;回到完整模式:/ppt normal。"
277
282
  ]
278
283
  },
@@ -292,7 +297,7 @@
292
297
  "4. 页数:≤8 页(用户指定除外);每页文本精简(每块 ≤40 字为默认参考,用户要求可放宽)。",
293
298
  "5. 审阅:ppt_render + ppt_verify 必跑——内容互压/出界/文本溢出/预期外重叠(设计意图声明制)必须清零;出界分级同标准模式(超页面不可声明;安全区外有意元素逐项加 expectedOutOfSafeArea);autoDeclare 后附一句意图说明;跳过截图视觉审阅与美学迭代。",
294
299
  "6. 交付:ppt_export(引擎 auto=pptd)→ 交付说明标注\"快速模式:未经视觉审阅\"。",
295
- "7. 引擎:auto 默认 = pptd(自研主引擎,图表矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
300
+ "7. 引擎:auto 默认 = pptd(自研主引擎;**图表默认原生可编辑**:图表部件 + 内嵌数据工作簿,`chart.render: vector` 可回到矢量拼绘);python-pptx 仅显式指定或 pptd 失败时使用(其图表同为原生可编辑图表 + 内嵌数据工作簿)。不要自行切换引擎。",
296
301
  "8. 用户明确要求始终优先;回到完整模式:/ppt normal。"
297
302
  ]
298
303
  }