Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions partner-built/sspdf/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "sspdf",
"version": "1.0.0",
"description": "Generate publication-ready PDF documents — financial reports, tear sheets, invoices, and branded deliverables — directly from Claude with deterministic, math-first rendering. No LibreOffice, no browser, no pixel nudging.",
"author": {
Comment on lines +1 to +5
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This plugin directory is missing a .mcp.json at the root. The repo-level docs describe the standard plugin layout as including .mcp.json alongside .claude-plugin/plugin.json (see README.md:51-59), so consider adding an empty config (e.g., { "mcpServers": {} }) for consistency even if this plugin doesn’t need external tool connections.

Copilot uses AI. Check for mistakes.
"name": "Hugo Palma"
},
"repository": "https://github.com/hugopalma17/sspdf",
"license": "Apache-2.0",
"keywords": ["pdf", "document-generation", "financial-reports", "invoices", "charts", "tables"]
}
73 changes: 73 additions & 0 deletions partner-built/sspdf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# sspdf — PDF Generation Plugin

Generate publication-ready PDF documents directly from Claude — financial reports, tear sheets, invoices, articles, and branded deliverables — with deterministic, math-first rendering.

## What This Plugin Does

This plugin gives Claude the ability to produce PDF documents from natural language descriptions. Instead of generating HTML and converting it, or relying on LibreOffice, sspdf renders PDFs directly via jsPDF with precise mathematical layout. The output is deterministic: same input, same PDF, every time.

The engine separates content from styling completely. A **source** JSON describes what to render (text, tables, charts, dividers, blocks). A **theme** JS file controls how it looks (fonts, colors, spacing, page geometry). Claude builds both from a description and renders the final PDF.

## Skills

| Skill | What It Does |
|-------|-------------|
| `sspdf` | Builds source JSON and renders PDF documents. Knows all operation types (text, tables, charts, rows, bullets, blocks, quotes, dividers) and the complete rendering pipeline. |
| `sspdf-theme-generator` | Creates custom theme files from brand specs. Knows the full label property schema — page config, text styling, spacing, containers, table formatting, dividers. |

## Commands

| Command | Description |
|---------|-------------|
| `/generate-pdf` | Generate a PDF from a natural language description |
| `/create-theme` | Create a custom theme from brand specifications |

## What It Can Render

- **Text** — wrapped paragraphs, headings, captions with full font/style control
- **Tables** — column alignment, alternating row shading, borders, header repetition on page breaks
- **Charts** — bar, line, pie, stacked bar, grouped bar — rendered as embedded images via canvas
- **Rows** — left/right aligned pairs (ideal for invoice line items, key-value data)
- **Blocks** — grouped content with background, border, and keep-together pagination
- **Quotes** — blockquotes with optional attribution
- **Bullets** — custom markers with wrapped text
- **Page templates** — repeating headers and footers with `{{page}}` token
- **Hidden text** — invisible text layer for ATS keyword injection

Built-in themes: `default`, `editorial`, `newsprint`, `corporate`, `ceremony`, `program`, `financial`.

## Installation

```bash
npm install h17-sspdf
```

Requires Node.js and the `canvas` native addon (automatically installed as a dependency).

## Quick Start

```bash
# CLI
npx h17-sspdf -s source.json -t financial -o output/report.pdf

# Programmatic
const { renderDocument } = require("h17-sspdf");
renderDocument({ source, theme, outputPath: "output/report.pdf" });
```
Comment on lines +49 to +56
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fenced block is labeled as bash but includes JavaScript (require(...) / renderDocument(...)), which will render with misleading syntax highlighting and may confuse copy/paste. Split into separate bash and js code blocks (or use an untyped fence) to match the actual languages.

Copilot uses AI. Check for mistakes.

## Why sspdf

- **No LibreOffice** — Renders PDFs directly via jsPDF. No headless browsers, no OS-level dependencies beyond Node.js.
- **Deterministic** — Math-first layout engine. Same input produces identical output on any machine.
- **Charts and tables out of the box** — Native table operation with page-break header repetition. Chart plugin renders bar, line, pie charts as embedded images.
- **Content/style separation** — Source JSON never contains colors, fonts, or sizes. The theme controls all visual decisions. Swap themes without touching content.
- **Pagination built in** — Automatic page breaks, keep-together blocks, orphan prevention, header/footer templates.

## Requirements

- Node.js 18+
- npm (for h17-sspdf package installation)

## License

[Apache License 2.0](../../LICENSE)
49 changes: 49 additions & 0 deletions partner-built/sspdf/commands/create-theme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
description: Create a custom sspdf theme from brand specs — colors, fonts, and document type
argument-hint: "<brand specs> (e.g. 'navy headers, Helvetica, financial tear sheet')"
---

# Create Theme

> This command uses the sspdf engine (`h17-sspdf` npm package). See the **sspdf-theme-generator** skill for the full property reference.

Create a custom theme file for the sspdf PDF engine from brand specifications.

## Workflow

### 1. Gather Brand Specs

Ask the user for:
- Primary and accent colors
- Font preferences (built-in: helvetica, courier, times — or TTF for custom)
- Document type the theme targets
- Any reference materials or existing brand guidelines

### 2. Read Documentation

```bash
SSPDF_DIR=$(node -e "console.log(require.resolve('h17-sspdf').replace('/index.js',''))")
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SSPDF_DIR snippet is fragile due to hard-coded '/index.js' replacement and can break on Windows path separators. Consider switching to a path-based require.resolve('h17-sspdf/package.json') approach for a reliable package root path.

Suggested change
SSPDF_DIR=$(node -e "console.log(require.resolve('h17-sspdf').replace('/index.js',''))")
SSPDF_DIR=$(node -e "const path = require('path'); console.log(path.dirname(require.resolve('h17-sspdf/package.json')))")

Copilot uses AI. Check for mistakes.
cat $SSPDF_DIR/DOCUMENTATION.md
```

Read the Theme section for the complete property reference.

### 3. Study Existing Themes

```bash
ls $SSPDF_DIR/examples/themes/
```

Read at least one theme to match conventions.

### 4. Generate Theme

Write a `.js` file exporting a valid theme object with all required labels fully specified. See the **sspdf-theme-generator** skill for the schema, rules, and label property reference.

### 5. Test Render

If the user has a source JSON ready:

```bash
npx h17-sspdf -s <source.json> -t <theme-path> -o output/test.pdf
```
52 changes: 52 additions & 0 deletions partner-built/sspdf/commands/generate-pdf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
description: Generate a PDF document from a description — invoices, reports, tear sheets, articles, or any printable deliverable
argument-hint: "<what to generate> (e.g. 'quarterly earnings summary for AAPL', 'invoice for $7,250')"
---

# Generate PDF

> This command uses the sspdf engine (`h17-sspdf` npm package) to render PDF documents. No external dependencies beyond Node.js and the canvas native addon.

Generate a publication-ready PDF from a natural language description. Builds the source JSON, selects or creates a theme, and renders the output.

See the **sspdf** skill for the full operation reference and rendering workflow.

## Workflow

### 1. Determine the Document

Ask the user what they need if not already clear from the argument. Identify:
- Document type (report, invoice, tear sheet, article, program, etc.)
- Content to include
- Any brand preferences (colors, fonts)

### 2. Read Documentation

```bash
SSPDF_DIR=$(node -e "console.log(require.resolve('h17-sspdf').replace('/index.js',''))")
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SSPDF_DIR snippet depends on replace('/index.js',''), which is brittle (may not be the module entrypoint) and not Windows-safe. Prefer a path.dirname(require.resolve('h17-sspdf/package.json'))-style approach so the documentation lookup works cross-platform.

Suggested change
SSPDF_DIR=$(node -e "console.log(require.resolve('h17-sspdf').replace('/index.js',''))")
SSPDF_DIR=$(node -e "const path = require('path'); console.log(path.dirname(require.resolve('h17-sspdf/package.json')))")

Copilot uses AI. Check for mistakes.
cat $SSPDF_DIR/DOCUMENTATION.md
```

### 3. Select or Create Theme

Check built-in themes: `default`, `editorial`, `newsprint`, `corporate`, `ceremony`, `program`, `financial`.

```bash
ls $SSPDF_DIR/examples/themes/
```

If none fits, create a custom theme using the **sspdf-theme-generator** skill.

### 4. Build Source JSON

Construct the source JSON with operations matching the document structure. Every label must exist in the chosen theme.

### 5. Render

```bash
npx h17-sspdf -s <source.json> -t <theme> -o output/<name>.pdf
```

### 6. Verify

Confirm the PDF exists and open it for the user.
147 changes: 147 additions & 0 deletions partner-built/sspdf/skills/sspdf-theme-generator/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
---
name: sspdf-theme-generator
description: Generate custom sspdf theme files from brand specs — colors, fonts, and document type. Use when asked to create a theme, style a document, or design a PDF layout for sspdf.
---

# sspdf Theme Generator

Generate theme files for the sspdf PDF engine. A theme is a JS object that controls every visual decision in a document — page geometry, baseline state, and label styles. Themes produced here work on first render.

## Setup

Verify h17-sspdf is installed:

```bash
npx h17-sspdf --help
```

If this fails, install it:

```bash
npm install h17-sspdf
```

## How It Works

The sspdf engine takes two inputs: a theme (styling rules) and a source (content). The theme controls page geometry, baseline state, and label styles. The source references labels by name. If a label is missing, the engine throws.

Resolve the package location:

```bash
SSPDF_DIR=$(node -e "console.log(require.resolve('h17-sspdf').replace('/index.js',''))")
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SSPDF_DIR derivation uses replace('/index.js',''), which is not robust across package entrypoints and fails on Windows paths. Use a path-based approach (e.g., path.dirname(require.resolve('h17-sspdf/package.json'))) so users can reliably locate DOCUMENTATION.md on all platforms.

Suggested change
SSPDF_DIR=$(node -e "console.log(require.resolve('h17-sspdf').replace('/index.js',''))")
SSPDF_DIR=$(node -e "console.log(require('path').dirname(require.resolve('h17-sspdf/package.json')))")

Copilot uses AI. Check for mistakes.
```

## Required Reading

Before generating a theme, always read the documentation:

```bash
cat $SSPDF_DIR/DOCUMENTATION.md
```

Read the full Theme section (page config, labels, customFonts, layout). This is your source of truth for every property name, type, and constraint.

Also check existing themes for patterns:

```bash
ls $SSPDF_DIR/examples/themes/
```

Read at least one existing theme to match the project's conventions.

## Theme Structure

```js
module.exports = {
name: "Theme Name",

page: {
format: "a4", // only a4
orientation: "portrait", // or "landscape"
unit: "mm", // only mm
compress: true,

// margins
marginTopMm: 20,
marginBottomMm: 20,
marginLeftMm: 18,
marginRightMm: 18,

// background
backgroundColor: [255, 255, 255],

// baseline text state (required, every property)
defaultText: {
fontFamily: "helvetica",
fontStyle: "normal",
fontSize: 10,
color: [0, 0, 0],
lineHeight: 1.2,
},

// baseline stroke state (required)
defaultStroke: {
color: [0, 0, 0],
lineWidth: 0.2,
lineCap: "butt",
lineJoin: "miter",
},

// baseline fill (required)
defaultFillColor: [255, 255, 255],
},

labels: {
// every label the source JSON will reference
},
};
```

## Rules

1. Every label is self-contained. No inheritance between labels. If a label needs `fontFamily`, write `fontFamily`.
2. Colors are always `[R, G, B]` arrays, 0-255.
3. Only `"a4"` format and `"mm"` units are supported. The engine throws on anything else.
4. The `page` section must include `defaultText`, `defaultStroke`, and `defaultFillColor`, all fully specified. These reset after every operation to prevent style leaks.
5. Label names are arbitrary strings. Use a dot-namespace convention: `invoice.title`, `report.body`, `news.headline`.
6. Built-in font families: `helvetica`, `courier`, `times`. For anything else, embed TTF via `customFonts`.
7. Table labels need `cellPaddingMm`, border properties, and optionally `altRowColor`. Use the shared constants pattern from existing theme files if the document includes tables.
8. Do not hardcode positions or sizes in labels that belong in the source JSON.

## Label Property Quick Reference

**Text labels:** `fontFamily`, `fontStyle`, `fontSize`, `color`, `lineHeight`, `lineHeightMm`, `align`, `textTransform`

**Spacing:** `marginTopMm`, `marginTopPx`, `marginBottomMm`, `marginBottomPx`

**Padding:** `paddingMm`, `paddingPx`, `paddingTopMm`, `paddingBottomMm`, `paddingLeftMm`, `paddingRightMm` (and Px variants)

**Container:** `backgroundColor`, `borderWidthMm`, `borderColor`, `borderRadiusMm`

**Left border accent:** `leftBorder: { color, widthMm, gapMm, heightMm, topOffsetMm }`

**Divider labels:** `color`, `lineWidth`, `opacity`, `dashPattern`, spacing props

**Bullet marker:** `fontFamily`, `fontStyle`, `fontSize`, `color`, `lineHeight`, `marker`

**Spacer labels:** `spaceMm`, `spacePx`

**Table cell labels:** `fontFamily`, `fontStyle`, `fontSize`, `color`, `lineHeight`, `cellPaddingMm`, `backgroundColor`, `altRowColor`, `borderColor`, `borderTopMm`, `borderBottomMm`, `borderLeftMm`, `borderRightMm`, per-edge color overrides

## Workflow

1. Read `DOCUMENTATION.md` for the full property reference.
2. Read at least one existing theme in `examples/themes/` for conventions.
3. Ask the user what document type they need (or infer from context).
4. Identify every visual element the document will have. Each one needs a label.
5. Generate the theme file with all labels fully specified.
6. If the document uses tables, read an existing theme with tables and use the shared constants pattern.
7. Write the file to the specified path.

## Verification

If the user has a source JSON ready, render it:

```bash
npx h17-sspdf -s <source.json> -t <theme-path> -o output/test.pdf
```
Loading
Loading