From mercury
Renders branded Mercury documents from structured audit data. Use this skill whenever you need to produce a Word document, PowerPoint presentation, or markdown report from Mercury audit findings. Triggers on: generate a document, create a report, make a presentation, export findings, render results, produce a deck, write up the audit. Also trigger when the sector-intelligence skill has completed an audit and the user wants output in any document format. This skill owns the visual layer — it takes structured findings (strengths, gaps, benchmarks, talking points) and produces branded, professional documents. The sector-intelligence skill owns the analysis; this skill owns the rendering.
npx claudepluginhub mb-uc/mercury --plugin mercuryThis skill uses the workspace's default tool permissions.
Produces branded documents from structured Mercury audit data. Supports four output formats: Word (.docx), PowerPoint (.pptx), interactive HTML (.html), and markdown (.md).
assets/fonts/IDXHeadline-Heavy.otfassets/fonts/IDXSans-Bold.otfassets/fonts/IDXSans-Regular.otfassets/fonts/IDXSerif-Regular.otfassets/logos/IDX-black-large.pngassets/logos/IDX-black-tiny.pngassets/logos/IDX-black.pngassets/logos/IDX-black.svgassets/logos/IDX-white-large.pngassets/logos/IDX-white-tiny.pngassets/logos/IDX-white.pngassets/logos/IDX-white.svgreferences/markdown-templates.mdreferences/mercury-brand-guide.mdreferences/report-structures.mdscripts/build-pipeline.shscripts/mercury-adapter.jsscripts/mercury-components.jsscripts/mercury-html.jsscripts/mercury-output.jsGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Automates semantic versioning and release workflow for Claude Code plugins: bumps versions in package.json, marketplace.json, plugin.json; verifies builds; creates git tags, GitHub releases, changelogs.
Produces branded documents from structured Mercury audit data. Supports four output formats: Word (.docx), PowerPoint (.pptx), interactive HTML (.html), and markdown (.md).
Before using any mercury-render scripts, install the required npm packages. Run this at the start of every session — it takes a few seconds and is safe to re-run:
npm install docx pptxgenjs exceljs
These are the only dependencies. Both are pure JavaScript with no native bindings. The scripts also use Node built-ins (fs, path) which need no installation.
You must run this before requiring mercury-components.js or mercury-pptx.js, or they will fail with MODULE_NOT_FOUND.
Use mercury-render whenever you have audit findings ready and need to produce a deliverable. The typical flow is:
You can also use it standalone if you have structured findings from any source and want Mercury-branded output.
mercury-render/
├── SKILL.md ← You are here
├── scripts/
│ ├── mercury-components.js ← Reusable docx-js building blocks
│ ├── mercury-pptx.js ← Reusable pptxgenjs building blocks
│ ├── mercury-html.js ← Interactive HTML presentation builder
│ ├── mercury-adapter.js ← Artefact → reportData transformer (all stages)
│ ├── mercury-output.js ← On-demand render + manifest + cumulative hub
│ └── build-pipeline.sh ← Validate → convert → verify pipeline
├── references/
│ ├── report-structures.md ← Section order and content for each report type
│ ├── markdown-templates.md ← Markdown output templates
│ └── mercury-brand-guide.md ← IDX brand system reference
└── assets/
├── fonts/
│ ├── IDXHeadline-Heavy.otf ← Display font
│ ├── IDXSans-Bold.otf ← Heading font
│ ├── IDXSans-Regular.otf ← Body font
│ └── IDXSerif-Regular.otf ← Quote/accent font
├── logos/
│ ├── IDX-black.png ← Logo for light backgrounds
│ ├── IDX-black-large.png ← Large logo for covers
│ ├── IDX-white.png ← Logo for dark backgrounds
│ ├── IDX-white-large.png ← Large logo for dark covers
│ └── (tiny and SVG variants)
└── templates/
└── word-generic-a4.docx ← IDX branded Word template
Critical rule: The renderer must compose output from claims and claim-backed findings. It must not generate free prose first and then validate or annotate it afterwards.
The rendering flow is:
claims[] → findings (with claim_ids) → prose sections
Not:
findings → prose → check against claims (WRONG)
Scope inheritance: When rendering a finding or gap, the output text must not exceed the
scope of its source claim(s). If a claim says scope: "reviewed IR pages", the rendered
prose must say "in the reviewed IR pages", not "on the site".
Negative claim rendering: Negative findings (gaps, absences) must render as bounded absence statements that match their source claim scope. "No dedicated investment case page was identified in the reviewed IR pages" — never "There is no investment case page on the site" unless the claim has multi-section evidence.
Provisional legacy claims: Findings backed only by provisional_legacy claims must
render with hedged language ("based on available evidence", "in the material reviewed") and
cannot render as high-confidence or site-wide statements.
Mercury has three report types, each with a different document structure:
| Type | Sections | Typical length |
|---|---|---|
| Quick audit | Cover, exec summary, strengths, gaps, benchmarks, talking points, pages analysed, methodology | 5-6 pages |
| Peer comparison | Cover, exec summary, comparison matrix, where A leads, where B leads, gaps, benchmarks, talking points, pages analysed, methodology | 8-10 pages |
| Deep dive | Cover, exec summary, section-by-section analysis, gaps, benchmarks, recommendations, talking points, pages analysed, methodology | 12-20 pages |
See references/report-structures.md for the full section-by-section breakdown of each type.
The adapter at scripts/mercury-adapter.js transforms one or more stage artefact JSONs into the unified reportData shape consumed by all three renderers. Always use the adapter — do not manually map artefact fields.
const { buildReportData, loadAndBuild } = require('./scripts/mercury-adapter.js');
// Option A: Load from files by naming convention
const reportData = loadAndBuild('/path/to/artefacts', 'company-name', {
sector: "Business Services",
index: "FTSE 100",
});
// Option B: Pass artefact objects directly (any combination of stages)
const reportData = buildReportData({
brief: briefArtefact, // optional
compete: competeArtefact, // optional
sitemap: sitemapArtefact, // optional
meeting: meetingArtefact, // optional
}, { sector: "...", index: "..." });
// Then pass reportData to any renderer
The adapter handles all field mapping from artefact schema to renderer schema:
findings (severity=positive) → strengthsgap_analysis (status=searched_not_found) → gapssynthesis.priorities → talkingPointscitations (type=web_page) → pagesAnalysedcomparison_matrix → comparisonMatrix (compete stage)sitemap_data / recommended_architecture → sitemapData (sitemap stage)Sections only appear when their stage data exists. The report type is auto-detected from which stages are provided.
The full reportData schema expected by the renderers is below. vNext: The claims array from the artefact must be included; findings reference claim IDs.
const reportData = {
// Meta
type: "quick_audit" | "peer_comparison" | "deep_dive",
title: "Site audit", // Cover page title
subtitle: "Inchcape plc", // Cover page subtitle
date: "February 2026",
meta: [ // Cover page metadata pairs
["Sector", "Automotive distribution"],
["Index", "FTSE 250"],
["Pages analysed", "10 key pages"],
],
// Claims (vNext) — the authoritative bounded knowledge layer
claims: [
{
claim_id: "C-001",
statement: "The IR landing page lists three upcoming results dates",
claim_type: "fact",
scope: "IR landing page only",
certainty: "confirmed",
status: "active",
evidence_ids: ["E-001"]
}
],
// Findings — must reference claim_ids
executiveSummary: "string",
strengths: [{ title: "...", detail: "...", claim_ids: ["C-001"] }],
gaps: [{ gap: "...", section: "...", priority: "High|Medium|Low", detail: "...", claim_ids: ["C-003"] }],
benchmarks: { rows: [["Category", "Median", "P75", "Estimate", "Assessment"]] },
talkingPoints: [{ title: "...", detail: "...", claim_ids: ["C-001", "C-003"] }],
pagesAnalysed: [["URL", "Page type", "Assessment"]],
// Findings (peer comparison) — adds:
companyA: "Rolls-Royce",
companyB: "GE Aerospace",
summaryRatings: [{ dimension: "...", ratingA: "...", ratingB: "...", edge: "..." }],
comparisonMatrix: [{ dimension: "...", a: "...", b: "...", edge: "..." }],
whereALeads: [{ title: "...", detail: "...", claim_ids: [] }],
whereBLeads: [{ title: "...", detail: "...", claim_ids: [] }],
pagesA: [["URL", "Page type"]],
pagesB: [["URL", "Page type"]],
};
When building prose from a finding, look up its claim_ids and apply this guard:
scope field from each referenced claimcertainty is inferred or not_assessed, the prose must use hedged languagestatus is provisional_legacy, the prose must use hedged language and cannot assert site-wide conclusionsThe renderer automatically selects the correct Word format based on the data:
reportData.isMsFindings === true) — routes to renderMsStrategyDOCX(). Produces 10 main sections + 5 appendices. See references/report-structures.md under "Mercury Strategy" for the full section order and data sources.renderOriginalDOCX(). Produces the standard quick audit / peer comparison / deep dive format.Both paths are in scripts/mercury-output.js. The adapter (scripts/mercury-adapter.js) builds reportData from the artefact files and sets isMsFindings = true when ms-findings data is present.
Mercury Strategy Word report sections:
The component library at scripts/mercury-components.js provides all the building blocks:
const M = require('./scripts/mercury-components.js');
// M exposes:
// - Design system: M.COLORS, M.BORDERS, M.CELL_MARGINS, M.PAGE_A4
// - Text helpers: M.t(text, opts), M.p(children, opts)
// - Table helpers: M.cell(children, opts), M.hCell(text, width), M.dataTable(headers, rows, columnWidths)
// - Section builders: M.coverPage(title, subtitle, meta), M.headerFooter(left, right)
// - Document builder: M.createDocument(sections)
// - Build: M.build(doc, outputPath)
The component library handles all Mercury branding automatically — colours, fonts, table styles, page sizing, headers, footers. You focus on content structure, not styling.
The pptx component library at scripts/mercury-pptx.js provides equivalent building blocks for presentations:
const MP = require('./scripts/mercury-pptx.js');
// MP exposes:
// - MP.createPresentation() → configured pptxgenjs instance with Mercury master slides
// - MP.titleSlide(pptx, title, subtitle, meta)
// - MP.sectionSlide(pptx, heading)
// - MP.contentSlide(pptx, heading, bodyText)
// - MP.tableSlide(pptx, heading, headers, rows)
// - MP.twoColumnSlide(pptx, heading, leftContent, rightContent)
// - MP.build(pptx, outputPath)
The HTML renderer at scripts/mercury-html.js produces self-contained browser presentations:
const MH = require('./scripts/mercury-html.js');
// MH exposes:
// - MH.buildPresentation(reportData) → complete HTML string
// - MH.COLORS → IDX colour tokens
// - MH.FONTS → IDX font family names
const html = MH.buildPresentation(reportData);
require('fs').writeFileSync('output.html', html);
HTML presentations include all brand fonts embedded as base64, so they render correctly on any machine without font installation. The dark theme (Licorice background) matches the PPTX master for visual consistency across formats.
Optional data-driven sections:
reportData.sitemapData (hierarchical structure from sitemap stage) to render a D3.js treemapreportData.comparisonMatrix for interactive comparison tablesFor markdown output, see references/markdown-templates.md for the template structures. Markdown reports use the same section order as Word documents but with simple formatting — no component library needed.
After generating any document, run the build pipeline:
# For .docx files:
bash scripts/build-pipeline.sh docx output.docx
# For .pptx files:
bash scripts/build-pipeline.sh pptx output.pptx
# For .html files:
bash scripts/build-pipeline.sh html output.html
The pipeline validates the file, converts to PDF (docx/pptx), extracts page images, and reports the page count. For .docx it validates with python-docx (inline); for .pptx it uses LibreOffice conversion. For .html it validates structure and font embedding — no PDF conversion needed.
Always visually verify at least the cover page, first content page, and a table page by reading the generated JPG images.
Derived from the IDX brand templates (IDX2024_core_v1.pptx, About us.dotx). The design system is codified in the component libraries but documented here for reference.
| Token | Hex | Name | Usage |
|---|---|---|---|
LICORICE | #12061A | Licorice | Primary dark — headings, table headers, cover bg |
FLORAL_WHITE | #F7F6EE | Floral White | Primary light — slide backgrounds |
ROSE | #FF006F | Rose | Primary accent — dividers, highlights, links |
LEMON_LIME | #EEFF00 | Lemon Lime | Accent 1 — section divider backgrounds |
AQUAMARINE | #00FFC9 | Aquamarine | Accent 3 — "Strong" rating indicator |
MERCURY_GRAY | #F5F5F5 | — | Alternating table row fill |
WHITE | #FFFFFF | Pure White | Text on dark backgrounds |
MEDIUM | #666666 | — | Meta text, footers, captions |
HIGH_RED | #CC3333 | — | High priority gaps |
MED_AMBER | #E8A317 | — | Medium priority gaps |
LOW_GREEN | #27AE60 | — | Low priority gaps |
The full IDX palette also includes Orange (#FF6500), Green (#00FF00), Blue (#0068FF), and Hyperlink blue (#00A6EB), all available as COLORS.* constants.
Mercury uses the IDX custom type family across all formats:
| Font | Weight | Usage | Fallback |
|---|---|---|---|
| IDX Sans | Regular | Body copy, table cells, meta text | Arial |
| IDX Sans | Bold | Headings (H1-H3), table headers, emphasis | Arial Bold |
| IDX Headline | Heavy | Cover page titles, display text (sparingly) | Arial Black |
| IDX Serif | Regular | Pull quotes, product names (rare) | Georgia |
Font files are in assets/fonts/ (OTF format). For Word documents, the fonts are referenced by name — recipients need IDX Sans installed, or Word substitutes Arial automatically. For HTML presentations, fonts are embedded as base64 @font-face so no installation is needed.
The skill includes IDX logos in assets/logos/:
IDX-black.png / IDX-black.svg — for light backgrounds (Word cover, Lemon Lime dividers)IDX-white.png / IDX-white.svg — for dark backgrounds (PPTX content + title slides, HTML)IDX-black-large.png / IDX-white-large.png — large variants for cover pages-tiny) for header/footer placementM.getLogoBuffer("black"|"white") in docx or MP.getLogoPath("black"|"white", "large"|"tiny") in pptxMercury uses a progressive rendering model. Each pipeline stage (brief, compete, sitemap, meeting) produces an artefact JSON. At the end of each stage, the user is offered formatted output rather than raw data.
mercury-output.js)The output helper at scripts/mercury-output.js handles on-demand rendering from artefact files. It:
reportData via the adapter (cumulative — all completed stages){company}-mercury-manifest.json) tracking all rendered filesconst MO = require('./scripts/mercury-output.js');
const result = await MO.renderStage({
dir: '/path/to/artefacts',
company: 'rentokil-initial',
stage: 'brief',
formats: ['html', 'docx', 'pptx'],
opts: { sector: 'Business Services', index: 'FTSE 100' },
});
// result.files = { html: '...path', docx: '...path', pptx: '...path' }
// result.hub = '...path to cumulative HTML hub'
// result.manifest = { stages_completed, documents, ... }
Each command file (commands/brief.md, etc.) includes a stage completion protocol. After a stage finishes:
mercury-output.js when the user picks a formatThe HTML renderer supports a documentsTab property on reportData. When present, a "Documents" section appears in the nav and at the bottom of the presentation, listing all rendered files grouped by stage with format badges (HTML, DOCX, PPTX, XLSX).
The output helper (mercury-output.js) automatically injects this data when building the hub.
The manifest at {company}-mercury-manifest.json tracks:
{
"company": "Rentokil Initial",
"slug": "rentokil-initial",
"stages_completed": ["brief", "compete"],
"documents": [
{ "stage": "brief", "format": "html", "filename": "...", "rendered_at": "..." },
{ "stage": "brief", "format": "docx", "filename": "...", "rendered_at": "..." }
],
"hub_path": "...",
"last_updated": "..."
}
npm install docx pptxgenjs exceljs before using any scripts (see Setup section above)ShadingType.CLEAR for table fills, never SOLIDLevelFormat.BULLET via numbering configpython-docx inline (no external dependency needed)