Imported from jjanuszczak/margo (
AGENTS.md). Install upstream withnpx skills add jjanuszczak/margo. Copyright stays with the author.
AGENTS.md
This file is for a new developer or agent picking up margo.
It is intentionally practical. Read this first so you understand:
- what the repo is
- what works today
- where the important code lives
- how to verify changes safely
- which areas are still in flux
What This Repo Is
margo is a Go CLI for building slide decks from Markdown with a Hugo-like project model.
Current shape:
- local CLI tool
- HTML-first output
- scaffold/build/serve workflow
- default theme plus deck-local custom themes
- initial PDF pipeline via print-oriented HTML
- Git-based vendored theme install workflow
This is not a finished product. It is beyond prototype scaffolding, but still actively evolving in product scope, theme contract, and export quality.
Read These First
Start with:
Historical context:
Use the product docs for intent and scope boundaries. Use the authoring guide for what the tool is supposed to feel like for end users.
Current Product State
Working CLI surface
margo new <deck-name>margo initmargo buildmargo servemargo cleanmargo new slide <name>margo new theme <name>margo theme add <repo> [--ref <rev>] [--name <local-name>]margo theme update <name>margo theme list
Implemented platform pieces
margo.yamlparsing and project discovery- YAML slide front matter
- Markdown rendering with Goldmark
- deck-local themes under
themes/<name>/ - per-slide layouts
- slide archetypes
- draft and hidden filtering
- notes preservation without normal slide rendering
- sections and synthetic section divider slides
- deck-local shortcodes
- project-local Markdown includes
- deck-level snippet injection at approved locations
- deck and slide asset staging
- interactive HTML output
- print-oriented HTML output
- PDF generation from print HTML
- vendored theme install/list
- benchmark and regression fixtures
- release archive script
Implemented but still rough
- PDF fidelity and environment reliability
- theme print overrides beyond the default/productized examples
- theme portability UX beyond the current repo-root install assumption
- manifest-driven sequencing beyond the current loader path
Not done
- PPTX export
- presenter mode
- plugin architecture
- multi-deck repo workflow
- arbitrary slide sizes and ratios beyond the current defaults
Current Priorities
There is no single active sprint doc you should treat as the source of truth.
When choosing work, check:
- the PRD
- the implementation plan
- open GitHub issues
- whether the change tightens the current model or expands product scope
As of now, the highest-risk product areas are:
- PDF quality and validation
- theme API stability
- authoring polish and CLI ergonomics
Recent additions that matter:
- theme-aware print templates
- vendored theme installation via
theme add serve --portfor non-default preview ports
Architectural Principles
These are important project-level design choices, not incidental implementation details.
1. Keep the Go engine generic
Prefer Go code to provide:
- parsing
- validation
- asset resolution
- staging
- model shaping
- generic template helper primitives
Avoid pushing presentation-specific HTML/CSS shape decisions into Go unless there is a strong cross-cutting reason.
2. Keep rendering shape in templates
Shortcodes, layouts, and future partials should own:
- markup structure
- class composition
- inline style composition where needed
- theme-facing presentational decisions
Example:
- generic helpers like required param checks and asset resolution belong in Go
- figure-specific class/style assembly belongs in shortcode templates, not in Go helpers
3. Prefer reusable primitives over named feature logic
If a helper can validate or resolve something for many shortcodes or templates, it is a good candidate for Go.
If a helper only exists to assemble one component's final markup shape, it probably belongs in template composition instead.
4. Keep deck, theme, and shortcode concerns separate
Margo should preserve a clear boundary:
- engine mechanics in Go
- theme and deck presentation in templates
- author-facing content usage in Markdown/front matter
Do not quietly collapse those layers together.
Treat engine/theme decoupling as a first-class rule, not a stylistic preference.
- Avoid making themes depend on ad hoc engine-only template fields when the same behavior can be derived from rendered markup or stable generic helpers.
- Prefer theme behavior that keys off HTML structure, CSS classes, declared assets, or reusable template primitives rather than feature-specific booleans injected from Go.
- If the engine must expose something to templates, prefer a stable mechanism-level helper over a narrow feature flag that couples one theme behavior to one internal implementation detail.
Example:
- loading a chart runtime because the deck contains
.shortcode-chartmarkup is a good theme-side decision - requiring a theme to read a special field like
.HasChartsis tighter coupling and should be avoided unless there is a strong cross-cutting reason
5. Favor explicit override models
When deck-level and theme-level customization both exist, prefer explicit local override behavior over magic lookup or deep inheritance.
This already applies to shortcodes and should remain the bias for future features such as partials.
Repo Layout
Top-level directories:
cmd/
docs/
examples/
internal/
scripts/
skills/
Agent Skills
Predefined agent skills are stored in the skills/ directory. These skills provide specialized workflows and domain expertise for Gemini CLI when working on the margo project.
- github-issue-manager: Manages the creation of GitHub issues and development branches. Use this to start work on a new feature or bug fix.
- git-workflow-lifecycle: Automates the end-to-end lifecycle of a feature branch, from submission (commit, push, PR) to cleanup.
To ensure these skills are active in your environment, they should be installed into the workspace scope:
gemini skills install skills/github-issue-manager.skill --scope workspace
gemini skills install skills/git-workflow-lifecycle.skill --scope workspace
After installation, reload the skills in your interactive session using /skills reload.
Important code areas
-
cmd/margo/main.go CLI entrypoint
-
internal/cli Command dispatch and user-facing CLI flows
-
internal/config
margo.yamlparsing and validation -
internal/project Deck-root discovery
-
internal/content Slide discovery, front matter parsing, notes extraction, includes
-
internal/deck In-memory deck model, filtering, section building
-
internal/theme Theme loading, metadata, validation, install workflow
-
internal/shortcode Shortcode rendering and resolution
-
internal/output/render Shared render helpers used by multiple output pipelines
-
internal/output/html Interactive HTML rendering pipeline
-
internal/output/printhtml Static print-oriented HTML rendering pipeline
-
internal/output/pdf PDF generation from print HTML
-
internal/scaffold Deck/theme/slide scaffolding and default theme templates
-
internal/serve Preview server and PDF export endpoint
-
internal/watch File watching for rebuild flows
-
internal/manifest Manifest loading support
-
internal/ignore Ignore rules for project walking/build inputs
Example Decks And Fixtures
These matter a lot:
-
examples/reference-deck Main regression/acceptance fixture
-
examples/benchmark-deck Committed 20-slide benchmark deck
-
examples/arca-investor-memo Real dogfood deck and the main theme-aware PDF fidelity check
Use them for:
- manual QA
- regression tests
- validating author-facing behavior
- checking whether theme changes hold up on a real deck
Prefer committed fixtures and temp directories in tests over ad hoc throwaway decks.
How To Build And Run
Build the CLI:
go build -o ./bin/margo ./cmd/margo
Run directly:
go run ./cmd/margo help
Create and use a test deck:
./bin/margo new my-deck
cd my-deck
../bin/margo build
../bin/margo serve
Use a non-default preview port when needed:
../bin/margo serve --port 1414
Install a vendored theme from Git:
../bin/margo theme add https://example.com/brand-theme.git --ref v0.1.0
../bin/margo theme list
Important limitation:
theme addcurrently assumes the Git repo root is itself a single Margo theme- it does not yet install a theme from a subdirectory inside a larger monorepo
Testing And Verification
Full suite
env GOCACHE=/Users/johnjanuszczak/Projects/margo/.gocache go test ./...
In restricted environments, set GOCACHE explicitly as above.
Focused test areas
- content parsing:
./internal/content - themes/install/options:
./internal/theme - interactive rendering:
./internal/output/html - print rendering:
./internal/output/printhtml - PDF glue:
./internal/output/pdf - CLI workflows:
./internal/cli
Benchmark
go test -run '^$' -bench BenchmarkBenchmarkDeckBuildFlow ./internal/output/html
Manual checks
When a change affects user-facing output, prefer checking:
examples/reference-deckexamples/benchmark-deckexamples/arca-investor-memo- a fresh scaffolded deck from
margo new
Release / Packaging
Release archive script:
Example:
VERSION=0.1.0 ./scripts/release.sh
This builds versioned archives that bundle:
- the binary
- README.md
- docs/AUTHORING_GUIDE.md
Version stamping comes from:
Current caveat:
- archive creation works
- Homebrew formula and
.pkgpackaging are not implemented in-repo
Common Sharp Edges
1. The repo root is not a deck
margo source itself is not a presentation project.
Do not expect margo build to work from repo root.
2. PDF has two separate concerns
There are two classes of PDF problems:
- print HTML correctness
- browser/headless environment behavior
Do not conflate them.
If a PDF looks wrong, compare:
- interactive HTML
- print HTML
- generated PDF
The print pipeline now uses a dedicated static print artifact rather than rewriting the interactive deck HTML.
3. Theme behavior is convention-heavy
The default theme is still the primary reference contract.
Changes to:
- layout names
- theme metadata
- option names
- slide wrapper structure
- print template behavior
will ripple into:
- scaffolding
- fixtures
- docs
- tests
- real deck fidelity
Also be careful about architectural drift:
- do not move shortcode-specific presentational logic into Go unless it is genuinely reusable
- prefer template composition over new feature-specific helper code
- when adding helper functions, ask whether they are mechanism-level or component-specific
4. The print and interactive pipelines are related but not identical
internal/output/html and internal/output/printhtml share render logic, but they are not the same shell.
When changing deck-level wrappers or CSS assumptions, verify both pipelines.
5. Keep features disciplined
The product direction avoids turning authoring into a second programming language.
Prefer:
- explicit, constrained features
- deck-local and theme-local customization
- minimal extension points with clear ownership
- generic engine primitives with presentational composition in templates
Avoid:
- broad DSLs
- implicit magic behavior
- arbitrary generalization unless the product needs it
- growing a library of shortcode-specific Go helpers when template logic is sufficient
How To Work Safely
When implementing a change:
-
Identify whether it is:
- product behavior
- theme behavior
- scaffold behavior
- test-only behavior
-
Update all affected layers together:
- implementation
- scaffold output if applicable
- committed fixtures if applicable
- tests
- docs for user-facing behavior
-
Verify with the smallest correct test scope first.
-
If output changes, verify with a real deck flow.
-
If the change touches theme rendering, check both:
- the default/reference deck
- the ArCa dogfood deck
-
If you add template helpers in Go, explicitly check whether they are:
- generic mechanism helpers that could serve multiple shortcodes/layouts
- presentational helpers that should stay in templates instead
Documentation Conventions
Use relative Markdown links in repo docs.
Good:
[PRD](./docs/product/PRD.md)[Authoring Guide](./docs/AUTHORING_GUIDE.md)- from
docs/:[reference deck](../examples/reference-deck)
Avoid:
- absolute local filesystem paths in repo Markdown
Practical Advice
If you are unsure what to do next:
- use the committed decks
- prefer tightening the current model over inventing a new subsystem
- check whether the problem is really product behavior, theme behavior, or export behavior
- do not “fix PDF” by damaging the HTML-first experience