diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e641a9f76..304de8344 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,11 +1,11 @@ { "name": "ShinyPDF Tests", "image": "mcr.microsoft.com/dotnet/sdk:10.0", - "postCreateCommand": "apt-get update && apt-get install -y libfontconfig1 libfreetype6 libpng16-16t64 libharfbuzz0b libjpeg-turbo8 libgif7 libwebp7 && dotnet restore src/ShinyPDF.sln", + "postCreateCommand": "apt-get update && apt-get install -y libfontconfig1 libfreetype6 libpng16-16t64 libharfbuzz0b libjpeg-turbo8 libgif7 libwebp7 && dotnet restore src/ShinyPDF.slnx", "customizations": { "vscode": { "settings": { - "dotnet.defaultSolution": "src/ShinyPDF.sln" + "dotnet.defaultSolution": "src/ShinyPDF.slnx" }, "extensions": [ "ms-dotnettools.csharp", diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..c2c350915 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,9 @@ +# Copilot instructions + +Follow [AGENTS.md](../AGENTS.md) in the repository root. It holds the project rules, commands, and workflow for all AI tools. + +When reviewing pull requests, check in particular: + +- Changes to the public API (`ShinyPDF.Fluent`, public types) that break consumers need a `BREAKING CHANGE:` commit footer. +- SkiaSharp, HarfBuzzSharp and their `NativeAssets.*` packages stay on matching versions. +- Tests use NUnit `Assert.That`. diff --git a/.vscode/settings.json b/.vscode/settings.json index 57b6d430b..6b286c251 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "dotnet.defaultSolution": "src/ShinyPDF.sln", + "dotnet.defaultSolution": "src/ShinyPDF.slnx", } \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..22486ce9c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,41 @@ +# ShinyPDF - .NET library for PDF generation with a C# Fluent API + +The single orientation file for any AI agent (Claude Code, Copilot, Codex, ...) and any human working in this repo. Keep it current. + +## Project + +- Status: active. Open-source library, published to NuGet as `ShinyPDF`. Fork of the last MIT-licensed version of QuestPDF. +- Stack: C# / .NET 10 (SDK pinned in `src/global.json`), SkiaSharp + HarfBuzzSharp for rendering, NUnit for tests. +- Layout: `src/ShinyPDF` (library: `Fluent` = public API, `Elements`, `Drawing`, `Infrastructure`, `Helpers`), `src/ShinyPDF.UnitTests` (fast tests with an operation-recording test engine), `src/ShinyPDF.Examples` (NUnit tests that render real PDFs/images). + +## Key rules + +- Never commit `.env`, `*.tfvars`, or `.claude/settings.local.json`. +- The public API (`ShinyPDF.Fluent`, public types) is used by consumers: breaking changes need a `BREAKING CHANGE:` commit footer (major release). +- SkiaSharp, HarfBuzzSharp and their `NativeAssets.*` packages must stay on matching versions, including the Linux ones in `Directory.Build.props`. +- Native asset references in `Directory.Build.props` keep `PrivateAssets="all"` so they never become package dependencies. +- The `Grid` element's `[Obsolete]` marker is inherited from the QuestPDF base, not a ShinyPDF decision; it may be reintroduced. Do not remove `Grid` or migrate existing usages unprompted; its CS0618 warnings are expected. +- Use NUnit `Assert.That` in tests (no FluentAssertions). + +## Commands + +```bash +dotnet build src/ShinyPDF.slnx # build all projects +dotnet test src/ShinyPDF.UnitTests/ShinyPDF.UnitTests.csproj # unit tests (seconds, what CI runs) +dotnet test src/ShinyPDF.Examples/ShinyPDF.Examples.csproj # example renders (~8 min, writes PDFs/PNGs to bin/) +dotnet pack src/ShinyPDF/ShinyPDF.csproj -c Release -o out # local NuGet package +``` + +Example tests marked `.ShowResults()` try to open the generated file in a viewer; run them only when rendering changed. +On Linux (or with `SHINYPDF_DEVCONTAINER=true`) the Linux native assets are added automatically. + +## Workflow + +- GitHub: `LM-Development/ShinyPDF`, use `gh` for issues and PRs. Branch from `main`, open a PR, CI (`pull-request.yaml`) builds and runs the unit tests. +- Commits follow Conventional Commits. Every push to `main` runs `release.yaml`: `feat:` / `fix:` / `BREAKING CHANGE` create a GitHub release and publish to NuGet; `chore:`, `test:`, `docs:` release nothing. +- Merge PRs with a merge commit, not squash, so commit types and footers reach `main` unchanged. +- Published NuGet versions cannot be deleted, only unlisted: check the commit type before merging. + +## Current focus + +Open issues: user documentation (#9, #22), more underline options (#11), template designer app (#12). diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..c3b8dc6d3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,10 @@ +# ShinyPDF + +Read [AGENTS.md](AGENTS.md) first. All project rules, commands, and workflow live there; this file holds only what is Claude-specific. + +## Claude-specific rules + +- No em-dashes in any generated text, code comments, or commit messages. +- This repo is on GitHub: use `gh`, not `az repos` / `az boards`. +- Before claiming done or fixed: verify the actual result (tests run, package packed, release visible), or say "UNVERIFIED". A green build is not verification. +- On Windows, PowerShell 5.1 writes UTF-8 with BOM by default; preserve the existing encoding of files you edit.