@liustack/pptwise 0.22.0 → 0.24.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 (42) hide show
  1. package/README.md +72 -41
  2. package/README.zh-CN.md +72 -41
  3. package/dist/{chunk-M35M4QUC.js → chunk-2CA3JRFR.js} +460 -499
  4. package/dist/chunk-2CA3JRFR.js.map +1 -0
  5. package/dist/{chunk-WL5KWYKS.js → chunk-G7WQ7KSP.js} +34800 -30625
  6. package/dist/chunk-G7WQ7KSP.js.map +1 -0
  7. package/dist/{chunk-VUOLBHD7.js → chunk-RQUKZYSH.js} +1 -1
  8. package/dist/{chunk-VUOLBHD7.js.map → chunk-RQUKZYSH.js.map} +1 -1
  9. package/dist/{chunk-3ZUKISTY.js → chunk-VEZGVYJS.js} +2 -2
  10. package/dist/cli.js +911 -462
  11. package/dist/cli.js.map +1 -1
  12. package/dist/index.d.ts +5320 -1534
  13. package/dist/index.js +15 -13
  14. package/dist/node.d.ts +1 -1
  15. package/dist/node.js +2 -2
  16. package/dist/{pixel-audit-H5K6JK3X.js → pixel-audit-M5Q5WCST.js} +4 -4
  17. package/dist/pixel-audit-M5Q5WCST.js.map +1 -0
  18. package/dist/{registry-C0GJH7ZT.d.ts → registry-D8bkC8ff.d.ts} +1 -1
  19. package/dsh/preview-tool.js +20 -17
  20. package/package.json +2 -1
  21. package/skills/pptwise/SKILL.md +133 -70
  22. package/skills/pptwise/SKILL.zh-CN.md +136 -73
  23. package/skills/pptwise/references/branding.md +34 -8
  24. package/skills/pptwise/references/branding.zh-CN.md +36 -8
  25. package/skills/pptwise/references/components.md +63 -33
  26. package/skills/pptwise/references/components.zh-CN.md +63 -33
  27. package/skills/pptwise/references/density.md +23 -9
  28. package/skills/pptwise/references/density.zh-CN.md +23 -9
  29. package/skills/pptwise/references/images.md +26 -13
  30. package/skills/pptwise/references/images.zh-CN.md +26 -13
  31. package/skills/pptwise/references/layouts.md +30 -26
  32. package/skills/pptwise/references/layouts.zh-CN.md +30 -26
  33. package/skills/pptwise/references/spec.md +143 -69
  34. package/skills/pptwise/references/spec.zh-CN.md +143 -69
  35. package/skills/pptwise/references/validate.md +33 -45
  36. package/skills/pptwise/references/validate.zh-CN.md +33 -45
  37. package/skills/pptwise/scripts/run.ps1 +1 -1
  38. package/skills/pptwise/scripts/run.sh +1 -1
  39. package/dist/chunk-M35M4QUC.js.map +0 -1
  40. package/dist/chunk-WL5KWYKS.js.map +0 -1
  41. package/dist/pixel-audit-H5K6JK3X.js.map +0 -1
  42. /package/dist/{chunk-3ZUKISTY.js.map → chunk-VEZGVYJS.js.map} +0 -0
@@ -1,107 +1,181 @@
1
- # Spec writing and page types
1
+ # Intent, narrative, theme binding, and spec
2
2
 
3
- Read this when writing `deck.spec.json`, choosing page types (`cover` / `chapter` / `content` / `ending`), or running the narrative interview.
3
+ Read this before creating `deck.spec.json`, choosing a theme, or handling a menu mismatch.
4
4
 
5
- ### Phase 1 Read the vocabulary (do this fresh every session)
5
+ The authoring chain is causal and one-way:
6
6
 
7
- ```bash
8
- pptwise schema # IR JSON Schema: the single source of truth
9
- pptwise schema --spec # deck spec schema
10
- pptwise narratives --json # named narrative presets (strategy/pacing/audience axes + theme recommendations)
11
- pptwise themes --json # built-in themes (id + label)
7
+ ```text
8
+ intent -> narrative -> theme binding -> spec with kind -> fill -> render
12
9
  ```
13
10
 
14
- Never write IR or a spec from memory of a previous session or from this file — the schema evolves and `schema`/`narratives`/`themes` output always wins.
15
-
16
- Also scan the workspace before asking anyone anything. Facts the files can answer are not questions:
17
-
18
- - An existing confirmed `deck.spec.json` already locks narrative, theme, and branding. Do not re-interview. Route follow-ups through phase 6.
19
- - A `theme.json`, a pinned `pptwise.config.json` theme, a user-named theme id, or a supplied `.thmx` / `.potx` / branded `.pptx` is a brand signal. Extract or honor it. Do not ask whether a template exists.
20
- - Request text that already names the audience, argument style, or density has derived that axis. Do not re-ask it.
21
-
22
- A brand signal answers what the deck should look like, never how it should argue. The full rule lives in `references/branding.md`.
11
+ ## Read live vocabularies
23
12
 
13
+ Run these at the start of every deck task:
24
14
 
25
- **Boundary-page rule — learn this now, it is the single most common mistake:** `chapter` and `ending` pages never render `components` or `footnote`. `cover` pages never render `footnote`. A `cover` may carry `components` only when its locked layout declares a slot for them. Today that is `verdict-index` (consulting), which reads the first `bullets` block as up to three numbered arguments. Every other cover layout still drops components. Put body content on a `content` page unless you are filling that consulting argument row. `validate` catches a stray field with `"<type>" slides do not render components/footnote — move this content to a content slide or remove it`.
26
-
27
- ```json
28
- // pages/closing.json — spec type "ending" — WRONG: components never render on an ending page
29
- { "components": [{ "type": "bullets", "items": ["Thank you", "Questions? sales@example.com"] }] }
15
+ ```bash
16
+ pptwise schema
17
+ pptwise schema --spec
18
+ pptwise narratives --json
19
+ pptwise themes --json
30
20
  ```
31
21
 
32
- ```json
33
- // pages/wrap-up.json — spec type "content", inserted right before the ending page — CORRECT
34
- { "components": [{ "type": "bullets", "items": ["Thank you", "Questions? sales@example.com"] }] }
35
- ```
22
+ The command output and workspace files outrank this guide. Scan for an existing `deck.spec.json`, deck-local `theme.json`, workspace `themes/`, and supplied Office brand files before asking questions.
36
23
 
37
- ```json
38
- // pages/closing.json — spec type "ending" — stays bare, nothing to move here
39
- {}
40
- ```
24
+ ## Intent and narrative
41
25
 
42
- `docs/deck-projects.md`'s boundary-page render surface table has the full per-type accounting.
26
+ Intent records who the deck is for, the result it should cause, whether it will be presented or circulated, and the available time. Narrative is the first decision made from that intent. It chooses argument strategy, pacing, and tone.
43
27
 
44
- ### Phase 2 Spec and confirm
28
+ When essential facts are missing and a user is present, ask one compact round:
45
29
 
46
- Propose and confirm before writing any page content.
30
+ 1. Who is the audience, and what should they decide, understand, or do afterward?
31
+ 2. Will someone present it, or must it stand alone? How much time is available?
32
+ 3. Should the argument lead with a conclusion, unfold as a story, teach a sequence, showcase an image or number, or read as a compact briefing?
33
+ 4. Should pages be dense, balanced, or spacious?
47
34
 
48
- - Lock a narrative package first: named preset (or explicit axes), theme id, branding posture, and a type-scale band (how large cover / chapter / speech headings render: `regular` omit/1, `display` 1.3, `hero` 1.5). This is a decision layer above theme, not a visual choice. Use the Narrative interview below when any axis is still unknown and a user is present. Do not silently pick a preset in that case.
49
- - Density (leave air vs pack the page) is decided in that interview (or derived). Follow the Sparse-page contract in `references/layouts.md` when you pin climax, quote, and evidence layouts and write `notes`. `pacing` does not grow a fourth value for this.
50
- - Theme id comes from the chosen narrative's `themeRecommendations` in `narratives --json` (or from `themes` output if none fit — a recommendation, never a constraint). If the interview's brand question returned a template, extract it first — see `references/branding.md`.
51
- - Write the confirmed `narrative`, `theme`, and `branding` into `deck.spec.json` as soon as the user agrees, before drafting any page. Do not hold them in the conversation and reconstruct them once pages exist.
52
- - Draft `deck.spec.json`: one entry per page (`id`, `type`, `heading`, optionally `beat`/`focus`/`summary`) — opens on `cover`, closes on `ending`, everything in between is `content` or `chapter`. Write `narrative` as a preset id string when the three axes match a preset exactly, otherwise as `{strategy, pacing, audience}`. Never write `{id, pacing}` mixed shapes. Omit `branding` by default. Write `branding: "full"` only when every content page needs the brand footer (and whenever `meta.confidentiality` is `confidential` or `restricted`). Do not invent a `typeScale` field on the spec — it does not exist. The band is a recommendation. Only a bare IR (spec skipped) may put `theme.style.shape.typeScale` on the IR itself.
53
- - Run `pptwise spec validate deck.spec.json` and fix whatever it reports until it prints `OK` — the hard gates (boundary pages, heading length, beat rotation, page count vs. pacing) all fire here, before a single page is written
54
- - Once `spec validate` prints `OK`, set a `seed` (any integer) in `deck.spec.json` for revision stability — write one now, or run `pptwise assemble` once in phase 3 and copy the `generated seed …` value it prints into the spec. Without a persisted seed, editing one page's heading later can reshuffle every other page's auto-picked layout
35
+ Use `pptwise narratives --json` to map the answer to a named preset or to explicit `strategy`, `pacing`, and `audience`. Do not infer the narrative from brand colors. Confirm this package before choosing a theme.
55
36
 
56
- **After the user confirms the validated spec, do not re-spec.** Restructuring a confirmed spec (reordering, retyping, dropping pages) silently wastes the user's review. If new information genuinely forces a change, say so and re-confirm first, then re-run `spec validate`.
37
+ ## Choose, create, and bind a theme
57
38
 
58
- ### Narrative interview (at most one round)
39
+ Theme is the second decision and must be settled before the spec. A theme is one complete file with style, a page menu, optional brand rules, `occasions`, and `identity`. The menu serves a deliberate subset of the 11 content kinds.
59
40
 
60
- When a user is present and any of audience, how it is told / strategy, or pacing is still unknown, relay the unresolved questions below in **one** message, then stop. Do not fill them in. Do not say "I'll assume". If the harness has a multiple-choice question tool, use it and pass the options verbatim.
41
+ Shortlist by occasion first and identity strength second. Compare two to four candidates with the fixed fitting-room sample:
61
42
 
62
- Open that message with one sentence naming the deck you are about to build: who it is for, how the argument is told, how full a page runs, which theme, footer on or off. Build that sentence only out of what the request and the workspace actually said. Where a signal is missing, say it is missing and name the ★ option as a default, not as a read of their situation. Never dress a default as a conclusion about their meeting. Keep axis names (`pyramid`, `spacious`, `executive`) out of that sentence and out of the options. Close the message with the three ways out: take it as-is, change an option, or say none of these fit.
43
+ ```bash
44
+ pptwise theme try consulting,swiss,memo
45
+ ```
63
46
 
64
- Skip the whole interview (zero questions) when: a confirmed spec already exists; the user said to skip questions / just generate / batch; there is nobody in this run at all; or the request already locks audience, argument style, and density. A complete brief still gets a one-line narrative package before you write the spec — that is the existing spec confirmation, not a second interview round.
47
+ `theme try` renders the same fixed sample deck under every candidate. It is the only place to compare themes without binding a deck. Choose from the images, not from names alone.
65
48
 
66
- Having no multiple-choice tool is not the same as having no user. In a plain conversation the user is present: the questions are the entire message and the stop still applies. Only a run with nobody in it (CI, batch, a script with no conversation) skips the pause, and there you still put the package, the reason, and what would change it in the visible output, then proceed on it. A later objection reopens the choice, and you re-run `spec validate` after changing it.
49
+ Create means copy. Prefer a workspace-owned theme even when the starting point is a factory preset:
67
50
 
68
- Skip only the derived axes. An empty workspace (no spec, no `theme.json`, no pinned config theme, nothing derivable in the request) asks Q1–Q4 together. A workspace with no brand signal asks Q4 even if it is not otherwise empty.
51
+ ```bash
52
+ pptwise theme new --from consulting --id acme-report
53
+ ```
54
+
55
+ With an Office theme or template, choose the donor menu by occasion, then extract colors and fonts into one complete v2 file:
69
56
 
70
- If the user skips an option, answers "anything", or replies off-list: fill the missing axis with the ★ default, name that fill in the recommendation reason, and do not follow up. "None of these fit" gets exactly one question back — which single axis is wrong — and nothing else. A veto of the package gets the prepared second candidate, not a new interview.
57
+ ```bash
58
+ pptwise brand extract corp.pptx -o themes/acme.theme.json --from consulting
59
+ ```
71
60
 
72
- <!-- Maintainer note, not an instruction to relay: Q1 earns its place today only through the lookup below and the tone of the prose. The `audience` axis still changes nothing on the render surface. If a future wave stops reading `audience` in that lookup, delete Q1 rather than keep asking a question whose answer changes no deliverable. -->
61
+ With an existing theme and a requested color change, fork it. The fork keeps the menu byte-identical and rederives the full palette:
73
62
 
74
- **Q1 — Who is this for?** `executive` board / VP (conclusion first) · `technical` engineers who will check the numbers · `customer` ★ buyers, users, a pitch room · `public` mixed or public.
63
+ ```bash
64
+ pptwise theme fork acme --primary '#0B5FFF' --id acme-blue
65
+ ```
75
66
 
76
- **Q2 How should it be told?** This is the reading of the deck. Q1 and Q3 only tune it. `talk-pyramid` ★ one conclusion per page (`pyramid`) · `talk-showcase` one image or number per page (`showcase`) · `read-brief` a packed brief, evidence first (`briefing`) · `teach` a training walkthrough (`instructional`). Derive `storytelling` from 年报 / brand-film / situation-to-resolution language. Do not add it as a fifth option.
67
+ Theme names resolve in three levels:
68
+
69
+ 1. The deck directory, including `theme.json` and named theme JSON files.
70
+ 2. A workspace `themes/` directory while walking upward from the deck.
71
+ 3. Factory presets.
72
+
73
+ Bind exactly one name by writing it to `deck.spec.json` as `theme`. To freeze a workspace theme for one deck, copy the complete file into the deck directory as `theme.json` without changing its id. Deck commands then load it automatically.
74
+
75
+ <!-- generated:begin themes -->
76
+ ### Complete factory preset catalog
77
+
78
+ This section is generated from the preset library and each preset menu. `identity` is the strength of the visual voice. `menu words` and the final column count content kinds only.
79
+
80
+ | id | label | occasions | identity | menu words | offered kinds |
81
+ | --- | --- | --- | --- | ---: | --- |
82
+ | `consulting` | Business Consulting | business | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
83
+ | `enterprise` | Enterprise | business, institutional | low | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
84
+ | `academic` | Academic | education | medium | 11 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `evidence`, `hierarchy` |
85
+ | `insight` | Financial Insight | finance | medium | 9 | `points`, `list`, `comparison`, `process`, `data`, `statement`, `quote`, `fact`, `hierarchy` |
86
+ | `campaign` | Marketing Campaign | marketing, event | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
87
+ | `classroom` | Classroom | education | medium | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
88
+ | `ink` | Ink Wash | culture | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
89
+ | `tech` | Tech | tech | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
90
+ | `runway` | Fashion Runway | fashion | high | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement` |
91
+ | `journal` | Editorial Journal | editorial | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
92
+ | `luxe` | Luxe | luxury, event | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
93
+ | `heritage` | Heritage | culture, luxury | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
94
+ | `pulse` | Health & Life Science | health | medium | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
95
+ | `terra` | Sustainability & ESG | sustainability | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
96
+ | `ember` | Startup Pitch | startup | high | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
97
+ | `vermilion` | Official Report | government, institutional | low | 9 | `points`, `list`, `comparison`, `process`, `data`, `statement`, `fact`, `evidence`, `hierarchy` |
98
+ | `crayon` | Kids Education | kids, education | high | 6 | `points`, `list`, `comparison`, `process`, `photo`, `statement` |
99
+ | `arena` | Esports & Entertainment | entertainment | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
100
+ | `museum` | Museum | museum, culture | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
101
+ | `stage` | Keynote Stage | keynote | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
102
+ | `lecture` | Lecture Hall | education | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
103
+ | `swiss` | Swiss Institutional | institutional | low | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
104
+ | `memo` | Decision Memo | business, institutional | low | 9 | `points`, `list`, `comparison`, `process`, `data`, `statement`, `quote`, `fact`, `hierarchy` |
105
+ | `playbill` | Playbill | event, entertainment | high | 9 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `hierarchy` |
106
+ <!-- generated:end themes -->
107
+
108
+ ## The 11 content kinds
109
+
110
+ `kind` states how a content page makes its point. It is required on every content page and absent from cover, chapter, and ending pages.
111
+
112
+ | `kind` | Use it when | Do not confuse it with |
113
+ | --- | --- | --- |
114
+ | `points` | Ordered reasoning advances step by step | `list`, whose items may be reordered |
115
+ | `list` | Peer items are displayed together | `points`, whose order carries the argument |
116
+ | `comparison` | Alternatives or sides need direct contrast | `hierarchy` for containment, `process` for direction |
117
+ | `process` | Steps, time, movement, or a closed cycle matter | `points` for an argument with no process relation |
118
+ | `data` | A set of numbers, chart, or table is the subject | `fact` for one number only |
119
+ | `photo` | The image itself is the content | `evidence`, where an exhibit supports a claim |
120
+ | `statement` | The deck author's own proposition gets a full page | `quote` for another speaker's words |
121
+ | `quote` | Words are attributed to another speaker or source | `statement` for the deck author's own voice |
122
+ | `fact` | One number carries the whole message | `data` for numeric structure across a set |
123
+ | `evidence` | One assertion is paired with one supporting exhibit | `photo` when the image stands alone |
124
+ | `hierarchy` | The page explains containment, levels, or composition | `process` for sequence, `comparison` for two sides |
125
+
126
+ Four boundaries settle most ambiguous cases:
127
+
128
+ - `statement`, `quote`, `fact`, and `evidence` differ by the speaking subject: our proposition, another person's words, one number, or a claim with an exhibit.
129
+ - `data` exposes structure across several values. `fact` creates impact with one value.
130
+ - `points` has progression. `list` can be reordered.
131
+ - `photo` makes the image the message. `evidence` makes the image serve the assertion.
132
+
133
+ ## Write the spec
134
+
135
+ A valid deck spec opens with `cover`, closes with `ending`, and uses `content` or `chapter` inside. Every page has `id`, `type`, and `heading`. Content pages additionally require `kind`. `focus` may name a preferred component type. `summary` is a short content anchor for the fill step.
77
136
 
78
- **Q3 — Sparse or packed?** `spacious` ★ leave air, few words per page · `balanced` a normal mix · `dense` pack the evidence, the page stands alone.
137
+ ```json
138
+ {
139
+ "version": "1",
140
+ "filename": "q3-review.pptx",
141
+ "narrative": "boardroom-report",
142
+ "theme": "acme-report",
143
+ "meta": { "organization": "Acme", "date": "2026 Q3" },
144
+ "pages": [
145
+ { "id": "cover", "type": "cover", "heading": "Q3 operating review" },
146
+ { "id": "decision", "type": "content", "kind": "points", "heading": "Two actions protect the annual target" },
147
+ { "id": "options", "type": "content", "kind": "comparison", "heading": "The focused plan wins on payback" },
148
+ { "id": "economics", "type": "content", "kind": "data", "heading": "Margin recovers before year end" },
149
+ { "id": "delivery", "type": "content", "kind": "process", "heading": "Three releases close the gap" },
150
+ { "id": "close", "type": "ending", "heading": "Approve the focused plan" }
151
+ ]
152
+ }
153
+ ```
79
154
 
80
- **Q4 Brand template?** Only when there is no brand signal. `extract` yes, they will hand over a `.thmx` / `.potx` / branded `.pptx` · `builtin` no, use a built-in theme · `later` built-in now, brand later (treat as `builtin`, do not open a second round). Whether a `theme.json` is already in the workspace is something you check, never something you ask.
155
+ The spec contains no page geometry or render selection state. Do not add retired author fields. Page files later contain only fillable content and never repeat `type`, `kind`, or `heading`.
81
156
 
82
- End that message with this block, verbatim, one line per axis, a derived value filled in and every unresolved axis left as `?`:
157
+ Run:
83
158
 
159
+ ```bash
160
+ pptwise spec validate deck.spec.json
84
161
  ```
85
- NARRATIVE_INTERVIEW
86
- audience: ?
87
- tell: ?
88
- pacing: ?
89
- brand: ?
90
- ```
91
162
 
92
- The block is the gate, not your self-discipline: while any line still reads `?`, you may not create or edit `deck.spec.json`, a page file, or a bare IR. Only the user's reply clears a `?` — or, once they have replied, the ★ default for an axis they left open. In a run with nobody in it, fill every line yourself and print the block with `(no user in this run)` on the first line, so the choice is visible and reversible.
163
+ Fix hard errors until the command prints `OK`. Page count is checked against pacing. Three or more consecutive content pages with the same `kind` produce an editorial warning.
164
+
165
+ ## Menu mismatch handling
93
166
 
94
- After the reply, emit one package and one backup, one sentence of reason, one clause for what would change it, then wait for confirmation:
167
+ If the spec requests a `kind` that the bound theme does not offer, validation fails and lists the available kinds. Handle it in this order:
95
168
 
96
- `recommend: <preset-or-axes> × <theme> × branding omit|full × typeScale regular|display|hero`
97
- `what would change it: <one clause>` — most often: this will be forwarded without a speaker, so put the extra words in notes, or recommend a PDF instead of packing the slide.
169
+ 1. Recheck the page's semantic posture. Change `kind` only when another offered word is genuinely correct.
170
+ 2. If the page intent is fixed, choose or create a theme whose menu serves it.
171
+ 3. If content was already filled, return to the theme layer. Keep useful facts, data, images, and copy fragments, then rewrite the spec and page files for the new menu.
98
172
 
99
- Lookup (theme = first `themeRecommendations` entry from `narratives --json` for that preset, or for the nearest preset when writing axes). Omit the field by default. Write `"full"` when `meta.confidentiality` is `confidential` or `restricted`, or every content page needs the brand footer. `customer` + `talk-pyramid` + `spacious` → `pitch` / omit / display. `executive` + `talk-pyramid` + `spacious` → `boardroom-report` / omit / display. `customer` + `talk-showcase` + `spacious` → `product-launch` / omit / display. `technical` + `teach` + `balanced` → `training` / omit / regular. `technical` + `read-brief` + `dense` → `weekly-brief` / omit / regular. `executive` + `read-brief` + `dense` → axes `{pyramid, dense, executive}` / omit / regular, theme from `boardroom-report`. `public` + storytelling + `balanced` → `annual-review` / omit / regular. Else write the axes object and take the nearest preset's theme list: `pyramid`+`executive` → `boardroom-report`, `pyramid`+`customer` → `pitch`, `showcase` → `product-launch`, `instructional` → `training`, `briefing`+`dense` → `weekly-brief`, `storytelling` → `annual-review`, else `general`.
173
+ Do not force a nearby word merely to pass validation. A menu gap is a theme decision, not missing geometry.
100
174
 
101
- Type-scale band: `regular` when `dense` or `balanced`. `display` when `spacious`. `hero` only on a repaint that switches the theme to `stage`. Do not retarget a boardroom deck to `stage` just to enlarge titles. Do not write `typeScale` onto `deck.spec.json`. Do not edit a repo-root `pptwise.config.json` for one deck. On a bare IR (spec skipped) a non-`regular` band may be written as `theme.style.shape.typeScale` 1.3 or 1.5.
175
+ ## Rebinding after work starts
102
176
 
103
- The second candidate ships with the package, prepared in advance, and it has to differ in mechanism: flip density (`spacious` ↔ `dense`, type-scale follows), or flip what leads the argument (`pitch` `product-launch`, `training` ↔ the same material as a dense handout). The same three axes in a different theme is a repaint, not a candidate — offer that only when the user rejected the look, and say the narrative did not move. `stage` × `hero` is the repaint for a showcase that wanted bigger titles. Do not flip all three axes at once.
177
+ A color fork with the same menu may replace the bound theme. Update the bound name and rerun spec validation, assemble, validate, audit, and render.
104
178
 
105
- This interview settles the three narrative axes, not whether the request should be a deck at all. If that larger question is open, say so plainly and let the user answer it before you spec.
179
+ A theme with a different menu is not a repaint. It requires restarting at the theme layer and rewriting the spec. The CLI compares normalized menus directly and refuses an in-place different-menu rebind.
106
180
 
107
- A very small deck may still skip the spec file and write a single IR. It may not skip this interview when axes are unknown. Write the same decisions onto the IR's `narrative` / `theme` / `branding`.
181
+ A very small deck may use one IR file instead of a deck project. It still follows the same chain. Its top-level `theme.id` is the binding, and every content slide still requires explicit `kind`.
@@ -3,110 +3,184 @@ summary: 'skills/pptwise/references/spec.md 的中文阅读镜像'
3
3
  mirror_of: skills/pptwise/references/spec.md
4
4
  ---
5
5
 
6
- # Spec 写法与页型
6
+ # 意图、叙事、主题绑定与 spec
7
7
 
8
- 何时读:写 `deck.spec.json`、选页型(`cover` / `chapter` / `content` / `ending`)、或做叙事访谈时。
8
+ 何时读:创建 `deck.spec.json`、选择主题、或处理菜单不匹配时。
9
9
 
10
- ### Phase 1 — 读词汇表(每个 session 都要重新读一遍)
10
+ 作者链条是因果单向的:
11
11
 
12
- ```bash
13
- pptwise schema # IR JSON Schema: the single source of truth
14
- pptwise schema --spec # deck spec schema
15
- pptwise narratives --json # named narrative presets (strategy/pacing/audience axes + theme recommendations)
16
- pptwise themes --json # built-in themes (id + label)
12
+ ```text
13
+ 意图 -> 叙事 -> 主题绑定 -> kind spec -> 填充 -> 渲染
17
14
  ```
18
15
 
19
- 永远不要凭上一个 session 的记忆、或凭这份文件本身的记忆去写 IR 或 spec——schema 会演进,`schema`/`narratives`/`themes` 的实际输出永远优先。
20
-
21
- 动手问人之前,先扫工作区。文件能回答的事实不要问人:
22
-
23
- - 已有确认过的 `deck.spec.json` 已经锁死 narrative、theme、品牌框。不要重做访谈。后续请求走阶段六
24
- - 已有 `theme.json`、项目 `pptwise.config.json` 钉死的 theme、用户点名的 theme id、或用户递来的 `.thmx` / `.potx` / 带品牌 `.pptx`,都是品牌信号。抽取或沿用。不要再问有没有模板
25
- - 请求原文已经点名受众、论证方式或疏密,这一轴就算推导出来了。不要再问
26
-
27
- 品牌信号回答的是这份 deck 长什么样,从来不回答它该怎么论证。完整规则在 `references/branding.md`。
16
+ ## 读取现场词汇
28
17
 
18
+ 每个 deck 任务开始时运行:
29
19
 
30
- **边界页规则——现在就记住,这是最常见的错误:** `chapter` 和 `ending` 永远不渲染 `components` 或 `footnote`。`cover` 永远不渲染 `footnote`。封面只有在锁定版式声明了对应槽位时才能带 `components`。今天这只发生在 `verdict-index`(consulting):它读第一个 `bullets` 块,画成最多三条编号论据。其余封面版式仍会丢掉 components。正文放到 `content` 页,除非你在填 consulting 封面那三列论据。`validate` 会用 `"<type>" slides do not render components/footnote — move this content to a content slide or remove it` 抓住多余字段。
31
-
32
- ```json
33
- // pages/closing.json — spec type "ending" — WRONG: components never render on an ending page
34
- { "components": [{ "type": "bullets", "items": ["Thank you", "Questions? sales@example.com"] }] }
20
+ ```bash
21
+ pptwise schema
22
+ pptwise schema --spec
23
+ pptwise narratives --json
24
+ pptwise themes --json
35
25
  ```
36
26
 
37
- ```json
38
- // pages/wrap-up.json — spec type "content", inserted right before the ending page — CORRECT
39
- { "components": [{ "type": "bullets", "items": ["Thank you", "Questions? sales@example.com"] }] }
40
- ```
27
+ 命令输出与工作区文件优先于本指南。提问前先找已有 `deck.spec.json`、deck 内 `theme.json`、工作区 `themes/`,以及用户递来的 Office 品牌文件。
41
28
 
42
- ```json
43
- // pages/closing.json — spec type "ending" — stays bare, nothing to move here
44
- {}
45
- ```
29
+ ## 意图与叙事
46
30
 
47
- `docs/deck-projects.md` 里的边界页渲染面表(boundary-page render surface table)有按页型划分的完整对照。
31
+ 意图记录讲给谁、要促成什么结果、现场讲述还是传阅、可用时长。叙事是根据意图作出的第一个决定,确定论证方式、节奏与语气。
48
32
 
49
- ### Phase 2 — 定 spec 并确认
33
+ 用户在场且仍缺关键事实时,只问一轮简洁问题:
50
34
 
51
- 写任何页面内容之前,先提议并确认。
35
+ 1. 受众是谁,结束后应该决定、理解或做什么?
36
+ 2. 会有人现场讲,还是文件必须独立读懂?有多少时间?
37
+ 3. 论证应该结论先行、按故事展开、分步教学、突出一个画面或数字,还是写成紧凑简报?
38
+ 4. 页面应该密、均衡,还是留白?
52
39
 
53
- - 先锁定叙事包:具名预设(或显式三轴)、theme id、品牌框姿态、以及 typeScale 档(封面 / 章 / 演讲页标题有多大:`regular` 省略/1,`display` 1.3,`hero` 1.5)。这是位于 theme 之上的一层决策,不是视觉选择。任一轴仍未知且用户在场时,走下方「叙事访谈」。这种情况下不要自己静默挑一个预设
54
- - 疏密(留白还是铺满)在访谈里判定(或从请求推导)。钉高潮页、金句页、证据页版式和写 `notes` 时走 `references/layouts.md` 的稀排页合同。`pacing` 不会为此多出第四档
55
- - 再定 theme id:从 `narratives --json` 里该预设的 `themeRecommendations` 取(如果都不合适,就从 `themes` 输出里挑一个贴合这份 deck 调性的。这只是推荐,从不构成约束)。访谈的品牌问如果返回了模板,先抽成自定义 theme,见 `references/branding.md`
56
- - 用户一点头,立刻把确认下来的 `narrative`、`theme`、`branding` 写进 `deck.spec.json`,再起草任何一页。不要把答案留在对话里,等页面写完再凭记忆补
57
- - 起草 `deck.spec.json`:每页一条记录(`id`、`type`、`heading`,可选加 `beat`/`focus`/`summary`)——以 `cover` 开篇,以 `ending` 收尾,中间的每一页都是 `content` 或 `chapter`。三轴与某个预设完全相等时,`narrative` 写预设 id 字符串,否则写 `{strategy, pacing, audience}`。不要写 `{id, pacing}` 这种混形。默认省略 `branding`。只有每一页内容页都需要品牌页脚时才写 `branding: "full"`(`meta.confidentiality` 为 `confidential` 或 `restricted` 时同样写 `"full"`)。不要在 spec 上发明 `typeScale` 字段,那个字段不存在。档是推荐。只有跳过 spec、直接写 IR 时,才允许把 `theme.style.shape.typeScale` 写进 IR
58
- - 跑 `pptwise spec validate deck.spec.json`,把它报出的问题都修掉,直到打印 `OK`——边界页、标题长度、beat 轮换、页数是否匹配 pacing 这些硬门都在这一步触发,早于任何一页正文的写作
59
- - `spec validate` 打印 `OK` 之后,在 `deck.spec.json` 里设一个 `seed`(任意整数)以保证修订稳定——现在就写一个,或者在阶段三跑一次 `pptwise assemble`,把它打印出的 `generated seed …` 值抄进 spec。没有固化的 seed,之后改一页的标题就可能打乱其余每一页自动选出的 layout
40
+ `pptwise narratives --json` 把答案映射成具名预设,或显式的 `strategy`、`pacing`、`audience`。不要从品牌配色推导叙事。先确认这份叙事包,再选择主题。
60
41
 
61
- **用户确认过校验通过的 spec 之后,不要再重新定 spec。** 改动一份已确认的 spec(调整顺序、改页型、删页)会悄悄浪费用户已经做过的审阅。如果确有新信息迫使必须改动,先说明理由并重新取得确认,再重新跑一次 `spec validate`。
42
+ ## 选择、创建并绑定主题
62
43
 
63
- ### 叙事访谈(最多一轮)
44
+ 主题是第二个决定,必须早于 spec。主题是一个完整文件,包含样式、页面菜单、可选品牌规则、`occasions` 与 `identity`。菜单只服务 11 种内容页讲法中的一个明确子集。
64
45
 
65
- 用户在场,且受众、怎么讲 / strategy、pacing 任一轴仍未知时,把所有未决的问放进**一条**消息转达给人,然后停。不要自己填。不要说「我按常见情况先选」。宿主有选择题工具就用它,选项原文照传。
46
+ 先按场合筛选,再按视觉个性强度筛选。用固定样张比较 2 4 个候选:
66
47
 
67
- 这条消息开头先写一句话,说出你打算建的这份 deck:给谁、论证怎么讲、每页多满、哪个主题、页脚开还是关。这句话只能用请求和工作区真说过的东西搭。缺信号的地方就说缺,并把 ★ 点明成默认,不是对用户处境的读数。不要把默认打扮成结论。这句话和选项里都不要出现 `pyramid`、`spacious`、`executive` 这类轴名。结尾给三条出路:不改就说「就这样」,要改就挑选项,或者说「都不对」。
48
+ ```bash
49
+ pptwise theme try consulting,swiss,memo
50
+ ```
68
51
 
69
- 整段跳过访谈(零问):已有确认过的 spec。用户说跳过问题、直接生成或批量。这一轮里根本没有人。请求已经同时锁定受众、论证方式、疏密。完整 brief 仍要在写 spec 之前甩一句叙事包。那是原来的 spec 确认,不是第二轮访谈。
52
+ `theme try` 用每个候选渲染同一份固定样张 deck。只有这里会在不绑定 deck 的情况下比较主题。按图选,不要只看名字。
70
53
 
71
- 没有选择题工具,不等于没有用户。普通文本对话里用户是在场的:问题就是整条消息,停照旧。只有真的没有人的运行(CI、批量、无对话脚本)才免掉这次停顿,而且仍要把包、一句理由、一句改口条件写进可见输出,然后按包继续。事后用户任何一条反对都重开这个决定,改完重跑 `spec validate`。
54
+ 创建就是拷贝。即使从出厂预设开始,也优先创建工作区自有主题:
72
55
 
73
- 只跳过已推导的轴。空 workspace(无 spec、无 `theme.json`、无钉死的 config theme、请求里什么都推不出)把 Q1–Q4 一起问。没有品牌信号的工作区即使别的文件很多,也要问 Q4。
56
+ ```bash
57
+ pptwise theme new --from consulting --id acme-report
58
+ ```
59
+
60
+ 有 Office 主题或模板时,先按场合选择菜单来源,再把配色与字体抽进一个完整的 v2 文件:
74
61
 
75
- 用户跳过某选项、说「都行」、或回了表外的话:用 ★ 默认补齐,在推荐理由里写明补了哪一轴,不要追问。用户说「都不对」:只回一句「三轴里哪一根不对」,别的都不问。用户否决推荐包:抛出事先准备的第二候选,不要重开访谈。
62
+ ```bash
63
+ pptwise brand extract corp.pptx -o themes/acme.theme.json --from consulting
64
+ ```
76
65
 
77
- <!-- 维护者注记,不要转达给用户:Q1 今天的价值全部来自下面那张查表和正文口吻,`audience` 轴在渲染面上仍然什么都不做。如果将来查表不再读 `audience`,应该删掉 Q1,而不是留着一个答案改变不了交付物的问题。 -->
66
+ 已有主题要改色时,fork 它。fork 保持菜单逐字节相同,并重新派生整套配色:
78
67
 
79
- **Q1 这页是讲给谁的?** `executive` 董事会 / 高管(结论先行) · `technical` 会核对数字的技术同事 · `customer` ★ 客户、买家、路演现场 · `public` 公开或不特定。
68
+ ```bash
69
+ pptwise theme fork acme --primary '#0B5FFF' --id acme-blue
70
+ ```
80
71
 
81
- **Q2 你想怎么讲这件事?** 这一问才是这份 deck 的读法,Q1 和 Q3 只是把它调准。`talk-pyramid` ★ 一页一个结论(`pyramid`) · `talk-showcase` 一页一个画面或数字(`showcase`) · `read-brief` 一页铺满证据(`briefing`) · `teach` 按步骤教(`instructional`)。年报 / 品牌片 / 情境到解决的说法直接推导 `storytelling`,不要把它加成第五选项。
72
+ 主题名按三级解析:
73
+
74
+ 1. deck 目录,包括 `theme.json` 与具名主题 JSON。
75
+ 2. 从 deck 向上查找的工作区 `themes/`。
76
+ 3. 出厂预设。
77
+
78
+ 在 `deck.spec.json` 的 `theme` 中写入唯一名称完成绑定。要把工作区主题冻结给单个 deck,保持 id 不变,把完整文件复制到 deck 目录并命名为 `theme.json`。之后 deck 命令会自动装载。
79
+
80
+ <!-- generated:begin themes -->
81
+ ### 出厂预设全量表
82
+
83
+ 本段由预设库及每个预设的菜单生成。`identity` 表示视觉个性强度。`菜单词数` 与最后一列都只计算内容页讲法。
84
+
85
+ | id | label | occasions | identity | 菜单词数 | 提供的 kind |
86
+ | --- | --- | --- | --- | ---: | --- |
87
+ | `consulting` | Business Consulting | business | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
88
+ | `enterprise` | Enterprise | business, institutional | low | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
89
+ | `academic` | Academic | education | medium | 11 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `evidence`, `hierarchy` |
90
+ | `insight` | Financial Insight | finance | medium | 9 | `points`, `list`, `comparison`, `process`, `data`, `statement`, `quote`, `fact`, `hierarchy` |
91
+ | `campaign` | Marketing Campaign | marketing, event | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
92
+ | `classroom` | Classroom | education | medium | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
93
+ | `ink` | Ink Wash | culture | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
94
+ | `tech` | Tech | tech | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
95
+ | `runway` | Fashion Runway | fashion | high | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement` |
96
+ | `journal` | Editorial Journal | editorial | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
97
+ | `luxe` | Luxe | luxury, event | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
98
+ | `heritage` | Heritage | culture, luxury | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
99
+ | `pulse` | Health & Life Science | health | medium | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
100
+ | `terra` | Sustainability & ESG | sustainability | medium | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
101
+ | `ember` | Startup Pitch | startup | high | 7 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `hierarchy` |
102
+ | `vermilion` | Official Report | government, institutional | low | 9 | `points`, `list`, `comparison`, `process`, `data`, `statement`, `fact`, `evidence`, `hierarchy` |
103
+ | `crayon` | Kids Education | kids, education | high | 6 | `points`, `list`, `comparison`, `process`, `photo`, `statement` |
104
+ | `arena` | Esports & Entertainment | entertainment | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
105
+ | `museum` | Museum | museum, culture | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
106
+ | `stage` | Keynote Stage | keynote | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `quote`, `fact`, `hierarchy` |
107
+ | `lecture` | Lecture Hall | education | high | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
108
+ | `swiss` | Swiss Institutional | institutional | low | 10 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `evidence`, `hierarchy` |
109
+ | `memo` | Decision Memo | business, institutional | low | 9 | `points`, `list`, `comparison`, `process`, `data`, `statement`, `quote`, `fact`, `hierarchy` |
110
+ | `playbill` | Playbill | event, entertainment | high | 9 | `points`, `list`, `comparison`, `process`, `data`, `photo`, `statement`, `fact`, `hierarchy` |
111
+ <!-- generated:end themes -->
112
+
113
+ ## 11 种内容页讲法
114
+
115
+ `kind` 说明内容页怎样表达观点。每张内容页必填。封面、章节与结尾不写。
116
+
117
+ | `kind` | 何时使用 | 不要混淆 |
118
+ | --- | --- | --- |
119
+ | `points` | 论证按顺序逐步推进 | `list` 的条目可以换序 |
120
+ | `list` | 一组并列项一起陈列 | `points` 的顺序承载论证 |
121
+ | `comparison` | 方案或两边需要直接对照 | 包含关系用 `hierarchy`,方向关系用 `process` |
122
+ | `process` | 步骤、时间、运动或闭环很重要 | 没有流程关系的递进论证用 `points` |
123
+ | `data` | 一组数字、图表或表格是主角 | 只有一个数字时用 `fact` |
124
+ | `photo` | 画面本身就是内容 | 展品服务断言时用 `evidence` |
125
+ | `statement` | 作者自己的一句话立论占满一页 | 借别人之口用 `quote` |
126
+ | `quote` | 文字归属于另一位说话者或来源 | 作者自己的话用 `statement` |
127
+ | `fact` | 一个数字承担整页信息 | 多个数字之间的结构用 `data` |
128
+ | `evidence` | 一个断言配一件支持它的展品 | 图片独立成义时用 `photo` |
129
+ | `hierarchy` | 页面解释包含、层级或组成 | 先后关系用 `process`,两边对照用 `comparison` |
130
+
131
+ 四条边界能解决大多数歧义:
132
+
133
+ - `statement`、`quote`、`fact`、`evidence` 的区别在说话主体,分别是自己的立论、别人的话、一个数字、断言加展品。
134
+ - `data` 展示多个值之间的结构。`fact` 用一个值制造冲击。
135
+ - `points` 有递进。`list` 可换序。
136
+ - `photo` 让画面成为信息。`evidence` 让画面服务断言。
137
+
138
+ ## 编写 spec
139
+
140
+ 合法 spec 以 `cover` 开头,以 `ending` 结束,中间使用 `content` 或 `chapter`。每页都有 `id`、`type`、`heading`。内容页还必须有 `kind`。`focus` 可以点名偏好的组件类型。`summary` 是填充步骤使用的简短内容锚点。
82
141
 
83
- **Q3 页上要留白还是铺满?** `spacious` ★ 留白,一页少字 · `balanced` 普通疏密 · `dense` 铺满证据,页自己把话说完。
142
+ ```json
143
+ {
144
+ "version": "1",
145
+ "filename": "q3-review.pptx",
146
+ "narrative": "boardroom-report",
147
+ "theme": "acme-report",
148
+ "meta": { "organization": "Acme", "date": "2026 Q3" },
149
+ "pages": [
150
+ { "id": "cover", "type": "cover", "heading": "Q3 经营复盘" },
151
+ { "id": "decision", "type": "content", "kind": "points", "heading": "两项动作守住全年目标" },
152
+ { "id": "options", "type": "content", "kind": "comparison", "heading": "聚焦方案回报更快" },
153
+ { "id": "economics", "type": "content", "kind": "data", "heading": "利润率在年末前恢复" },
154
+ { "id": "delivery", "type": "content", "kind": "process", "heading": "三次发布补齐缺口" },
155
+ { "id": "close", "type": "ending", "heading": "批准聚焦方案" }
156
+ ]
157
+ }
158
+ ```
84
159
 
85
- **Q4 有没有公司模板可以抽成主题?** 仅当没有品牌信号时问。`extract` 有,用户会给出 `.thmx` / `.potx` / 带品牌 `.pptx` · `builtin` ★ 没有,用内置主题 · `later` 先用内置,稍后补(当作 `builtin`,不开第二轮)。工作区里有没有 `theme.json`,是自己查的事,永远不问。
160
+ spec 不含页面几何或渲染选择状态。不要加入已退役的作者字段。后续页面文件只装可填内容,不重复 `type`、`kind` `heading`。
86
161
 
87
- 这条消息的结尾原样附上下面这个块,一轴一行,已推导的轴填上值,未决的轴留 `?`:
162
+ 运行:
88
163
 
164
+ ```bash
165
+ pptwise spec validate deck.spec.json
89
166
  ```
90
- NARRATIVE_INTERVIEW
91
- audience: ?
92
- tell: ?
93
- pacing: ?
94
- brand: ?
95
- ```
96
167
 
97
- 这个块就是闸,不靠自觉:只要还有一行是 `?`,就不许新建或修改 `deck.spec.json`、页面文件或裸 IR。清掉一个 `?` 只有两条路:用户回答,或者用户已经回复、只是留空了某一轴,那一轴用 ★ 默认补。真的没有人的运行里,自己把每一行填满,并在块的第一行标上 `(no user in this run)`,让这个选择可见、可推翻。
168
+ 修完硬错误,直到命令打印 `OK`。页数会按 `pacing` 检查。连续三张或更多内容页使用同一个 `kind` 时,会产生编辑提示。
169
+
170
+ ## 菜单不匹配怎么处理
98
171
 
99
- 用户回复之后,立刻给一个推荐包和一个第二候选,一句理由,一句改口条件,然后等确认:
172
+ spec 请求了绑定主题没有提供的 `kind` 时,校验会失败并列出可用词。按这个顺序处理:
100
173
 
101
- `推荐:<预设或三轴> × <theme> × branding 省略|full × typeScale regular|display|hero`
102
- `改口条件:<一句>`。最常见的一条:这份会在没有主讲人的情况下被转发,把多出来的字写进 notes,或者建议改用 PDF,不要把幻灯片塞满。
174
+ 1. 重查页面的语义姿势。只有另一个可用词确实正确时才改 `kind`。
175
+ 2. 页面意图不能变时,选择或创建菜单能服务它的主题。
176
+ 3. 已经填过内容时,回到主题层。保留有用的事实、数据、图片与文案片段,再按新菜单重写 spec 与页面文件。
103
177
 
104
- 查表(theme = `narratives --json` 里该预设 `themeRecommendations` 的第一项。写三轴对象时改取最靠近预设的名单)。默认省略该字段。`meta.confidentiality` 为 `confidential` 或 `restricted`,或每一页内容页都需要品牌页脚时,才写 `"full"`。`customer` + `talk-pyramid` + `spacious` → `pitch` / 省略 / display。`executive` + `talk-pyramid` + `spacious` → `boardroom-report` / 省略 / display。`customer` + `talk-showcase` + `spacious` → `product-launch` / 省略 / display。`technical` + `teach` + `balanced` → `training` / 省略 / regular。`technical` + `read-brief` + `dense` → `weekly-brief` / 省略 / regular。`executive` + `read-brief` + `dense` → 三轴 `{pyramid, dense, executive}` / 省略 / regular,theme 取 `boardroom-report`。`public` + storytelling + `balanced` → `annual-review` / 省略 / regular。其余写三轴对象,最靠近预设:`pyramid`+`executive` → `boardroom-report`,`pyramid`+`customer` → `pitch`,`showcase` → `product-launch`,`instructional` → `training`,`briefing`+`dense` → `weekly-brief`,`storytelling` → `annual-review`,否则 `general`。
178
+ 不要为了通过校验硬套一个相近词。菜单缺口是主题决策,不是几何缺口。
105
179
 
106
- typeScale 档:`dense` 或 `balanced` 用 `regular`。`spacious` 用 `display`。`hero` 只出现在把 theme 换成 `stage` 的那种换皮上。不要为了把标题加大,把董事会 deck 改成 `stage`。不要在 `deck.spec.json` 上写 `typeScale`。不要为了一个 deck 去改仓库根上的 `pptwise.config.json`。跳过 spec、直接写 IR 时,非 `regular` 的档可以写成 `theme.style.shape.typeScale` 1.3 或 1.5。
180
+ ## 开工后的换绑
107
181
 
108
- 第二候选跟着推荐包一起抛,事先准备,而且必须在机制上不同:翻疏密(`spacious` `dense`,type-scale 跟着翻),或者换由什么领头论证(`pitch` `product-launch`,`training` ↔ 同样内容的密页讲义)。同样三根轴换个主题是换皮,不算候选,只在用户否的是皮时才给,并说清叙事没动。showcase 想要更大标题时,`stage` × `hero` 属于这种换皮。不要三轴一起翻。
182
+ 菜单相同的配色 fork 可以替换绑定主题。更新绑定名称,再重跑 spec validate、assemble、validate、audit render。
109
183
 
110
- 这一轮只定三根叙事轴,不负责判断这件事该不该做成 deck。那个更大的问题还开着,就直说,让用户先答,再定 spec。
184
+ 菜单不同的主题不是换色,必须回到主题层重写 spec。CLI 会直接比较规范化后的菜单,并拒绝流程内换绑到不同菜单。
111
185
 
112
- 很小的 deck 仍可跳过 spec 文件、直接写一份 IR。轴未知时不可跳过这场访谈。把同样的决策写到 IR `narrative` / `theme` / `branding` 上。
186
+ 很小的 deck 可以使用单个 IR 文件而不是 deck 项目。它仍遵循同一条链。顶层 `theme.id` 是绑定,每张内容页仍必须显式写 `kind`。