Skip to content
Merged
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
14 changes: 8 additions & 6 deletions .agents/skills/minipdf-contribution/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
---
name: minipdf-contribution
description: "Run the vendor-neutral MiniPdf .NET or Rust rendering contribution loop with automatic low-score selection, three-attempt rollback, full regression validation, and PR preparation. Use when: donating compute, improving visual benchmark scores, or preparing a benchmark-backed MiniPdf contribution."
argument-hint: "Choose dotnet or rust"
description: "Run the vendor-neutral MiniPdf .NET or Rust rendering contribution loop with automatic toolchain detection, random implementation selection, low-score selection, three-attempt rollback, full regression validation, and PR preparation. Use when: donating compute, improving visual benchmark scores, or preparing a benchmark-backed MiniPdf contribution."
argument-hint: "Optionally choose dotnet or rust"
---

# MiniPdf Contribution Loop

Read `CONTRIBUTING.md`, especially "Donate Compute with Any Coding Agent", and
execute `scripts/Invoke-MiniPdfContributionLoop.ps1` as the source of truth.

Choose `dotnet` or `rust`, then carry the workflow through Start, focused
Begin/Evaluate attempts, Validate, and Pr. Make one evidence-driven root-cause
change per attempt. Preserve unrelated changes. Never commit, push, fork, or
open a pull request without explicit user approval.
Run `Start` without an implementation to detect installed .NET and Rust
toolchains and randomly choose an available implementation, or explicitly pass
`dotnet` or `rust`. Then carry the workflow through focused Begin/Evaluate
attempts, Validate, and Pr. Make one evidence-driven root-cause change per
attempt. Preserve unrelated changes. Never commit, push, fork, or open a pull
request without explicit user approval.
5 changes: 3 additions & 2 deletions .claude/commands/minipdf-contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ argument-hint: "[dotnet|rust]"
Read `CONTRIBUTING.md`, especially "Donate Compute with Any Coding Agent".
Requested implementation: `$ARGUMENTS`

Use the requested implementation from the command arguments, defaulting to
`dotnet` when omitted. Execute the vendor-neutral
Use the requested implementation from the command arguments. When omitted, let
the controller detect installed toolchains and randomly choose an available
implementation. Execute the vendor-neutral
`scripts/Invoke-MiniPdfContributionLoop.ps1` workflow end to end: Start, up to
three Begin/Evaluate attempts per selected case, Validate, and Pr. Diagnose and
fix root causes between Begin and Evaluate. Preserve unrelated changes, and do
Expand Down
5 changes: 3 additions & 2 deletions .cursor/commands/minipdf-contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ description: Run the automated MiniPdf rendering contribution loop for .NET or R
Read `CONTRIBUTING.md`, especially "Donate Compute with Any Coding Agent".
Requested implementation: `$ARGUMENTS`

Infer `dotnet` or `rust` from the command arguments, defaulting to `dotnet` when
omitted. Execute `scripts/Invoke-MiniPdfContributionLoop.ps1` through Start,
Infer `dotnet` or `rust` from the command arguments. When omitted, let the
controller detect installed toolchains and randomly choose an available
implementation. Execute `scripts/Invoke-MiniPdfContributionLoop.ps1` through Start,
Begin/Evaluate (at most three attempts per selected case), Validate, and Pr.
Diagnose and fix the root cause between Begin and Evaluate. Preserve unrelated
changes, and do not commit, push, fork, or create the pull request without
Expand Down
12 changes: 5 additions & 7 deletions .github/skills/skill-minipdf-contribution/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
---
name: skill-minipdf-contribution
description: "Run an automated .NET or Rust MiniPdf contribution loop that selects the two largest XLSX or DOCX visual differences, attempts each fix up to three times with rollback, runs full regression checks, and prepares or creates a PR. Use when: contributing compute time, fixing low-score Office-to-PDF images, running the self-evolution loop, or preparing a benchmark-backed MiniPdf PR."
argument-hint: "Choose .NET or Rust; optionally specify XLSX or DOCX, a benchmark case, or a score threshold"
description: "Run an automated .NET or Rust MiniPdf contribution loop that detects installed toolchains, randomly selects an available implementation, selects the two largest XLSX or DOCX visual differences, attempts each fix up to three times with rollback, runs full regression checks, and prepares or creates a PR. Use when: contributing compute time, fixing low-score Office-to-PDF images, running the self-evolution loop, or preparing a benchmark-backed MiniPdf PR."
argument-hint: "Optionally choose .NET or Rust, a format, a benchmark case, or a score threshold"
user-invocable: true
disable-model-invocation: false
---

# MiniPdf Contribution Loop

Turn local compute time into a focused, reproducible MiniPdf rendering improvement for either implementation. This Copilot skill is one adapter for the vendor-neutral workflow in `CONTRIBUTING.md`; Claude Code, Cursor, Codex, and terminal agents use the same controller. In VS Code Chat, run `/skill-minipdf-contribution .NET` or `/skill-minipdf-contribution Rust`.
Turn local compute time into a focused, reproducible MiniPdf rendering improvement for either implementation. This Copilot skill is one adapter for the vendor-neutral workflow in `CONTRIBUTING.md`; Claude Code, Cursor, Codex, and terminal agents use the same controller. In VS Code Chat, run `/skill-minipdf-contribution` for automatic selection, or append `.NET` or `Rust` to choose explicitly.

## Automatic Path

Run this once from the repository root:

```powershell
$loop = ".\scripts\Invoke-MiniPdfContributionLoop.ps1"
& $loop -Action Start -Implementation dotnet
# or
& $loop -Action Start -Implementation rust
& $loop -Action Start
```

`.NET` is the default when `-Implementation` is omitted. `Start` requires a clean working tree, runs implementation-specific preflight, installs benchmark Python packages, creates a local `improve/<implementation>-visual-parity-*` branch, builds fresh isolated XLSX/DOCX baselines for the current HEAD, selects the two documents with the lowest page-level visual scores for that renderer, and stores the choice in `.git/minipdf-contribution-loop/`.
When `-Implementation` is omitted, `Start` detects `dotnet` and `cargo` and randomly chooses one installed implementation. Pass `-Implementation dotnet` or `-Implementation rust` to override the choice. `Start` requires a clean working tree, runs implementation-specific preflight, installs benchmark Python packages, creates a local `improve/<implementation>-visual-parity-*` branch, builds fresh isolated XLSX/DOCX baselines for the current HEAD, selects the two documents with the lowest page-level visual scores for that renderer, and stores the choice in `.git/minipdf-contribution-loop/`.

For Rust, `Start` first builds fresh isolated XLSX and DOCX baseline reports from the shared classic corpus. The current Rust benchmark uses Microsoft 365 as the primary scored reference and LibreOffice as an auxiliary reference. It therefore requires Cargo, desktop Excel and Word, Python, and LibreOffice. The .NET path requires the .NET SDK, Python, and LibreOffice.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ param(
[Parameter(Mandatory)]
[ValidateSet("Start", "Begin", "Evaluate", "Validate", "Pr", "Status")]
[string]$Action,
[ValidateSet("dotnet", "rust")]
[string]$Implementation = "dotnet",
[ValidateSet("auto", "dotnet", "rust")]
[string]$Implementation = "auto",
[ValidateSet("xlsx", "docx")]
[string]$Format,
[string]$CaseName,
Expand Down Expand Up @@ -341,6 +341,7 @@ switch ($Action) {
if ($status.Count -gt 0) {
throw "Start requires a clean working tree so failed attempts can be restored without losing user work."
}
$Implementation = & (Join-Path $PSScriptRoot "resolve-implementation.ps1") -Implementation $Implementation
$preflightJson = & (Join-Path $PSScriptRoot "preflight.ps1") -Implementation $Implementation -Json
$preflight = ($preflightJson | Out-String) | ConvertFrom-Json
if (-not $preflight.Ready) { throw "Preflight failed. Follow the reported setup guidance and run Start again." }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[CmdletBinding()]
param(
[ValidateSet("auto", "dotnet", "rust")]
[string]$Implementation = "auto"
)

$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

if ($Implementation -ne "auto") {
return $Implementation
}

$available = @(
if (Get-Command dotnet -ErrorAction SilentlyContinue) { "dotnet" }
if (Get-Command cargo -ErrorAction SilentlyContinue) { "rust" }
)

if ($available.Count -eq 0) {
throw "Automatic implementation selection requires the .NET SDK or Rust/Cargo."
}

return Get-Random -InputObject $available
7 changes: 5 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ All coding agents, including Copilot, Claude Code, Cursor, and Codex, must use
the vendor-neutral workflow in `CONTRIBUTING.md`. The executable entry point is:

```powershell
scripts/Invoke-MiniPdfContributionLoop.ps1 -Action Start -Implementation dotnet
scripts/Invoke-MiniPdfContributionLoop.ps1 -Action Start -Implementation rust
scripts/Invoke-MiniPdfContributionLoop.ps1 -Action Start
```

The default detects installed .NET and Rust toolchains and randomly chooses an
available implementation. Pass `-Implementation dotnet` or
`-Implementation rust` to override it.

Preserve unrelated changes. Do not commit, push, fork, or open a pull request
without explicit user approval.

Expand Down
23 changes: 12 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,20 @@ Cursor, and Codex. The easiest way to start is to paste this prompt into the
agent chat:

```text
Read CONTRIBUTING.md and run the MiniPdf contribution loop for dotnet from start to finish. Diagnose and improve the automatically selected benchmark cases, validate all changes, and prepare the pull request. Do not commit, push, fork, or open a pull request without my explicit approval.
Read CONTRIBUTING.md and run the MiniPdf contribution loop from start to finish. Detect the installed supported language toolchains, randomly choose one available implementation, diagnose and improve the automatically selected benchmark cases, validate all changes, and prepare the pull request. Do not commit, push, fork, or open a pull request without my explicit approval.
```

Replace `dotnet` with `rust` to work on the Rust implementation. The agent
integrations are convenience prompts; the workflow and safety gates live in
one vendor-neutral command:
The agent integrations are convenience prompts; the workflow and safety gates
live in one vendor-neutral command. By default it detects `dotnet` and `cargo`
and randomly chooses one installed implementation:

```powershell
# Choose one implementation.
.\scripts\Invoke-MiniPdfContributionLoop.ps1 -Action Start -Implementation dotnet
.\scripts\Invoke-MiniPdfContributionLoop.ps1 -Action Start -Implementation rust
.\scripts\Invoke-MiniPdfContributionLoop.ps1 -Action Start
```

Pass `-Implementation dotnet` or `-Implementation rust` to choose explicitly.
The selected implementation is stored in the loop state for subsequent actions.

`Start` requires a clean working tree. It checks prerequisites, creates an
implementation-specific branch, builds fresh XLSX and DOCX baselines, and
selects the two largest visual differences.
Expand Down Expand Up @@ -173,10 +174,10 @@ request still require explicit user approval.

| Agent | Shortcut |
|---|---|
| GitHub Copilot | `/skill-minipdf-contribution .NET` or `/skill-minipdf-contribution Rust` |
| Claude Code | `/minipdf-contribution dotnet` or `/minipdf-contribution rust` |
| Cursor | `/minipdf-contribution dotnet` or `/minipdf-contribution rust` |
| Codex | Ask: `Run the MiniPdf contribution loop for dotnet` or `... for rust` |
| GitHub Copilot | `/skill-minipdf-contribution` (auto) or append `.NET`/`Rust` |
| Claude Code | `/minipdf-contribution` (auto) or append `dotnet`/`rust` |
| Cursor | `/minipdf-contribution` (auto) or append `dotnet`/`rust` |
| Codex | Ask: `Run the MiniPdf contribution loop` (auto) or specify an implementation |
| Any terminal agent | Run the vendor-neutral PowerShell commands above |

Agents must preserve unrelated changes and must not commit, push, fork, or open
Expand Down
101 changes: 88 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

# MiniPdf

**Lightweight Office-to-PDF libraries and command-line tools for .NET and Rust.**
**Lightweight Office-to-PDF libraries and command-line tools for .NET, Rust, Java, Python, Node.js, and Go.**

<p>
<a href="https://www.nuget.org/packages/MiniPdf"><img src="https://img.shields.io/nuget/v/MiniPdf.svg" alt="NuGet"></a>
<a href="https://crates.io/crates/minipdf"><img src="https://img.shields.io/crates/v/minipdf.svg" alt="crates.io"></a>
<a href="https://central.sonatype.com/artifact/io.github.shps951023/minipdf"><img src="https://img.shields.io/maven-central/v/io.github.shps951023/minipdf.svg" alt="Maven Central"></a>
<a href="https://pypi.org/project/minipdf/"><img src="https://img.shields.io/pypi/v/minipdf.svg" alt="PyPI"></a>
<a href="https://www.npmjs.com/package/minipdf"><img src="https://img.shields.io/npm/v/minipdf.svg" alt="npm"></a>
<a href="https://pkg.go.dev/github.com/mini-software/MiniPdf/minipdf-go"><img src="https://pkg.go.dev/badge/github.com/mini-software/MiniPdf/minipdf-go.svg" alt="Go Reference"></a>
<a href="https://github.com/mini-software/MiniPdf"><img src="https://img.shields.io/github/stars/mini-software/MiniPdf?logo=github" alt="GitHub stars"></a>
<a href="https://doi.org/10.5281/zenodo.22057294"><img src="https://zenodo.org/badge/DOI/10.5281/zenodo.22057294.svg" alt="DOI"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="License"></a>
Expand All @@ -26,11 +30,14 @@ implementation that matches your project.

## Choose an implementation

| | .NET | Rust |
|---|---|---|
| Inputs | XLSX, DOCX, PPTX | XLSX, DOCX |
| Interfaces | .NET library, CLI, standalone Native AOT binaries | Rust crate, CLI |
| Documentation | **[Open the .NET guide](documents/README.nuget.md)** | **[Open the Rust guide](minipdf-rs/README.md)** |
| Implementation | Inputs | Interfaces | Maturity | Documentation |
|---|---|---|---|---|
| .NET | XLSX, DOCX, PPTX | Library, CLI, Native AOT binaries | Stable | **[.NET guide](documents/README.nuget.md)** |
| Rust | XLSX, DOCX, PPTX | Crate, CLI | Experimental | **[Rust guide](minipdf-rs/README.md)** |
| Java | XLSX, DOCX | Library, CLI | Experimental | **[Java source](minipdf-java/)** |
| Python | DOCX | Package, CLI | Experimental | **[Python guide](minipdf-python/README.md)** |
| Node.js | XLSX, DOCX, PPTX | Native package | Experimental | **[Node.js guide](minipdf-node/README.md)** |
| Go | XLSX, DOCX, PPTX | Package, CLI | Experimental | **[Go guide](minipdf-go/README.md)** |

## Quick start

Expand Down Expand Up @@ -71,15 +78,77 @@ minipdf::convert_to_pdf("report.docx", "report.pdf")?;
minipdf report.docx -o report.pdf
```

The [Rust guide](minipdf-rs/README.md) documents the crate API, CLI, supported
[The Rust guide](minipdf-rs/README.md) documents the crate API, CLI, supported
features, known gaps, and development workflow.

### Java

```xml
<dependency>
<groupId>io.github.shps951023</groupId>
<artifactId>minipdf</artifactId>
<version>0.1.0</version>
</dependency>
```

```java
import io.github.minisoftware.minipdf.MiniPdf;
import java.nio.file.Path;

MiniPdf.convertToPdf(Path.of("report.docx"), Path.of("report.pdf"));
```

### Python

```bash
pip install minipdf
```

```python
import minipdf

minipdf.convert_to_pdf("report.docx", "report.pdf")
```

The [Python guide](minipdf-python/README.md) lists the current DOCX feature scope and CLI options.

### Node.js

```bash
npm install minipdf
```

```javascript
const minipdf = require('minipdf')

minipdf.convertToPdf('report.docx', 'report.pdf')
```

The [Node.js guide](minipdf-node/README.md) covers in-memory conversion, page sizing, font registration, and supported native platforms.

### Go

```bash
go get github.com/mini-software/MiniPdf/minipdf-go@latest
```

```go
import minipdf "github.com/mini-software/MiniPdf/minipdf-go"

if err := minipdf.ConvertToPDF("report.docx", "report.pdf"); err != nil {
panic(err)
}
```

The [Go guide](minipdf-go/README.md) documents the package, native CLI, current rendering scope, and release tags.

## Why MiniPdf

- **No office suite required**: conversion runs inside your application or CLI.
- **Small deployment surface**: minimal dependencies and no external process.
- **Server and CI friendly**: works in containers, cloud services, and pipelines.
- **Native command-line options**: .NET Native AOT releases and a Rust CLI.
- **Multiple language options**: use MiniPdf from .NET, Rust, Java, Python, Node.js, or Go.
- **Native command-line options**: available for .NET, Rust, Java, Python, and Go.
- **Open development**: Apache 2.0 licensed with reproducible visual benchmarks.

MiniPdf targets practical document conversion, not complete Microsoft Office
Expand All @@ -93,17 +162,19 @@ coding agent that can edit files and run PowerShell. The easiest way to
contribute is to paste this prompt into the agent chat:

```text
Read CONTRIBUTING.md and run the MiniPdf contribution loop for dotnet from start to finish. Diagnose and improve the automatically selected benchmark cases, validate all changes, and prepare the pull request. Do not commit, push, fork, or open a pull request without my explicit approval.
Read CONTRIBUTING.md and run the MiniPdf contribution loop from start to finish. Detect the installed supported language toolchains, randomly choose one available implementation, diagnose and improve the automatically selected benchmark cases, validate all changes, and prepare the pull request. Do not commit, push, fork, or open a pull request without my explicit approval.
```

Replace `dotnet` with `rust` to work on the Rust implementation. The universal
PowerShell entry points are:
The universal PowerShell entry point detects `dotnet` and `cargo`, then randomly
chooses one of the installed implementations:

```powershell
.\scripts\Invoke-MiniPdfContributionLoop.ps1 -Action Start -Implementation dotnet
.\scripts\Invoke-MiniPdfContributionLoop.ps1 -Action Start -Implementation rust
.\scripts\Invoke-MiniPdfContributionLoop.ps1 -Action Start
```

Pass `-Implementation dotnet` or `-Implementation rust` to override the random
choice. The selected implementation is stored for every later action in the run.

The contribution loop checks the toolchain, installs benchmark Python packages,
creates a local branch, and selects the chosen renderer's two lowest-scoring
visual differences. The agent gets up to three attempts per case; an attempt
Expand All @@ -126,6 +197,10 @@ opens a PR without your approval.
| [Online demo](https://mini-software.github.io/MiniPdf/) | Try conversion in a browser |
| [.NET documentation](documents/README.nuget.md) | Stable library and CLI usage |
| [Rust documentation](minipdf-rs/README.md) | Experimental crate and CLI usage |
| [Java implementation](minipdf-java/) | Experimental Maven library and CLI source |
| [Python documentation](minipdf-python/README.md) | Experimental package and CLI usage |
| [Node.js documentation](minipdf-node/README.md) | Experimental native package usage |
| [Go documentation](minipdf-go/README.md) | Experimental package and CLI usage |
| [.NET XLSX benchmark](tests/MiniPdf.Benchmark/reports/comparison_report.md) | Visual comparison results for spreadsheets |
| [.NET DOCX benchmark](tests/MiniPdf.Benchmark/reports_docx/comparison_report.md) | Visual comparison results for documents |
| [Rust XLSX benchmark](artifacts/rust-benchmark/classic/xlsx/report/comparison_report.md) | Rust spreadsheet visual comparison results |
Expand Down
Loading
Loading