Template-bound PowerPoint generation for enterprise decks
Project description
pptx
Template-bound PowerPoint generation for enterprise decks.
pptx turns a real .pptx template into a machine-readable manifest, then generates slides and decks inside the original corporate design contract instead of trying to approximate it from prompts.
If your organization cares about slide masters, locked branding, placeholder rules, layout fidelity, and CI validation, this is the tool.
The package is published to PyPI as pptx-cli and installs the pptx command.
Why pptx exists
Most AI slide generators fail where enterprise users care most:
- layouts drift from the official template
- placeholders get used inconsistently
- static branding moves or disappears
- theme styling gets recreated approximately instead of preserved exactly
- decks look plausible but are structurally wrong
pptx takes a different approach:
- Initialize from a real template
- Extract a manifest of layouts, placeholders, assets, and rules
- Generate only within those approved boundaries
- Validate output before it reaches humans, CI, or customers
The result is a CLI that behaves more like a compiler toolchain than a drawing tool.
Features
- Initialize a manifest package from a real enterprise
.pptx - Inspect layouts, placeholders, themes, assets, and compatibility warnings
- Estimate text placeholder line capacity for agent guidance during inspection
- Build slides from approved layouts only
- Build full decks from JSON/YAML specs
- Preserve template-bound masters, themes, geometry, and protected elements
- Validate generated decks against manifest rules and template fingerprints
- Diff template versions to detect breaking changes
- Generate template-specific wrapper CLIs
- Expose an agent-first machine contract with:
- stable JSON response envelopes
- structured error codes
- documented exit codes
- a built-in
guidecommand --dry-runsupport for mutating commands
Installation
With uv (recommended)
uv tool install pptx-cli
From the repository
uv tool install git+https://github.com/ThomasRohde/pptx-cli.git
From PyPI with pip
pip install pptx-cli
Verify installation
pptx --version
pptx guide --format json
Quick start
The repository includes a real sample template at Template.pptx. The examples below use that file and the layout IDs currently extracted from it.
Initialize a template package from an existing PowerPoint file:
pptx init ./Template.pptx --out ./corp-template
Inspect the extracted layouts:
pptx layouts list --manifest ./corp-template
pptx layouts show title-only --manifest ./corp-template
pptx placeholders list 1-title-and-content --manifest ./corp-template
pptx placeholders list --format json includes both explicit placeholder guidance and
an estimated_text_capacity block for text-capable placeholders so agents can stay
inside likely line limits when drafting slide content.
Create a single slide:
pptx slide create \
--manifest ./corp-template \
--layout title-only \
--set title="Enterprise AI Operating Model" \
--set subtitle="March 2026" \
--out ./out/operating-model-slide.pptx
Build a full deck from a spec:
pptx deck build \
--manifest ./corp-template \
--spec ./deck.yaml \
--out ./out/operating-model.pptx
Validate the result:
pptx validate \
--manifest ./corp-template \
--deck ./out/operating-model.pptx \
--strict
Preview the write before touching the filesystem:
pptx deck build \
--manifest ./corp-template \
--spec ./deck.yaml \
--out ./out/operating-model.pptx \
--dry-run
Replace an existing output file explicitly:
pptx deck build \
--manifest ./corp-template \
--spec ./deck.yaml \
--out ./out/operating-model.pptx \
--overwrite
Example deck spec
manifest: ./corp-template
metadata:
title: Enterprise AI Operating Model
author: Thomas Rohde
template_version: 1.2.0
slides:
- layout: title-only
content:
title: Enterprise AI Operating Model
subtitle: March 2026
- layout: 1-breaker-with-pattern
content:
title: Why this change
subtitle: Preserve, don’t imitate
- layout: 1-title-and-content
content:
title: Core idea
content_1: |
Preserve the template.
Generate inside its rules.
subtitle: Layouts and placeholders become machine-readable contracts.
Core commands
pptx guide
pptx init
pptx doctor
pptx layouts list
pptx layouts show
pptx placeholders list
pptx theme show
pptx assets list
pptx slide create
pptx deck build
pptx validate
pptx manifest diff
pptx manifest schema
pptx completions generate
pptx wrapper generate
Manifest package layout
A template initialization produces a package like this:
corp-template/
manifest.yaml
manifest.schema.json
annotations.yaml
assets/
images/
media/
embedded/
previews/
layouts/
fingerprints/
parts.json
reports/
init-report.json
Key files
manifest.yaml— extracted source-of-truth contractmanifest.schema.json— schema for validation and toolingannotations.yaml— human-authored semantic annotations and placeholder overrides layered over extracted factsreports/init-report.json— warnings, unsupported features, and compatibility findingsfingerprints/parts.json— structural fingerprints used for validation and diffing
Supported v1 content types
pptx supports these placeholder content types in v1:
- text
- image
- table
- chart
- markdown-text
markdown-text is parsed with markdown-it-py and currently maps CommonMark blocks into
PowerPoint paragraphs. Headings become plain paragraphs, bullet lists use native PowerPoint
bullet levels, ordered lists render as numbered paragraph text, and basic inline emphasis such
as bold/italic/code spans is preserved where PowerPoint run formatting can express it. Markdown
blocks also receive light presentation-aware spacing so headings, paragraphs, and lists do not
collapse into a dense wall of text.
Structured content objects
pptx slide create --set picture=@diagram.png automatically normalizes the file into an
image payload. In deck specs, use the equivalent structured object explicitly:
slides:
- layout: 3-front-page-title-and-picture
content:
title: Workflow
picture:
kind: image
path: out/diagrams/workflow.png
image_fit: fit
image_fit defaults to fit, which preserves the whole image inside the placeholder.
Use cover to opt back into crop-to-fill behavior.
Tables and charts use the same kind pattern:
slides:
- layout: 1-title-and-content
content:
title: Status by workstream
content_1:
kind: table
columns: [Workstream, Status]
rows:
- [Platform, Active]
- [Sales, Planned]
- layout: 1-title-and-content
content:
title: Quarterly trend
content_1:
kind: chart
chart_type: column_clustered
categories: [Q1, Q2, Q3]
series:
- name: Revenue
values: [12, 15, 18]
Fidelity model
Guaranteed in scope:
- slide size and orientation
- master/layout relationships
- approved placeholder geometry
- protected static elements
- preserved theme references where supported
- deterministic content mapping into approved placeholders
Best-effort in v1:
- advanced chart workbook behavior
- highly custom chart or table styling internals
- content-sensitive text reflow edge cases
- animations and transitions
Agent-first CLI contract
pptx is designed to be scriptable by both humans and coding agents.
Structured response envelope
In machine-readable mode, commands return a single JSON envelope on stdout:
{
"schema_version": "1.0",
"request_id": "req_20260307_120000_abcd",
"ok": true,
"command": "layouts.list",
"result": {},
"warnings": [],
"errors": [],
"metrics": {
"duration_ms": 42
}
}
Output rules
- stdout is reserved for structured machine output
- stderr is used for progress and diagnostics
LLM=trueenables minimal non-decorative output behavior--dry-runpreviews mutating commands without writing files
Discoverability
Use guide to retrieve the CLI contract in one call:
pptx guide --format json
That output includes:
- commands and subcommands
- input/output schema references
- examples
- error-code taxonomy
- exit-code mapping
- identifier conventions
Exit codes
pptx uses stable exit-code categories for automation:
| Exit code | Meaning |
|---|---|
0 |
Success |
10 |
Validation or schema error |
20 |
Permission or policy failure |
40 |
Conflict or stale-state failure |
50 |
I/O or package read/write failure |
90 |
Internal error |
Safety model
Mutating commands support preview-first workflows and safe writes:
--dry-runfor non-destructive previews- structured change summaries for write operations
- explicit override flags for dangerous operations
- temporary-file staging and atomic replacement where possible
Because PowerPoint files are ZIP-based packages wearing office clothes, half the job is content generation and the other half is not breaking them.
Wrapper CLIs
You can generate a template-specific wrapper CLI for teams that want a narrower interface:
pptx wrapper generate \
--manifest ./corp-template \
--out ./wrappers/acme-pptx
In v1, wrapper generation emits a thin Python package scaffold that delegates to the shared pptx engine.
Validation and governance
pptx validate checks both structure and fidelity constraints, including:
- master/layout usage
- placeholder mapping correctness
- required placeholder presence
- schema compliance of deck specs
- missing assets or broken relationships
- fingerprint mismatches for protected components
- geometry drift for locked objects and placeholders
This makes pptx suitable for:
- local authoring workflows
- CI pipelines
- agent-driven deck generation
- enterprise template governance
Versioning and diffing
When templates change, pptx can compare manifest packages:
pptx manifest diff ./corp-template-v1 ./corp-template-v2
Diffs highlight:
- added or removed layouts
- placeholder contract changes
- alias changes
- geometry changes
- theme/font changes
- asset changes
- additive vs. breaking changes
Platform support
- Windows
- macOS
- Linux
Microsoft PowerPoint is not required to run the CLI.
Use cases
- enterprise strategy decks
- consulting deliverables
- board and steering-committee presentations
- corporate communications templates
- internal automation pipelines generating
.pptxoutput from structured data - AI-assisted deck generation with strict branding control
Development
Sample template for local testing
The repository root includes Template.pptx, which is currently used for:
- CLI integration tests
- README quick-start examples
- local manual smoke tests while the fixture catalog grows
If additional sanitized templates are introduced later, they should live under tests/fixtures/templates/ with a short note describing their scenario coverage.
Clone the repository and sync the development environment:
git clone https://github.com/ThomasRohde/pptx-cli.git
cd pptx-cli
uv sync --group dev
Run the test suite:
uv run pytest
Run linting and type checks:
uv run ruff check .
uv run ruff format --check .
uv run pyright
Versioning
The project uses semantic versioning with a single source of truth in src/pptx_cli/__init__.py.
Use the helper script to bump versions safely:
uv run python scripts/bump_version.py patch
uv run python scripts/bump_version.py minor
uv run python scripts/bump_version.py major
This commits the version change, creates an annotated v* tag, and pushes — which triggers the publish workflow automatically. Use --no-push to tag locally without pushing.
This updates the package version used for builds and PyPI publishing without needing to edit multiple files manually.
Documentation
PRD.md— product definition and scopeCLI-MANIFEST.md— agent-first CLI design principles adopted by this projectSCAFFOLD.md— project scaffolding instructions
Roadmap highlights
- richer preview generation
- deeper table/chart plugins
- broader enterprise policy packs
- multi-template registries
- post-v1 MCP integration
Contributing
Contributions are welcome.
Please open an issue or discussion for:
- new placeholder/content type support
- template edge cases
- manifest schema changes
- CLI contract changes
- validation or fidelity bugs
For larger changes, include:
- the motivating template behavior
- expected vs. actual output
- sample manifest or sanitized
.pptxstructure where possible
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pptx_cli-1.2.2.tar.gz.
File metadata
- Download URL: pptx_cli-1.2.2.tar.gz
- Upload date:
- Size: 157.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae9ae1daf5287a35a255970a6fca6dcaa4d596b21fb0036c918c1ef8ef9896ce
|
|
| MD5 |
26a81a1ad3f089691e420f66fd3797f6
|
|
| BLAKE2b-256 |
a104b1f55cd351e7c2789b01ae2878c4f08b2ef94794b2198e66b6a9fe9553a2
|
Provenance
The following attestation bundles were made for pptx_cli-1.2.2.tar.gz:
Publisher:
publish.yml on ThomasRohde/pptx-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pptx_cli-1.2.2.tar.gz -
Subject digest:
ae9ae1daf5287a35a255970a6fca6dcaa4d596b21fb0036c918c1ef8ef9896ce - Sigstore transparency entry: 1056971872
- Sigstore integration time:
-
Permalink:
ThomasRohde/pptx-cli@b35a0d1ea0b2852b3d206ec32f3a59274076efed -
Branch / Tag:
refs/tags/v1.2.2 - Owner: https://github.com/ThomasRohde
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b35a0d1ea0b2852b3d206ec32f3a59274076efed -
Trigger Event:
push
-
Statement type:
File details
Details for the file pptx_cli-1.2.2-py3-none-any.whl.
File metadata
- Download URL: pptx_cli-1.2.2-py3-none-any.whl
- Upload date:
- Size: 41.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49946cd0dd05a0c4f9b037206dac4676e8a3063fb5275d47093b505e90928d52
|
|
| MD5 |
2ec25a9d49e53cff3ecd91533a6e213f
|
|
| BLAKE2b-256 |
d56e3ee12c042c7f9817567eb4f3539549d0492a4941d8eb4395514f08c3712d
|
Provenance
The following attestation bundles were made for pptx_cli-1.2.2-py3-none-any.whl:
Publisher:
publish.yml on ThomasRohde/pptx-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pptx_cli-1.2.2-py3-none-any.whl -
Subject digest:
49946cd0dd05a0c4f9b037206dac4676e8a3063fb5275d47093b505e90928d52 - Sigstore transparency entry: 1056971873
- Sigstore integration time:
-
Permalink:
ThomasRohde/pptx-cli@b35a0d1ea0b2852b3d206ec32f3a59274076efed -
Branch / Tag:
refs/tags/v1.2.2 - Owner: https://github.com/ThomasRohde
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b35a0d1ea0b2852b3d206ec32f3a59274076efed -
Trigger Event:
push
-
Statement type: