diffs: address review feedback on errors, aliases, docs

This commit is contained in:
Gustavo Madeira Santana
2026-03-02 01:31:54 -05:00
parent 5f383a633a
commit 65828b3e07
4 changed files with 44 additions and 2 deletions

View File

@@ -145,6 +145,7 @@ Compatibility note: `defaults.format` is accepted as an alias for `defaults.file
- `mode: "file"` uses a faster file-only render path and does not create a viewer URL.
- File quality presets include hard pixel caps to prevent runaway renders on very large diffs.
- PNG or PDF rendering requires a Chromium-compatible browser. If auto-detection is not enough, set `browser.executablePath`.
- If your channel compresses images aggressively (for example Telegram or WhatsApp), prefer `fileFormat: "pdf"` to preserve diff readability.
- Diff rendering is powered by [Diffs](https://diffs.com).
## Related docs

View File

@@ -117,7 +117,7 @@ After:
This is version two.
```
Render a PNG:
Render a file (PNG or PDF):
```text
Use the `diffs` tool in `file` mode for this before and after input. After it returns `details.filePath`, use the `message` tool with `path` or `filePath` to send me the rendered diff image.
@@ -165,4 +165,5 @@ diff --git a/src/example.ts b/src/example.ts
- The viewer is hosted locally through the gateway under `/plugins/diffs/...`.
- Artifacts are ephemeral and stored in the local temp directory.
- PNG/PDF rendering requires a Chromium-compatible browser. Set `browser.executablePath` if auto-detection is not enough.
- If your delivery channel compresses images heavily (for example Telegram or WhatsApp), prefer `fileFormat: "pdf"` to preserve readability.
- Diff rendering is powered by [Diffs](https://diffs.com).

View File

@@ -8,6 +8,7 @@ import { VIEWER_ASSET_PREFIX, getServedViewerAsset } from "./viewer-assets.js";
const DEFAULT_BROWSER_IDLE_MS = 30_000;
const SHARED_BROWSER_KEY = "__default__";
const IMAGE_SIZE_LIMIT_ERROR = "Diff frame did not render within image size limits.";
export type DiffScreenshotter = {
screenshotHtml(params: {
@@ -237,8 +238,11 @@ export class PlaywrightDiffScreenshotter implements DiffScreenshotter {
});
return params.outputPath;
}
throw new Error("Diff frame did not render within image size limits.");
throw new Error(IMAGE_SIZE_LIMIT_ERROR);
} catch (error) {
if (error instanceof Error && error.message === IMAGE_SIZE_LIMIT_ERROR) {
throw error;
}
const reason = error instanceof Error ? error.message : String(error);
throw new Error(
`Diff PNG/PDF rendering requires a Chromium-compatible browser. Set browser.executablePath or install Chrome/Chromium. ${reason}`,

View File

@@ -206,6 +206,42 @@ describe("diffs tool", () => {
expect((result?.details as Record<string, unknown>).fileMaxWidth).toBe(1100);
});
it("accepts deprecated format alias for fileFormat", async () => {
const screenshotter = {
screenshotHtml: vi.fn(
async ({
outputPath,
image,
}: {
outputPath: string;
image: { format: string; qualityPreset: string; scale: number; maxWidth: number };
}) => {
expect(image.format).toBe("pdf");
await fs.mkdir(path.dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, Buffer.from("%PDF-1.7"));
return outputPath;
},
),
};
const tool = createDiffsTool({
api: createApi(),
store,
defaults: DEFAULT_DIFFS_TOOL_DEFAULTS,
screenshotter,
});
const result = await tool.execute?.("tool-2format", {
before: "one\n",
after: "two\n",
mode: "file",
format: "pdf",
});
expect((result?.details as Record<string, unknown>).fileFormat).toBe("pdf");
expect((result?.details as Record<string, unknown>).filePath).toMatch(/preview\.pdf$/);
});
it("honors defaults.mode=file when mode is omitted", async () => {
const screenshotter = {
screenshotHtml: vi.fn(async ({ outputPath }: { outputPath: string }) => {