skilldrop-cli 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -314,7 +314,7 @@ Designing the agentic systems themselves — the loops, orchestrations, and budg
314
314
  |---|---|
315
315
  | [`audience-profile`](skills/audience-profile/SKILL.md) | Translate an audience type (exec, board, technical, sales, investor, internal, partner, customer) into structural rules — slide count, density, tone, must-have sections. Reusable input for the next three skills. |
316
316
  | [`slide-outliner`](skills/slide-outliner/SKILL.md) | Outline an architecture-review or pitch deck — slide titles, key points, and speaker notes — sized to a target time budget. Doesn't generate PPTX. |
317
- | [`deck-builder`](skills/deck-builder/SKILL.md) | Generate a real PowerPoint (`.pptx`) file from content + audience + color palette. Uses `python-pptx`; supports 7 layout types and audience-tuned density. Pairs naturally with `audience-profile` + `slide-outliner`. |
317
+ | [`deck-builder`](skills/deck-builder/SKILL.md) | Generate a real PowerPoint (`.pptx`) file from content + audience + a brand `.potx`/`.pptx` template or colour palette. Uses `python-pptx`; 10 layouts including charts, tables and images, audience-tuned density. Pairs naturally with `audience-profile` + `slide-outliner`. |
318
318
  | [`exec-summary`](skills/exec-summary/SKILL.md) | Compress a long technical document into a one-page executive summary structured around an Ask, business impact, cost/timeline, risks, and what you need from the audience. |
319
319
  | [`decision-log`](skills/decision-log/SKILL.md) | Extract decisions, action items, owners, and due dates from meeting notes, Slack threads, or transcripts into a structured log with source attribution. |
320
320
  | [`incident-comms`](skills/incident-comms/SKILL.md) | Draft the messages you send *while an incident is still burning* — audience-segmented into customer status-page posts, internal stakeholder updates that arm the relayer, and three-sentence exec briefs (business impact + the ask). Every message leads with reader-facing impact (not internal symptom), uses the precise status vocabulary (investigating / identified / monitoring / resolved), commits only to the **next-update time** (never a fix ETA or speculative cause you'd have to retract), and stays blameless and screenshot-safe. Acknowledge → update-on-committed-cadence → verified resolve. Completes the operate triad with `runbook-generator` (how to fix) and `postmortem-generator` (what to say after). |
package/bin/skilldrop.js CHANGED
@@ -55,6 +55,8 @@ Usage:
55
55
  skilldrop scan [<skill...>] [--from <src>] supply-chain scan — flag network/exec/credential
56
56
  patterns in scripts and injection-shaped instructions
57
57
  in SKILL.md before you trust a catalog (RFC-0022)
58
+ skilldrop bootstrap add the skilldrop marketplace to ~/.claude/settings.json
59
+ (idempotent — safe to run in onboarding scripts)
58
60
 
59
61
  Catalogs:
60
62
  (default) the catalog bundled with this package
@@ -1153,9 +1155,44 @@ function validateCmd(args) {
1153
1155
  console.log(`OK: ${names.length} skills in catalog '${cat.source}' pass the structural check.`);
1154
1156
  }
1155
1157
 
1158
+ /* ---------- bootstrap (enterprise distribution) ----------
1159
+ Writes the skilldrop marketplace into ~/.claude/settings.json so every Claude Code
1160
+ session on this machine discovers the catalogue without any per-session /plugin command.
1161
+ Idempotent: safe to run in a provisioning script or onboarding runbook. */
1162
+ const BOOTSTRAP_MARKETPLACE_KEY = "skilldrop";
1163
+ const BOOTSTRAP_GITHUB_OWNER = "sananthanarayan";
1164
+ const BOOTSTRAP_GITHUB_REPO = "skilldrop";
1165
+
1166
+ function bootstrap() {
1167
+ const settingsPath = path.join(os.homedir(), ".claude", "settings.json");
1168
+ let data = {};
1169
+ const raw = readIfPresent(settingsPath, null);
1170
+ if (raw !== null) {
1171
+ try { data = JSON.parse(raw); }
1172
+ catch (e) { die(`${settingsPath} is not valid JSON — fix it first, then re-run bootstrap`); }
1173
+ }
1174
+ data.extraKnownMarketplaces = data.extraKnownMarketplaces || {};
1175
+ const entry = { source: { source: "github", owner: BOOTSTRAP_GITHUB_OWNER, repo: BOOTSTRAP_GITHUB_REPO } };
1176
+ const existing = data.extraKnownMarketplaces[BOOTSTRAP_MARKETPLACE_KEY];
1177
+ if (existing && JSON.stringify(existing) === JSON.stringify(entry)) {
1178
+ console.log(`already configured: ${BOOTSTRAP_MARKETPLACE_KEY} -> github:${BOOTSTRAP_GITHUB_OWNER}/${BOOTSTRAP_GITHUB_REPO}`);
1179
+ console.log(`\nIn any Claude Code session:\n /plugin install <pack>@${BOOTSTRAP_MARKETPLACE_KEY}`);
1180
+ return;
1181
+ }
1182
+ data.extraKnownMarketplaces[BOOTSTRAP_MARKETPLACE_KEY] = entry;
1183
+ fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
1184
+ fs.writeFileSync(settingsPath, JSON.stringify(data, null, 2) + "\n");
1185
+ console.log(`configured ${settingsPath}:`);
1186
+ console.log(` extraKnownMarketplaces.${BOOTSTRAP_MARKETPLACE_KEY} -> github:${BOOTSTRAP_GITHUB_OWNER}/${BOOTSTRAP_GITHUB_REPO}`);
1187
+ console.log(`\nIn any Claude Code session, install a role pack:\n /plugin install solution-architect@${BOOTSTRAP_MARKETPLACE_KEY}`);
1188
+ console.log(` /plugin install dev-team@${BOOTSTRAP_MARKETPLACE_KEY}`);
1189
+ console.log(` /plugin install ai-engineering@${BOOTSTRAP_MARKETPLACE_KEY}`);
1190
+ console.log(`\nOr install the full catalogue:\n /plugin install ${BOOTSTRAP_MARKETPLACE_KEY}@${BOOTSTRAP_MARKETPLACE_KEY}`);
1191
+ }
1192
+
1156
1193
  const args = parseArgs(process.argv.slice(2));
1157
1194
  const cmd = args._.shift();
1158
- const commands = { list, info, packs: listPacks, agents: listAgents, loops: listLoops, install, update, outdated, uninstall, validate: validateCmd, scan };
1195
+ const commands = { list, info, packs: listPacks, agents: listAgents, loops: listLoops, install, update, outdated, uninstall, validate: validateCmd, scan, bootstrap };
1159
1196
  if (!cmd || cmd === "help" || args.flags.help) console.log(HELP);
1160
1197
  else if (commands[cmd]) commands[cmd](args);
1161
1198
  else die(`unknown command '${cmd}' — run: skilldrop help`);
@@ -104,7 +104,7 @@
104
104
  "adr-generator": { "tier": "standard", "rationale": "Structures a decision into MADR/Nygard. Some judgment on title/consequences; not adversarial." },
105
105
  "architecture-diagrams": { "tier": "standard", "rationale": "Translates prose to diagram syntax. Correctness matters; reasoning is bounded." },
106
106
  "brief-intake": { "tier": "standard", "rationale": "Extraction + tagging [explicit]/[implied]/[inferred]. The tagging needs care — above light, below heavy." },
107
- "deck-builder": { "tier": "standard", "rationale": "Generates pptx content + runs a script. Content shaping, not hard reasoning." },
107
+ "deck-builder": { "tier": "standard", "rationale": "Shapes content, maps a brand template's layouts, and runs a script. Judgment, not hard reasoning." },
108
108
  "design-doc": { "tier": "standard", "rationale": "Synthesizes a design doc from a brief. Escalate to heavy via large-input or ambiguous-input when alternatives are genuinely contested." },
109
109
  "exec-summary": { "tier": "standard", "rationale": "Compression to one page. Needs to keep the right signal; escalate on very long source docs." },
110
110
  "figma-diagrams": { "tier": "standard", "rationale": "API calls + spec generation. Bounded transformation." },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilldrop-cli",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Portable AI-agent skills for the deliverables knowledge workers ship \u2014 diagrams, ADRs, PRDs, runbooks, decks, reviews \u2014 installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
5
5
  "author": {
6
6
  "name": "Sanjay Ananthanarayan",
@@ -1,114 +1,181 @@
1
1
  ---
2
2
  name: deck-builder
3
- description: Generate a real PowerPoint (.pptx) file from content, target audience, and a color palette. Produces structurally-appropriate decks (slide count, density, layout choice) tuned for the audience — execs, technical reviewers, sales prospects, investors, internal teams. Use when the user wants an actual editable .pptx, not just an outline.
3
+ description: Generate a real PowerPoint (.pptx) file from content, audience, and either a brand template or a color palette — with charts, tables and images, not only bullets. Slide count, density and layout are tuned to the audience: execs, boards, technical reviewers, sales prospects, investors, internal teams. Use when the user wants an actual editable .pptx rather than an outline, wants their corporate template or brand colours applied, or says "build the deck", "make it a pptx", "use our template".
4
4
  ---
5
5
 
6
6
  # deck-builder
7
7
 
8
- You help the user produce an **actual editable `.pptx` file**, not just an outline. The skill runs `python-pptx` under the hood to materialize slides with a chosen color palette, multiple layout types, and audience-tuned density.
8
+ This skill produces an **actual editable `.pptx` file**, not an outline. It runs `python-pptx`
9
+ to materialise slides — either on a brand template's own masters and layouts, or on the skill's
10
+ built-in design driven by a colour palette.
9
11
 
10
- This skill pairs with two others:
11
- - **[`audience-profile`](../audience-profile/SKILL.md)** — decides how dense / how many / which sections the deck should have
12
- - **[`slide-outliner`](../slide-outliner/SKILL.md)** — drafts the per-slide content before this skill turns it into a `.pptx`
12
+ It pairs with two others:
13
+ - **[`audience-profile`](../audience-profile/SKILL.md)** — decides how dense, how many, which sections
14
+ - **[`slide-outliner`](../slide-outliner/SKILL.md)** — drafts per-slide content before this skill builds it
13
15
 
14
- For a single fast pipeline, use all three in order: profile → outline → build.
16
+ For a single fast pipeline, run all three in order: profile → outline → build.
15
17
 
16
18
  ## How to respond
17
19
 
18
- 1. **Gather three inputs** before generating anything:
19
-
20
- - **Content.** Either a finished outline (from `slide-outliner`), a long doc the user wants compressed into slides, or a list of points. If the content is thin ("here's the topic, you fill in"), pause and ask — *making slides up is the easiest way to make a bad deck*.
21
- - **Audience.** One of: `exec`, `board`, `technical`, `sales`, `internal`, `investor`, `partner`, `customer`. If the user gives a free-form description ("VP of Eng + their staff at a partner"), map to the closest archetype and call out your choice. Use [`audience-profile`](../audience-profile/SKILL.md) for the structural rules.
22
- - **Palette.** Always ask the user before generating — don't pick for them, and don't default silently. Present the choice like this:
23
-
24
- > Pick a palette before I generate the deck:
25
- > - `corporate-blue` — default for B2B / enterprise audiences
26
- > - `monochrome` — restrained / when content is sensitive
27
- > - `vibrant` — internal / sales / pitch decks
28
- > - `dark-mode` — engineering audiences, live demos
29
- > - `editorial` — long-form / read-ahead decks
30
- > - `forest` — calm, nature-leaning
31
- > - `sunset` — warm, narrative-leaning
32
- > - Or give me hex values for `primary` / `secondary` / `accent` / `background` / `text`
33
- > - Or paste your brand colors and I'll map them into the five roles
34
-
35
- If the user gives brand colors as a partial set (e.g. just a primary), derive the missing roles using the rules in [`reference.md`](reference.md#color-palette-principles) and call out what you filled in.
36
-
37
- 2. **Plan the slide list against the audience archetype.** For example:
38
-
39
- | Audience | Slide count | Density | Required sections |
40
- |---|---|---|---|
41
- | `exec` | 6–10 | Low — 3 bullets max | Ask • TL;DR • Business impact • Risks • Ask (closing) |
42
- | `board` | 8–12 | Low — big numbers | Cover • TL;DR • Strategic context • Financials • Risks • Ask |
43
- | `technical` | 12–20 | High — detail welcome | Context • Goals • Proposal (3–5) • Alternatives • Risks • Rollout |
44
- | `sales` | 8–12 | Story arc, visual | Hook • Pain • Solution • Proof • Pricing • Close |
45
- | `internal` | 5–10 | Mixed | Context • Proposal • Discussion topics • Action items |
46
- | `investor` | 10–15 | Polished, narrative | Problem • Market • Product • Traction • Team • Ask |
47
-
48
- The full archetype spec is in [`audience-profile`](../audience-profile/SKILL.md).
49
-
50
- 3. **Build a deck spec.** The spec is a JSON document with this shape — full schema in [`templates/deck-spec.json`](templates/deck-spec.json):
51
-
52
- ```json
53
- {
54
- "title": "ProjectX Migration — Board Update",
55
- "audience": "board",
56
- "palette": { "primary": "#1A2A6C", "accent": "#FDBB2D", ... },
57
- "slides": [
58
- { "layout": "title", "title": "...", "subtitle": "..." },
59
- { "layout": "section", "title": "..." },
60
- { "layout": "content", "title": "...", "bullets": ["..."] },
61
- { "layout": "big_number", "title": "...", "number": "$24M", "caption": "ARR at risk" },
62
- { "layout": "two_column", "title": "...", "left": {...}, "right": {...} },
63
- { "layout": "quote", "quote": "...", "attribution": "..." },
64
- { "layout": "closing", "title": "Approval requested", "subtitle": "..." }
65
- ]
66
- }
67
- ```
68
-
69
- Available layouts: `title`, `section`, `content`, `two_column`, `big_number`, `quote`, `closing`. Most slides should be `content`; sprinkle in `big_number` and `quote` for emphasis.
70
-
71
- 4. **Run the build script** to produce the actual `.pptx`:
72
-
73
- ```bash
74
- # Claude Code
75
- python3 "${CLAUDE_SKILL_DIR}/scripts/build_deck.py" /tmp/deck-spec.json -o ./out/deck.pptx
76
-
77
- # Other IDEs (from the skill folder)
78
- cd path/to/deck-builder && python3 scripts/build_deck.py /tmp/deck-spec.json -o ./out/deck.pptx
79
- ```
80
-
81
- The script writes a real `.pptx` the user can open in PowerPoint, Keynote, or Google Slides and edit further. Tell the user where the file landed and what to do next.
82
-
83
- 5. **Recommend post-generation refinement.** A generated deck is a strong first draft, not a finished artifact. Always suggest:
84
-
85
- - Reviewing speaker notes (they were written by the agent — verify before presenting)
86
- - Replacing any placeholder images with real visuals
87
- - Doing one "audience pass" — read every slide title in order, does the *narrative* make sense to that specific audience?
20
+ ### 1. Run the setup block — once
21
+
22
+ Ask everything in **one** message, with defaults already chosen, so the user can answer with a
23
+ single line or say "go". Never trickle out four separate questions, and never generate a deck
24
+ with the design silently defaulted.
25
+
26
+ > Before I build, confirm these — reply "go" to take the defaults:
27
+ > 1. **Audience** — `exec` · `board` · `technical` · `sales` · `internal` · `investor` · `partner` · `customer`
28
+ > 2. **Format** — live presentation / read-ahead / async share, **how many minutes**, and **16:9** (default) or **4:3**
29
+ > 3. **Design** — either
30
+ > - a **template**: path to a corporate `.pptx` / `.potx`, and the deck inherits its masters, fonts, colours and slide size; or
31
+ > - a **palette**: `corporate-blue` (default for B2B) · `monochrome` · `vibrant` · `dark-mode` · `editorial` · `forest` · `sunset`, or brand hex values for `primary` / `secondary` / `accent` / `background` / `text`
32
+ > 4. **Anything to embed** — numbers to chart, a table, diagram PNGs
33
+
34
+ Rules for reading the answers:
35
+
36
+ - **Content is the one hard input.** If the user supplied only a topic, stop and ask for the
37
+ material. Inventing the content is the easiest way to produce a bad deck.
38
+ - **A free-form audience maps to the closest archetype** — "VP of Eng and their staff at a
39
+ partner" → `technical`, stated out loud. Mixed audience → the least technical archetype, with
40
+ the rest served by appendix slides.
41
+ - **Time sets slide count**, not the other way round: 1.5–2 minutes per slide live. 30 minutes →
42
+ 12–15 slides including cover and close.
43
+ - **A partial brand palette gets completed**, using the rules in
44
+ [`reference.md`](reference.md#color-palette-principles) — say which roles were filled in.
45
+ - **Template beats palette** for chrome; the palette still colours charts, tables, big numbers
46
+ and quote bars, so ask for brand hexes even when a template is supplied.
47
+
48
+ **Non-interactive runs** (subagent, CI, headless): audience, format, time and palette degrade to
49
+ `[assumption]` lines stated at the top of the response — default `exec`, live, 16:9,
50
+ `corporate-blue`. Missing *content* does not degrade: emit `BLOCKED: need deck content
51
+ (outline, doc, or point list)` and build nothing.
52
+
53
+ ### 2. Plan the slide list against the audience archetype
54
+
55
+ | Audience | Slide count | Density | Required sections |
56
+ |---|---|---|---|
57
+ | `exec` | 6–10 | Low — 3 bullets max | Ask • TL;DR • Business impact • Risks • Ask (closing) |
58
+ | `board` | 8–12 | Low — big numbers | Cover • TL;DR • Strategic context • Financials • Risks • Ask |
59
+ | `technical` | 12–20 | High — detail welcome | Context • Goals • Proposal (3–5) • Alternatives • Risks • Rollout |
60
+ | `sales` | 8–12 | Story arc, visual | Hook • Pain • Solution • Proof • Pricing • Close |
61
+ | `internal` | 5–10 | Mixed | Context • Proposal • Discussion topics • Action items |
62
+ | `investor` | 10–15 | Polished, narrative | Problem • Market • Product • Traction • Team • Ask |
63
+
64
+ Full archetype spec: [`audience-profile`](../audience-profile/SKILL.md). Slide-count budgets per
65
+ format and time: [`reference.md`](reference.md#slide-count-budgets).
66
+
67
+ ### 3. Build a deck spec
68
+
69
+ A JSON document — full schema, with every layout and the template block, in
70
+ [`templates/deck-spec.json`](templates/deck-spec.json):
71
+
72
+ ```json
73
+ {
74
+ "title": "ProjectX Migration — Board Update",
75
+ "audience": "board",
76
+ "aspect": "16:9",
77
+ "template": "./brand/acme-master.potx",
78
+ "layout_map": { "title": "Title Slide", "content": "Title and Content" },
79
+ "palette": { "primary": "#1A2A6C", "accent": "#FDBB2D" },
80
+ "slides": [
81
+ { "layout": "title", "title": "...", "subtitle": "...", "presenter": "...", "date": "..." },
82
+ { "layout": "content", "title": "...", "bullets": ["..."], "notes": "..." },
83
+ { "layout": "chart", "title": "...", "takeaway": "...", "chart": { "type": "column", "categories": ["..."], "series": [{ "name": "...", "values": [1, 2] }] }, "source": "..." },
84
+ { "layout": "table", "title": "...", "columns": ["..."], "rows": [["..."]] },
85
+ { "layout": "image", "title": "...", "image": "./diagram.png", "position": "right", "bullets": ["..."] },
86
+ { "layout": "big_number", "title": "...", "number": "$24M", "caption": "ARR at risk" },
87
+ { "layout": "closing", "title": "Approval requested", "subtitle": "..." }
88
+ ]
89
+ }
90
+ ```
91
+
92
+ Ten layouts: `title`, `section`, `content`, `two_column`, `big_number`, `quote`, `image`,
93
+ `table`, `chart`, `closing`. Most slides are `content`; `chart`, `table` and `big_number` carry
94
+ the evidence; `quote` and `image` break the rhythm. Which content shape earns which layout:
95
+ [`reference.md`](reference.md#layout--content-matching).
96
+
97
+ Every slide gets a `notes` field. Slide numbers appear automatically past 10 slides — override
98
+ with `"slide_numbers": false`.
99
+
100
+ ### 4. Build from the user's template when there is one
101
+
102
+ A corporate template is the difference between a deck that gets presented and one that gets
103
+ rebuilt by hand. When the user names one:
104
+
105
+ ```bash
106
+ # Claude Code — list the template's layouts first
107
+ python3 "${CLAUDE_SKILL_DIR}/scripts/build_deck.py" --list-layouts ~/brand/acme-master.potx
108
+
109
+ # Other IDEs (from the skill folder)
110
+ python3 scripts/build_deck.py --list-layouts ~/brand/acme-master.potx
111
+ ```
112
+
113
+ Map each logical layout to one of the printed names in `layout_map`, then build. The template's
114
+ masters, theme fonts, colours, logos and slide size are inherited; any sample slides it ships
115
+ with are dropped. A logical layout left out of the map falls back to the skill's built-in
116
+ design on the template's blank layout — acceptable for `big_number` or `quote`, wrong for
117
+ `title` and `content`, which is where the branding shows.
118
+
119
+ `.potx` and `.pptx` both work. Templates carry no charts or tables of their own, so those are
120
+ drawn into whatever content region the mapped layout defines.
121
+
122
+ ### 5. Run the build script
123
+
124
+ ```bash
125
+ # Claude Code
126
+ python3 "${CLAUDE_SKILL_DIR}/scripts/build_deck.py" /tmp/deck-spec.json -o ./out/deck.pptx
127
+
128
+ # Other IDEs (from the skill folder)
129
+ cd path/to/deck-builder && python3 scripts/build_deck.py /tmp/deck-spec.json -o ./out/deck.pptx
130
+ ```
131
+
132
+ Add `--strict` to fail the build on a missing or unreadable image instead of drawing a
133
+ placeholder box — use it in CI, not in a conversation.
134
+
135
+ **Read the warnings.** The script degrades rather than crashing: a missing image, a short data
136
+ series, an unresolvable template layout each produce a warning and a visible fallback. Report
137
+ every warning to the user with the file path; never present a deck with an unexplained
138
+ placeholder box in it.
139
+
140
+ ### 6. Recommend the refinement pass
141
+
142
+ A generated deck is a strong first draft. Always tell the user to:
143
+
144
+ - Review the speaker notes — the agent wrote them, and they get read aloud
145
+ - Replace any placeholder box with the real diagram
146
+ - Do one audience pass: read every slide title in order, does the *narrative* land for that audience?
147
+ - Run [`doc-critique`](../doc-critique/SKILL.md) against the deck rubric before it goes out
88
148
 
89
149
  ## Useful references
90
150
 
91
- - [`reference.md`](reference.md) — Color palette principles + layout-vs-content matching guide
92
- - [`templates/deck-spec.json`](templates/deck-spec.json) — Full JSON schema with every layout demonstrated
93
- - [`templates/palettes.json`](templates/palettes.json) — Pre-built color palettes (corporate-blue, monochrome, vibrant, dark-mode, editorial, forest, sunset)
94
- - [`examples/exec-board-update.md`](examples/exec-board-update.md) — Worked example: brief → spec → resulting deck
95
- - [`scripts/build_deck.py`](scripts/build_deck.py) — The generator (don't edit unless extending layouts)
151
+ - [`reference.md`](reference.md) — palette principles, layout-vs-content matching, chart and table rules, density and slide-count budgets
152
+ - [`templates/deck-spec.json`](templates/deck-spec.json) — full JSON schema with every layout and the template block
153
+ - [`templates/palettes.json`](templates/palettes.json) — the seven presets
154
+ - [`examples/exec-board-update.md`](examples/exec-board-update.md) — worked example: brief → spec → deck
155
+ - [`examples/templated-brand-deck.md`](examples/templated-brand-deck.md) — worked example: corporate `.potx` → layout map → deck
156
+ - [`scripts/build_deck.py`](scripts/build_deck.py) — the generator (don't edit unless adding a layout)
96
157
 
97
158
  ## Quality bar
98
159
 
99
- - **Title slide isn't blank** — it has a real title, subtitle, presenter, date.
160
+ - **Design is chosen by the user, never silently defaulted** — a template path or a named palette, confirmed in the setup block.
161
+ - **A supplied template is actually inherited** — `layout_map` covers `title`, `section`, `content` and `closing` at minimum. A branded deck rendered on the blank layout has thrown away the branding.
162
+ - **Title slide isn't blank** — real title, subtitle, presenter, date.
163
+ - **Numbers are charted, not bulleted** — three or more comparable figures belong in a `chart` or a `table`, not a bullet list.
164
+ - **Every chart and table cites its `source`** and uses only figures from the user's material.
165
+ - **Bullet density matches audience** — `exec`, *3 bullets max*, period. `technical`, up to 6 when the content needs it.
166
+ - **Speaker notes on every slide** — even one sentence.
100
167
  - **Section dividers used sparingly** — at most one every 4–5 content slides.
101
- - **Big numbers are real** — never invent statistics for emphasis. If the user gave you a number, use it; otherwise pick a different layout.
102
- - **Bullet density matches audience** — for `exec`, *max 3 bullets per slide*, period. For `technical`, up to 6 if the content really needs it.
103
- - **Speaker notes for every slide** — even one sentence. They're how the presenter remembers what's *between* the bullets.
104
- - **Color palette is consistent** — don't mix in random colors that aren't in the palette.
105
- - **No surprise pages** — first and last slides match in style; the deck reads as one document.
168
+ - **Zero unexplained warnings** — every warning the script emits is fixed or reported to the user.
169
+ - **Colour is consistent** — palette roles only, no stray colours; text-on-background contrast ≥ 4.5:1.
106
170
 
107
171
  ## Anti-patterns to avoid
108
172
 
109
- - ❌ Generating a deck without confirming the audience. The same content for execs vs engineers is a different deck.
110
- - ❌ Writing fake numbers to fill a `big_number` slide.
111
- - ❌ Defaulting to bullets when a `big_number`, `quote`, or `two_column` would land harder.
112
- - ❌ Skipping speaker notes because the user "knows the topic" — they're for the reviewer/co-presenter too.
113
- - ❌ Choosing low-contrast palettes (light grey text on white). If the palette has poor contrast, swap to a sensible default and explain.
114
- - ❌ More than ~20 slides for any audience. If you can't make the point in 20, the deck isn't the right format.
173
+ - ❌ Ignoring a template the user already named, or asking for a palette after they supplied one. The template is the answer to "what should this look like".
174
+ - ❌ Mapping every logical layout onto the template's one title-and-bullets layout. That is a branded deck that still looks generated.
175
+ - ❌ Generating without confirming audience. The same content for execs and engineers is a different deck.
176
+ - ❌ Inventing a statistic to fill a `big_number`, or a series to fill a chart. No source, no chart.
177
+ - ❌ A table with 20 rows. Over ~12 it is an appendix or a spreadsheet, not a slide.
178
+ - ❌ Passing an SVG or EMF diagram to `image` — `python-pptx` reads raster only. Convert to PNG first.
179
+ - ❌ Shipping the deck with a grey placeholder box still in it because the warning went unread.
180
+ - ❌ Defaulting to bullets when a `big_number`, `chart`, `quote` or `two_column` would land harder.
181
+ - ❌ More than ~20 slides for any audience. If the point needs 21, the deck is the wrong format.
@@ -1,34 +1,14 @@
1
1
  [
2
- {
3
- "query": "Build me a PowerPoint from this content",
4
- "should_trigger": true
5
- },
6
- {
7
- "query": "Generate a .pptx deck for this exec presentation",
8
- "should_trigger": true
9
- },
10
- {
11
- "query": "Turn this into actual slides I can present, with our brand colors",
12
- "should_trigger": true
13
- },
14
- {
15
- "query": "I need a real deck file, not an outline",
16
- "should_trigger": true
17
- },
18
- {
19
- "query": "Just outline the slides — I'll build the deck myself",
20
- "should_trigger": false
21
- },
22
- {
23
- "query": "Write a one-page summary for executives",
24
- "should_trigger": false
25
- },
26
- {
27
- "query": "Which audience archetype should I target and what are its rules?",
28
- "should_trigger": false
29
- },
30
- {
31
- "query": "Critique the deck I already made",
32
- "should_trigger": false
33
- }
2
+ { "query": "Build me a PowerPoint from this content", "should_trigger": true },
3
+ { "query": "Generate a .pptx deck for this exec presentation", "should_trigger": true },
4
+ { "query": "Turn this into actual slides I can present, with our brand colors", "should_trigger": true },
5
+ { "query": "I need a real deck file, not an outline", "should_trigger": true },
6
+ { "query": "Build the deck on our corporate template — marketing rejects anything else", "should_trigger": true },
7
+ { "query": "Use our .potx master for this QBR deck", "should_trigger": true },
8
+ { "query": "Put these quarterly numbers on a slide as a chart", "should_trigger": true },
9
+ { "query": "Just outline the slides — I'll build the deck myself", "should_trigger": false },
10
+ { "query": "Write a one-page summary for executives", "should_trigger": false },
11
+ { "query": "Which audience archetype should I target and what are its rules?", "should_trigger": false },
12
+ { "query": "Critique the deck I already made", "should_trigger": false },
13
+ { "query": "Extract the text out of this existing .pptx so I can email it", "should_trigger": false }
34
14
  ]
@@ -6,12 +6,35 @@
6
6
  "prompt": "Build a .pptx from this content for an exec audience, using our brand palette (navy/white).",
7
7
  "assertions": [
8
8
  "A real .pptx file is produced, not an outline",
9
+ "Audience, format and design are confirmed in a single setup block rather than as a trickle of separate questions",
9
10
  "The title slide carries a real title, subtitle, presenter, and date — never left blank",
10
11
  "Section dividers appear sparingly, at most one every 4-5 content slides",
11
12
  "Big-number layouts use only numbers the user supplied; no statistic is invented for emphasis",
12
13
  "Bullet density matches the stated audience rather than a fixed default",
13
14
  "The requested palette is applied rather than the default theme"
14
15
  ]
16
+ },
17
+ {
18
+ "id": 2,
19
+ "prompt": "Build the Q3 QBR deck on our corporate template at ~/brand/acme-master.potx — 25 minutes, live, partner audience.",
20
+ "assertions": [
21
+ "The template's layouts are listed with --list-layouts before the spec is written, rather than layout names being guessed",
22
+ "The spec sets `template` and a `layout_map` covering at least title, section, content and closing",
23
+ "A palette is still collected, because the template does not colour charts, tables or big numbers",
24
+ "`aspect` is not fought with — the template's own slide size is accepted and stated",
25
+ "Slide count is derived from the 25-minute budget at roughly 2 minutes per slide"
26
+ ]
27
+ },
28
+ {
29
+ "id": 3,
30
+ "prompt": "Here are our renewal rates for the last three quarters (88%, 91%, 94%) and the SLA table from the contract. Put them in the deck.",
31
+ "assertions": [
32
+ "The three comparable figures become a `chart` slide, not a bullet list",
33
+ "The chart carries a `takeaway` sentence and a `source`",
34
+ "The SLA data becomes a `table` slide rather than aligned bullets",
35
+ "No figure appears that the user did not supply",
36
+ "Any build warning (missing image, short series) is reported to the user with its path rather than left in the file"
37
+ ]
15
38
  }
16
39
  ]
17
40
  }
@@ -0,0 +1,148 @@
1
+ # Example: Q3 partner QBR on the company's own PowerPoint template
2
+
3
+ **Prompt the user gave:** *"Make the Q3 QBR deck for Northwind. Use our corporate template at
4
+ `~/brand/acme-master.potx` — it's mandatory, marketing rejects anything else. 25 minutes, live,
5
+ with the partner's CTO and two of their architects in the room. Renewal rate went 88 → 91 → 94%
6
+ over the last three quarters, ticket volume is down 31%, and we want to land the co-sell
7
+ expansion ask. Brand colours are #0B3D6B and #E8A33D."*
8
+
9
+ ## Step 1 — Setup block, answered in one pass
10
+
11
+ | Input | Value | How it was resolved |
12
+ |---|---|---|
13
+ | Content | Renewal trend, ticket volume, expansion ask | Supplied |
14
+ | Audience | `partner` | Stated ("partner's CTO and architects") |
15
+ | Format | Live, 25 min → 12–14 slides | Stated; slide count derived at ~2 min/slide |
16
+ | Aspect | From the template | `aspect` ignored — the `.potx` is 16:9 |
17
+ | Design | `~/brand/acme-master.potx` + brand hexes | Template for chrome, palette for charts |
18
+ | Embeds | Renewal trend (chart), SLA table | Three comparable figures ⇒ chart, not bullets |
19
+
20
+ The palette is still collected: the template does not colour charts, tables or big numbers.
21
+ `primary: #0B3D6B`, `accent: #E8A33D`; `secondary`, `background` and `text` derived per
22
+ [`reference.md`](../reference.md#color-palette-principles) and called out to the user.
23
+
24
+ ## Step 2 — Read the template's layouts before writing the spec
25
+
26
+ ```bash
27
+ python3 "${CLAUDE_SKILL_DIR}/scripts/build_deck.py" --list-layouts ~/brand/acme-master.potx
28
+ ```
29
+
30
+ ```
31
+ acme-master.potx — slide size 13.33in x 7.50in
32
+ [0] Acme Cover
33
+ [1] Acme Section Break
34
+ [2] Acme Title and Body
35
+ [3] Acme Two Column
36
+ [4] Acme Statement
37
+ [5] Acme Full Bleed Image
38
+ [6] Blank
39
+ ```
40
+
41
+ The names are the template's, not PowerPoint's defaults — which is exactly why the map is read
42
+ from the file rather than guessed.
43
+
44
+ ## Step 3 — The deck spec
45
+
46
+ ```json
47
+ {
48
+ "title": "Northwind QBR — Q3 FY26",
49
+ "audience": "partner",
50
+ "template": "~/brand/acme-master.potx",
51
+ "layout_map": {
52
+ "title": "Acme Cover",
53
+ "section": "Acme Section Break",
54
+ "content": "Acme Title and Body",
55
+ "two_column": "Acme Two Column",
56
+ "big_number": "Acme Statement",
57
+ "quote": "Acme Statement",
58
+ "chart": "Acme Statement",
59
+ "table": "Acme Statement",
60
+ "image": "Acme Full Bleed Image",
61
+ "closing": "Acme Statement"
62
+ },
63
+ "palette": {
64
+ "primary": "#0B3D6B",
65
+ "secondary": "#4A6E94",
66
+ "accent": "#E8A33D",
67
+ "background": "#FFFFFF",
68
+ "text": "#222222"
69
+ },
70
+ "slides": [
71
+ {
72
+ "layout": "title",
73
+ "title": "Northwind × Acme — Q3 business review",
74
+ "subtitle": "Renewals, service quality, and the FY27 co-sell ask",
75
+ "presenter": "Jane Roe, Partner Director",
76
+ "date": "2026-09-30",
77
+ "notes": "Thank them for the quarter before the first slide. Name the ask now so it isn't a surprise at slide 12."
78
+ },
79
+ {
80
+ "layout": "chart",
81
+ "title": "Renewal rate has climbed every quarter this year",
82
+ "takeaway": "Three consecutive quarters of improvement — the joint success plan is what changed.",
83
+ "chart": {
84
+ "type": "line",
85
+ "categories": ["Q1 FY26", "Q2 FY26", "Q3 FY26"],
86
+ "series": [{ "name": "Renewal rate (%)", "values": [88, 91, 94] }],
87
+ "number_format": "0\"%\""
88
+ },
89
+ "source": "Northwind CS dashboard, 30 Sep 2026",
90
+ "notes": "Let them claim the win — ask their CTO what drove Q2. The answer is usually the thing to double down on in FY27."
91
+ },
92
+ {
93
+ "layout": "big_number",
94
+ "title": "Support load is down as adoption is up",
95
+ "number": "-31%",
96
+ "caption": "Ticket volume vs. Q3 FY25, on 2.4× the seat count",
97
+ "notes": "The pairing is the point: more users, fewer tickets. Pause after saying it."
98
+ },
99
+ {
100
+ "layout": "table",
101
+ "title": "SLA performance against contract",
102
+ "columns": ["Metric", "Contracted", "Q3 actual", "Status"],
103
+ "rows": [
104
+ ["Availability", "99.9%", "99.97%", "Met"],
105
+ ["P1 response", "15 min", "9 min", "Met"],
106
+ ["P1 resolution", "4 hrs", "3h 10m", "Met"],
107
+ ["Change failure", "< 5%", "6.2%", "Missed"]
108
+ ],
109
+ "caption": "Change-failure remediation plan on the next slide.",
110
+ "notes": "Do not skip the missed row. Naming it before they do is what makes the other three credible."
111
+ },
112
+ {
113
+ "layout": "closing",
114
+ "title": "Ask: co-sell motion for FY27, two named accounts each",
115
+ "subtitle": "Kick-off 15 Oct, joint pipeline review monthly",
116
+ "notes": "Land on the ask. Get the kick-off date agreed in the room, not in follow-up email."
117
+ }
118
+ ]
119
+ }
120
+ ```
121
+
122
+ *(Abridged — the full deck is 13 slides; the four above are the ones that show the new layouts.)*
123
+
124
+ ## Step 4 — Build
125
+
126
+ ```bash
127
+ python3 "${CLAUDE_SKILL_DIR}/scripts/build_deck.py" /tmp/northwind-qbr.json -o ./out/northwind-qbr.pptx
128
+ ```
129
+
130
+ ```
131
+ template: dropped 2 sample slide(s), kept masters and layouts
132
+ wrote ./out/northwind-qbr.pptx (13 slides, template)
133
+ ```
134
+
135
+ No warnings, so nothing to report. Had the SLA table's diagram been an `.svg`, the build would
136
+ have drawn a placeholder box and warned — which gets reported to the user with the path, not
137
+ quietly shipped.
138
+
139
+ ## What the template bought
140
+
141
+ | Without the template | With it |
142
+ |---|---|
143
+ | Calibri, generated-looking cover | Acme's typeface, cover, and logo on every slide |
144
+ | Palette-coloured title bars | The master's own chrome |
145
+ | Marketing sends it back | Passes brand review unchanged |
146
+
147
+ The palette still did real work: the line chart, the `-31%`, and the table header are brand
148
+ colours because `palette` was collected *alongside* the template, not instead of it.