返回 ppt-master
native-enhance-pptx.md
根目录 / skills / ppt-master / workflows / native-enhance-pptx.md
1 ---
2 description: Native enhancement platform for existing PPTX files, with delivery checks and scoped OOXML updates without SVG conversion
3 ---
4
5 # Enhance Native PPTX Route
6
7 > Top-level route for enhancing an existing PowerPoint deck without regenerating it. The current write scope is speaker notes, narration audio, slide auto-advance timings, and global or per-slide page transitions; read-only delivery checks always run.
8
9 This route treats a `.pptx` as the artifact to preserve. It archives the source file into a lightweight project, uses `ppt_to_md.py` only to understand slide content, then patches the archived PPTX package directly through OOXML zip operations.
10
11 ---
12
13 ## 1. Platform Contract
14
15 | Rule | Contract |
16 |---|---|
17 | Source file | If already under `projects/`, move it into the enhancement project; otherwise copy it |
18 | Visible slides | Do not rewrite existing text, shapes, images, charts, tables, masters, or layouts |
19 | Existing hyperlinks | Preserve hyperlink XML and relationships unchanged |
20 | Route | Direct PPTX package patching; no SVG conversion |
21 | Output | A new `.pptx` under `<project>/exports/` |
22 | Project kind | `native_pptx_enhancement` |
23
24 **Hard rule**: Native enhancement is append-oriented. It may add notes, media, timings, transitions, relationships, and content-type records. It must not regenerate slides.
25
26 **Forbidden — SVG pipeline**:
27 - Do not run `pptx_template_import.py`
28 - Do not create `svg_output/`
29 - Do not run `finalize_svg.py`
30 - Do not run `svg_to_pptx.py`
31
32 **Hard rule — public entrypoint**: Route and document all new work through
33 `native_enhance_pptx.py`. The legacy `native_narration_pptx.py` command remains
34 only as a thin CLI compatibility shim; it is not a separate route. The core
35 continues to accept the legacy `native_narration_pptx_project.v1` project schema.
36
37 **OOXML execution model**:
38
39 ```text
40 source.pptx
41 → unzip to temporary work directory
42 → patch only required package parts
43 → rezip to exports/<source>_enhanced.pptx
44 ```
45
46 ---
47
48 ## 2. Module Scope
49
50 | Module | V1 status | Behavior |
51 |---|---:|---|
52 | `narration.notes` | Enabled | Add or replace speaker notes generated from slide content |
53 | `narration.audio` | Enabled | Embed one audio file per slide |
54 | `narration.timings` | Enabled | Set narrated slides to auto-advance from page-start lead-in, audio duration, and page-tail padding |
55 | `narration.transitions` | Enabled | Add page-level transitions for narrated/selected slides |
56 | `delivery.check` | Enabled | Read-only package/font/media/hidden-slide/file-size and existing-motion audit |
57 | `delivery.compress` | Planned | Reduce embedded media size for oversized packages; the audit above already reports them |
58 | `presenter` | Planned | Q&A notes, speaker cues, rehearsal artifacts |
59 | `animation` | Planned | Explicit object-level animation only |
60 | `visible-stamp` | Planned | Watermark/footer/logo; requires explicit confirmation |
61
62 **Default — current write scope only**: Do not implement planned write modules inside this route yet. Keep mutations limited to notes, narration audio, timings, and page transitions.
63
64 **Object animation boundary**: `delivery.check` reports existing object-animation presence, and apply proves its fingerprint is unchanged. It does not author or edit object animations. The shared animation writer builds a complete timing tree for generated slides and is not safe to append to an arbitrary native slide.
65
66 ---
67
68 ## 3. When to Run
69
70 | Condition | Action |
71 |---|---|
72 | Existing `.pptx` + wants notes / narration / voiceover / auto-play / page transitions while keeping format stable | Run this route |
73 | Existing `.pptx` + asks to optimize it but says not to change existing content or layout | Run this route only for V1 narration enhancements; clarify any visible-slide request |
74 | Existing `.pptx` + asks to beautify or re-layout | Enter Generate PPTX with the [`beautify-pptx`](./profiles/beautify-pptx.md) profile |
75 | Existing `.pptx` + asks to fill new content into the design | Use [`template-fill-pptx`](./template-fill-pptx.md) |
76 | PPT Master generated project with `svg_output/` | Stay in Generate PPTX and run the shared [`generate-audio`](./stages/generate-audio.md) stage |
77
78 ---
79
80 ## 4. Create the Project and Draft Plan
81
82 🚧 **GATE**: User provided an existing `.pptx`.
83
84 Run:
85
86 ```bash
87 python3 skills/ppt-master/scripts/native_enhance_pptx.py init "<source.pptx>" --name "<project_slug>"
88 ```
89
90 Project layout:
91
92 | Path | Purpose |
93 |---|---|
94 | `<project>/project.json` | Project schema, kind, enabled modules, source paths, defaults |
95 | `<project>/sources/<source>.pptx` | Archived source PPTX used for package patching |
96 | `<project>/sources/<source>.md` | `ppt_to_md.py` output for slide understanding |
97 | `<project>/analysis/slide_index.json` | Slide order and PPTX slide part mapping |
98 | `<project>/notes/` | Per-slide spoken notes, named `001.md`, `002.md`, ... |
99 | `<project>/audio/` | Per-slide narration media, named `001.mp3`, `002.mp3`, ... |
100 | `<project>/exports/` | Enhanced PPTX copies |
101 | `<project>/validation/` | Delivery checks, readiness reports, and read-back artifacts |
102
103 **Validation**: `project.json` contains `schema: native_pptx_enhancement_project.v1`, `kind: native_pptx_enhancement`, and `modules` containing `notes`, `audio`, `timings`, `transitions`, and `delivery.check`.
104
105 `init` records the archived source SHA-256 and ordered slide-part roster, then writes the intake audit to `<project>/validation/report.json`. Package-integrity, OPC part/content-type/relationship, XML, slide-inventory, transition, or object-animation errors stop before a project-local source is moved. The only retained historical structural baseline is the narrowly recognized legacy notes-slide relationship to a missing notes master; it remains visible in the report and apply may not add any new structural error.
106
107 **Source import rule**: When `<source.pptx>` is inside the repo's `projects/` tree, `init` moves it into `<project>/sources/`. When it is outside `projects/`, `init` copies it into `<project>/sources/`. The mode is recorded in `project.json` as `source_import.mode`.
108
109 The `init` command also writes:
110
111 ```text
112 <project>/analysis/enhancement_plan.json
113 ```
114
115 **Hard rule**: Treat this draft plan as the first user-facing artifact. Do not generate notes, list voices, generate audio, or apply package patches before the user confirms which enhancements to add.
116
117 ---
118
119 ## 5. Enhancement Plan Confirmation
120
121 🚧 **GATE**: Step 4 complete; `<project>/analysis/enhancement_plan.json` exists.
122
123 If the project already existed or notes/audio coverage changed, refresh the draft:
124
125 ```bash
126 python3 skills/ppt-master/scripts/native_enhance_pptx.py plan "<project>"
127 ```
128
129 `plan` preserves module settings, refreshes coverage, and emits a
130 reconfirmation `draft`. It changes `audio.enabled: true` /
131 `notes.enabled: false` to `notes.enabled: true`; `validate`/`apply` reject the
132 old state. Audio remains unchecked until `validate` runs ffprobe. Supplied CLI
133 flags override.
134
135 Present the plan to the user before generating notes or audio:
136
137 | Module | Recommended default | Confirmation question |
138 |---|---|---|
139 | `notes` | Enabled; required whenever audio is enabled | Add/replace speaker notes generated from slide content? |
140 | `audio` | Enabled when user wants narration/video/autoplay | After notes are complete, generate one narration audio file per slide? |
141 | `timings` | Enabled with audio; 0.8s page-start floor and 0.4s page-tail padding | Set slide auto-advance from narration timing? |
142 | `transitions` | Enabled, `fade` 0.5s | Add page transitions? Which canonical native effect, Effect Options, and duration? |
143 | `delivery.check` | Always on, read-only | No confirmation required; review errors and advisories |
144
145 **⛔ BLOCKING**: Stop here and wait for explicit user confirmation. Do not generate notes, generate audio, or patch the PPTX until the user confirms the module plan.
146
147 **Hard dependency — notes before audio**: Confirming `audio.enabled: true`
148 also requires `notes.enabled: true`. If complete per-slide notes do not already
149 exist, run Step 6 and generate them before entering audio configuration or
150 audio generation. Never generate narration directly from slide text or bypass
151 the notes artifact.
152
153 **Transition/timing ownership**:
154
155 | Confirmed state | Enter transition | Slide advance |
156 |---|---|---|
157 | Transitions enabled with an effect | Replace with that exact effect and duration | Preserve unless timings is enabled |
158 | Transitions disabled with a non-`none` configured effect | Preserve the source effect, including unknown `AlternateContent` | Preserve unless timings is enabled |
159 | Explicit `none` | Remove the visual effect | Preserve, or write timing-only advance when timings is enabled |
160 | Timings enabled with audio | Keep the resolved enter policy | Use page-start lead-in plus audio duration plus page-tail padding; click disabled |
161 | Timings disabled | Apply the confirmed enter policy only | Use duration only to reject source auto-advance that would truncate narration; do not derive, add, or change `advTm` / `useTimings` |
162
163 The timing module's `narration_start_floor` and `narration_padding` are
164 independent optional values. When omitted, use `0.8` and `0.4` seconds
165 respectively. For a destination-page transition of `T` seconds, the
166 post-transition lead-in is
167 `max(0, narration_start_floor - T)`: narration does not begin during the
168 transition, and the transition duration itself remains unchanged. A start
169 floor of `0` means start immediately after the transition completes. A
170 preserved legacy transition that exposes only `spd` has no exact millisecond
171 duration; keep the full configured floor after that transition instead of
172 guessing a PowerPoint-specific duration. When timings are disabled, preserve
173 source `advTm`, but fail if it would advance before the delayed narration ends.
174
175 The confirmed `modules.transitions` object may include `effect_options` beside
176 an explicit canonical `effect`. Use
177 `pptx_animations.py --describe-transition <effect>` for its exact fields.
178 Old names remain accepted only when reading compatibility input; a newly
179 written plan stores the canonical effect and any implied options.
180
181 For explicit page selection or page-specific settings, add `slides` keyed by
182 the 1-based `index` in `analysis/slide_index.json`:
183
184 ```json
185 {
186 "modules": {
187 "transitions": {
188 "enabled": false,
189 "effect": "fade",
190 "duration": 0.5,
191 "apply_without_audio": false,
192 "slides": {
193 "2": {},
194 "3": {"duration": 0.8},
195 "4": {
196 "effect": "push",
197 "effect_options": {"direction": "left"}
198 },
199 "5": {"effect": "none"},
200 "6": {"effect": "preserve"}
201 }
202 }
203 }
204 }
205 ```
206
207 | Per-slide entry | Behavior |
208 |---|---|
209 | `{}` | Select the page and inherit the global effect/options/duration |
210 | Partial object | Inherit omitted global fields; a new explicit effect uses its own default options |
211 | `effect: none` | Remove the visual transition; timings remain independently owned |
212 | `effect: preserve` | Preserve the source visual transition; narration timing may still update advance |
213
214 A `slides` entry always selects that page. Without audio, enabled global effects
215 and explicit global `none` apply deck-wide; `apply_without_audio` is ignored.
216 With audio, the flag extends the global policy from narrated to all pages.
217 Disabled non-`none` effects preserve unlisted pages. Morph uses PowerPoint
218 automatic matching; this route does not rename native objects for deterministic
219 pairs.
220
221 **Hard rule — no silent downgrade**: a requested native effect must be written with its complete validated Effect Options. Unknown effects or inapplicable options fail; unknown source effects are preserved when the transition module is disabled.
222
223 After confirmation, update `<project>/analysis/enhancement_plan.json`:
224
225 ```json
226 {
227 "status": "confirmed"
228 }
229 ```
230
231 Also set each confirmed module's `enabled` value. Disabled modules must stay in the file with `enabled: false`, not be deleted.
232
233 ---
234
235 ## 6. Generate Notes From Existing Slides
236
237 🚧 **GATE**: Step 5 confirmed; `notes.enabled` is true; `<project>/sources/<source>.md` exists.
238
239 Read:
240
241 | File | Use |
242 |---|---|
243 | `<project>/sources/<source>.md` | Visible slide text, tables, extracted notes, image references |
244 | `<project>/analysis/slide_index.json` | Exact slide count and target note filenames |
245
246 Write:
247
248 ```text
249 <project>/notes/001.md
250 <project>/notes/002.md
251 ...
252 ```
253
254 **Hard rule**: Notes are spoken narration only. Do not include stage directions, implementation comments, timing labels, markdown tables, or visible-slide rewrite instructions.
255
256 **Hard rule**: Notes must be faithful to the slide. They may explain visible content, but must not add unsupported facts.
257
258 | Slide type | Notes length |
259 |---|---|
260 | Cover / section divider | 1-2 short sentences |
261 | Dense content page | 2-4 sentences |
262 | Chart / table page | Explain the reading path, then state the takeaway |
263 | Ending page | One concise close |
264
265 Run coverage check:
266
267 ```bash
268 python3 skills/ppt-master/scripts/native_enhance_pptx.py validate "<project>" --materials notes
269 ```
270
271 > Note: This keeps source/plan/transition/carrier checks but does not require
272 > audio. Missing/invalid notes return `2`; structural/semantic errors return
273 > `1`. Step 8 runs full validation after audio.
274
275 ---
276
277 ## 7. Shared Audio Configuration
278
279 🚧 **GATE**: Step 6 complete; `audio.enabled` is true.
280
281 Run [`generate-audio`](./stages/generate-audio.md) Steps 1–3. That shared stage exclusively owns language selection, provider/voice catalog lookup, recommendation rules, and the one-shot confirmation. Do not repeat or fork those rules here.
282
283 Record the confirmed config into `project.json`:
284
285 ```json
286 {
287 "audio": {
288 "provider": "edge",
289 "voice": "zh-CN-YunjianNeural",
290 "rate": "+0%"
291 }
292 }
293 ```
294
295 ---
296
297 ## 8. Run the Shared Audio Stage
298
299 🚧 **GATE**: Step 7 confirmed; complete non-empty notes files exist under
300 `<project>/notes/` for every slide.
301
302 Run [`generate-audio`](./stages/generate-audio.md) Step 4 with `<project>` and the confirmed values. Stop after audio generation; do not run its Generate-PPTX-only `svg_to_pptx.py --recorded-narration` integration. This route integrates audio through Step 9 instead.
303
304 **Naming contract**: Audio stems match note stems: `001.md` → `001.mp3`.
305
306 Validate:
307
308 ```bash
309 python3 skills/ppt-master/scripts/native_enhance_pptx.py validate "<project>"
310 ```
311
312 ---
313
314 ## 9. Apply V1 Enhancements
315
316 🚧 **GATE**: Enhancement plan is confirmed; notes are ready if requested; audio is ready if requested.
317
318 Run:
319
320 ```bash
321 python3 skills/ppt-master/scripts/native_enhance_pptx.py apply "<project>"
322 ```
323
324 Optional:
325
326 ```bash
327 python3 skills/ppt-master/scripts/native_enhance_pptx.py apply "<project>" \
328 --transition fade \
329 --transition-duration 0.5 \
330 --narration-start-floor 0.8 \
331 --narration-padding 0.4 \
332 --apply-transition-without-audio \
333 --overwrite
334 ```
335
336 `--apply-transition-without-audio` matters only with audio enabled: it extends
337 the global enter policy from narrated slides to all slides. Explicit slide
338 entries always opt in. Without audio, enabled transitions apply to every slide.
339
340 `apply` reruns the same source/readiness/plan checks as `validate`. Enabling
341 audio always requires every selected file to be decodable by ffprobe; enabling
342 timings additionally consumes that duration for `advTm`. It refuses
343 partial requested material, a changed source hash/slide roster, or a source
344 that already contains a `native_enhance_audio_*` carrier. New audio/poster
345 parts use collision-free names; an existing poster is reused only when its
346 bytes match the tool marker exactly. Output must be a new `.pptx` under
347 `exports/` or an external location; apply never overwrites either source or
348 writes into project control directories. Every apply attempt invalidates the
349 previous validation receipt, and a failed preflight records its current errors
350 instead of leaving stale passed evidence.
351
352 Patch scope:
353
354 | Package area | Append/update |
355 |---|---|
356 | `ppt/notesSlides/` | Notes slide parts |
357 | `ppt/notesMasters/` | Notes master only when needed |
358 | `ppt/slides/_rels/slideN.xml.rels` | Relationships for notes/audio/media/poster |
359 | `ppt/media/` | Narration audio and transparent poster |
360 | `ppt/slides/slideN.xml` | Hidden autoplay audio shape and page timing |
361 | `ppt/presProps.xml` | `showPr useTimings=1` only when this run writes automatic slide advance |
362 | `[Content_Types].xml` | Required content types |
363
364 **Hard rule**: Do not modify existing slide shapes, text bodies, images, chart
365 data, master/layout parts, hyperlink XML/relationships, or existing non-target
366 relationships.
367
368 Before publishing the candidate, apply validates transitions, timing/object
369 animation structure, ZIP integrity, unique parts, internal relationships,
370 slide count, and hidden-slide state. The narrowly allowed legacy missing
371 notes-master finding may remain exactly equivalent, but the candidate must not
372 introduce any structural error. Apply then writes both audits and the
373 introduced-error delta to `<project>/validation/report.json`.
374
375 ---
376
377 ## 10. Validate Output
378
379 Run read-back:
380
381 ```bash
382 python3 skills/ppt-master/scripts/source_to_md/ppt_to_md.py \
383 "<project>/exports/<source>_enhanced.pptx" \
384 -o "<project>/validation/readback.md"
385 ```
386
387 Check:
388
389 | Check | Expected |
390 |---|---|
391 | Slide count | Same as source |
392 | Visible content | No intentional changes |
393 | Notes | Present on intended slides |
394 | Audio media | Present under `ppt/media/` when generated |
395 | Auto-play | Narrated slides wait for the resolved page-start lead-in, then advance after audio duration plus page-tail padding |
396 | Transition | Requested effect remains exact; preserved `AlternateContent` keeps its primary and fallback branches |
397 | Timings disabled | Source `advTm` and package `useTimings` are not changed |
398 | Delivery check | No newly introduced structural errors; source baseline and font/media/hidden-slide advisories reviewed |
399
400 ```markdown
401 ## ✅ Native PPTX Enhancement V1 Complete
402
403 - [x] Project initialized at `<project>`
404 - [x] Source PPTX archived into `<project>/sources/`
405 - [x] Confirmed native enhancement modules applied
406 - [x] Enhanced PPTX exported to `<project>/exports/<file>.pptx`
407 - [x] Delivery postflight written to `<project>/validation/report.json`
408 - [x] Read-back validation written to `<project>/validation/readback.md`
409 ```
410
410 lines MARKDOWN