competitor-one-pager
Skill0 starsChanged 3 months agoMITView on GitHub
Builds a single A4 PDF page per competitor that a seller reads live during a call — win condition, who buys it, value promise, business-metric connection, pricing, where each side wins, one discovery question and one walk-away signal. Generated from an existing battlecard's content JSON so the two can never drift apart, and combinable into one badged, tiered PDF across a whole competitive set. Use when someone asks for a one-pager, sales one-pager, PDF card, pocket card, printable competitor sheet, a battlecard "in PDF", or something short enough to hold during a call. Trigger in any language. For the 2–3 page battlecard use competitor-battlecard; for the long sourced reference document use competitor-deep-dive.
In this repository3 other files it gives its agents.
- competitive-profileSkill
- competitor-battlecardSkill
- competitor-deep-diveSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 83
Read every page image. Expect dead space at the bottom — the page fills from the top and the footer is pinned to the foot, so a third of …
- Distinctive: line 100
A cell reading "Not established in the card.": No snapshot row matched one of the five required fields.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Competitor one-pager
The shortest artefact in the set. One A4 page, one competitor, read live on a call with a prospect talking. It is not a summary of the battlecard — it is a different job. The card teaches a seller the competitor before the call; the one-pager is what they glance at during it.
Shared files live in the plugin's shared/ folder, ../../shared/ from this
skill (also ${CLAUDE_PLUGIN_ROOT}/shared/).
It is generated, not written
The one-pager is built from the same content JSON the battlecard skill uses. Nothing here is re-researched or re-worded. That is the point: a hand-written one-pager drifts from its card within a quarter, and then two documents disagree in front of a customer.
So the order is fixed. No card, no one-pager — build the card first with
competitor-battlecard, get it approved, then run this over it.
What has to be on the page
| Block | Comes from | Why it is there |
| Win when | the card's cardHeader.right.headline | The one sentence. Hero of the page |
| Who buys it | snapshot row Buyer profile | Segment, vertical tilt, scale, named logos |
| Value promise | snapshot row Main value promise | Which side of your value-promise axis they sit on |
| Business metric | snapshot row Connects to a business metric? | Usually the sharpest gap |
| Pricing | snapshot row Pricing model | Structure and any real number, provenance marked |
| They win / We win | snapshot row Where they win vs. where we win | Both directions, honestly, side by side |
| Ask | first row of the discovery table | One question, not six |
| Walk away | first item of the harder-situations column | Tells sales when to stop |
references/required-fields.md explains what each field is for and how it gets
answered badly.
Positioning gets no section. It exists only as the Win when line — one element, not a headline. Re-adding a positioning block is the fastest way to have the page rejected by the people who have to use it.
Build it
cd <plugin>/shared/scripts
# one competitor
python build_onepager.py /path/to/x-card.json \
-o ./output/Us_vs_X_OnePager.pdf --stamp "Aug 2026"
# the whole set, combined and split, ordered and badged by threat tier
python build_onepager.py '/path/to/*-card.json' \
--meta ../assets/meta.example.json --stamp "Aug 2026" \
-o ./output/Competitor_One_Pagers.pdf \
--split ./output/onepagers/Your company name is read from the card's compareTable.usHeader, so the page
says whatever the card says. --company overrides it. Brand colours come from
the card's optional theme block, so the PDFs match the .docx set.
--meta is optional and adds the threat badge, the deal tag under it, and the
page order. Copy ../../shared/assets/meta.example.json and edit. Keys are the
competitor name exactly as it appears in the card's cardHeader.left.title
(minus the <Us> vs. prefix), or the file stem. A key that matches neither is
silently ignored, which looks like a badge that failed to render. Without it the
pages render unbadged in the order given — fine for a single new competitor.
Rendering needs headless Chromium; the script finds Playwright's bundled copy or
one on PATH. The A4 geometry is tuned to Chromium's print engine, so don't
substitute LibreOffice or wkhtmltopdf — the columns will not land.
Then look at it
pdftoppm -jpeg -r 80 out.pdf page # every page; add -f N -l N to narrowRead every page image. Expect dead space at the bottom — the page fills from the top and the footer is pinned to the foot, so a third of the sheet is often empty. That is the design, not a section that failed to draw.
Four things do go wrong, and only the render shows them:
Overflow. A snapshot cell written for a battlecard table can be too long for a quarter of an A4 page. The script warns above 400 characters, but the warning is a hint, not a measurement — check the page. If it overflows, shorten the cell in the card's JSON and rebuild both. Never fix it only in the one-pager.
A blank or duplicated heading. Some cards merge two required fields into one
snapshot row. The extractor claims each row once and prints its real label rather
than a fixed one, so such a card correctly shows two different headings. If you
see the same paragraph twice, a new label variant slipped past the matcher in
find() — add the keyword there rather than editing the output.
A cell reading "Not established in the card." No snapshot row matched one of the five required fields. The script names it on stderr; the battlecard build script warns about the same thing earlier. Fix the card, not the page.
A missing subtitle under the competitor name. Harmless. It means the card has
no standalone Primary use case row — some cards merge it into the value-promise
row — so the text prints under that heading instead and the subtitle is dropped
rather than filled with a placeholder. The script says so on stderr with a ·
rather than a !, because nothing is wrong.
Deliver
Send the combined PDF for browsing and printing, and the split files when people
want one competitor. Split files are named <Us>_vs_<Name>_OnePager.pdf so all
three documents for a competitor sit together in one folder.
Reference files
references/required-fields.md— what each field is for, and how each one gets answered badly.../../shared/assets/meta.example.json— threat tiers, deal tags, page order.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

