fix(tests): section-prefix tool API URLs across overhauled suite

#276's overhauled integration tests + QA sweep scripts hit the old
sectionless /api/v1/tools/<id> routes, which 404 after #280 made routes
section-prefixed. Ran scripts/rewrite-tool-paths.ts for literal URLs and
converted dynamic /api/v1/tools/${id} constructions to apiToolPath().
Negative-test paths (nonexistent/fake tools) intentionally left raw.
This commit is contained in:
SnapOtter
2026-06-21 02:30:58 +08:00
parent 5ffa1d55ea
commit d4dc2eae5d
10 changed files with 187 additions and 180 deletions
+162 -162
View File
@@ -200,12 +200,12 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Unicode filenames — specific requested patterns handles filename with ampersand and equals: file&name=special.jpg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Unicode filenames — specific requested patterns handles filename with backslashes: path\\to\\image.png",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Unicode filenames — specific requested patterns handles filename with picture frame emoji: 🖼️.jpg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/border with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/compress with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/convert with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/crop with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/resize with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/rotate with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/border with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/compress with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/convert with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/crop with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/resize with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/rotate with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-final-gaps.test.ts > 1x1 pixel image through previously untested tools adds text overlay to 1x1 pixel image without crash",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-final-gaps.test.ts > 1x1 pixel image through previously untested tools beautifies a 1x1 pixel image without crash",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-final-gaps.test.ts > 1x1 pixel image through previously untested tools converts 1x1 pixel PNG to JPEG without crash",
@@ -516,12 +516,12 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edge cases & adversarial inputs rejects a JSON body on multipart-only endpoint",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edge cases & adversarial inputs rejects a zero-byte file upload",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edge cases & adversarial inputs rejects double-encoded path traversal in download",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata preserves metadata with empty settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata strips specific fields via fieldsToRemove",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata writes metadata and returns downloadable file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata/inspect rejects request with no file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata/inspect returns no exif for metadata-free PNG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata/inspect returns parsed EXIF for JPEG with metadata",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata preserves metadata with empty settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata strips specific fields via fieldsToRemove",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata writes metadata and returns downloadable file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata/inspect rejects request with no file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata/inspect returns no exif for metadata-free PNG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata/inspect returns parsed EXIF for JPEG with metadata",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > File upload/download GET /api/v1/download/:jobId/:filename download is public (no auth required)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > File upload/download GET /api/v1/download/:jobId/:filename downloads an uploaded file successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > File upload/download GET /api/v1/download/:jobId/:filename returns 400 for null bytes in filename",
@@ -542,32 +542,32 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Health & Config GET /api/v1/config/auth returns authEnabled flag without auth",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Health & Config GET /api/v1/health also works with auth",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Health & Config GET /api/v1/health returns only status and version without auth",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image-enhancement processes an image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image-enhancement/analyze returns analysis data",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image/image-enhancement processes an image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image/image-enhancement/analyze returns analysis data",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement preserves JPEG format through enhancement",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement rejects empty file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal POST /api/v1/tools/noise-removal processes with quick tier",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal POST /api/v1/tools/image/noise-removal processes with quick tier",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal accepts JPEG input",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal returns 400 for empty file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal uses default settings when none provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr accepts language auto and enhance params",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr accepts quality param and returns text without engine field",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr backward compat: old engine param is still accepted",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr returns 400 for invalid quality value",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch accepts gap and backgroundColor settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch applies alignment setting",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch applies border and cornerRadius",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch handles resizeMode crop",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch handles resizeMode stretch",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch outputs jpeg when requested",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch respects quality setting for jpeg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch returns 400 with no images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch returns 400 with only one image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch stitches in grid mode with 2 columns",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch stitches two images horizontally with default settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch stitches vertically",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr accepts language auto and enhance params",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr accepts quality param and returns text without engine field",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr backward compat: old engine param is still accepted",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr returns 400 for invalid quality value",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch accepts gap and backgroundColor settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch applies alignment setting",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch applies border and cornerRadius",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch handles resizeMode crop",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch handles resizeMode stretch",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch outputs jpeg when requested",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch respects quality setting for jpeg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch returns 400 with no images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch returns 400 with only one image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch stitches in grid mode with 2 columns",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch stitches two images horizontally with default settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch stitches vertically",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Pipeline GET /api/v1/pipeline/tools excludes tools that are not pipeline-compatible",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Pipeline GET /api/v1/pipeline/tools includes AI tools registered for pipeline use",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Pipeline GET /api/v1/pipeline/tools includes factory-registered tools (resize, crop, convert)",
@@ -630,24 +630,24 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Smart crop format preservation trim mode with new mode name",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing Input format handling processes JPEG input",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing Input format handling processes WebP input",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert converts PNG to JPEG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert converts PNG to WebP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert rejects quality outside valid range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert rejects unsupported format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/crop crops an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/crop returns 400 when required crop fields are missing",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/crop returns 422 when crop exceeds image bounds",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert converts PNG to JPEG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert converts PNG to WebP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert rejects quality outside valid range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert rejects unsupported format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/crop crops an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/crop returns 400 when required crop fields are missing",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/crop returns 422 when crop exceeds image bounds",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/nonexistent returns 404 for a tool that does not exist",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize download URL from resize result is accessible",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize resizes an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize resizes by percentage",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 for invalid settings (negative width)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 for malformed settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 with empty settings (no dimensions given)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/rotate flips horizontally",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/rotate rotates 90 degrees",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/rotate works with default settings (no rotation)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize download URL from resize result is accessible",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize resizes an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize resizes by percentage",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 for invalid settings (negative width)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 for malformed settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 with empty settings (no dimensions given)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/rotate flips horizontally",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/rotate rotates 90 degrees",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/rotate works with default settings (no rotation)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Workspace integrity each job gets a unique workspace (no cross-contamination)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Workspace integrity tool processing creates both input and output in workspace",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Workspace integrity upload creates workspace with input dir",
@@ -1760,8 +1760,8 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Wrong file extension (magic byte detection) detects actual PNG format when filename says .jpg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte / empty file uploads rejects a null-byte-only buffer with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte / empty file uploads rejects a zero-byte file with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/info with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/sharpening with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/image/info with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/image/sharpening with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edit-metadata.test.ts > Author field writes author field (alias for artist)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edit-metadata.test.ts > Comprehensive field writing handles negative date shift",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edit-metadata.test.ts > Comprehensive field writing removes specific fields and adds new ones simultaneously",
@@ -5895,8 +5895,8 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Optimize mode parameter variations optimizes with maximum colors (256)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Optimize mode parameter variations optimizes with minimum colors (2)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Optimize mode processes with custom color/effort settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/gif-tools/info returns metadata for an animated GIF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/gif-tools/info returns pages=1 for a static image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/image/gif-tools/info returns metadata for an animated GIF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/image/gif-tools/info returns pages=1 for a static image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Resize mode edge cases resize without dimensions or percentage passes through",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Resize mode edge cases resizes with both width and height",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Resize mode edge cases resizes with only height specified",
@@ -6716,34 +6716,34 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-metadata.test.ts > pdf-metadata (requires pikepdf) sets metadata and returns the updated values",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-metadata.test.ts > pdf-metadata validation (ungated) rejects title longer than 500 characters with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-page-numbers.test.ts > pdf-page-numbers (requires pdfcpu) adds page numbers and produces a valid output",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image accepts custom DPI values",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image applies black and white color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image applies grayscale color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts a single page to JPG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts a single page to PNG with per-page URLs and ZIP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts multiple pages and returns JSON with ZIP URL",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts specific comma-separated pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to AVIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to GIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to TIFF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to WebP format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image higher DPI produces larger images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image rejects DPI below minimum",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid page range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid settings (DPI above max)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for page number 0",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for reversed page range (start > end)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image uses defaults when no settings provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image verifies ZIP can be downloaded",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image verifies images can be downloaded from per-page URLs",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/info returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/info returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/info returns page count for a valid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/preview returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/preview returns thumbnails for all pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image accepts custom DPI values",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image applies black and white color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image applies grayscale color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts a single page to JPG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts a single page to PNG with per-page URLs and ZIP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts multiple pages and returns JSON with ZIP URL",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts specific comma-separated pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to AVIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to GIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to TIFF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to WebP format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image higher DPI produces larger images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image rejects DPI below minimum",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid page range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid settings (DPI above max)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for page number 0",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for reversed page range (start > end)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image uses defaults when no settings provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image verifies ZIP can be downloaded",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image verifies images can be downloaded from per-page URLs",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/info returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/info returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/info returns page count for a valid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/preview returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/preview returns thumbnails for all pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > Preview endpoint edge cases returns 400 when no file is provided to preview",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-text.test.ts > pdf-to-text (requires PyMuPDF) extracts text and returns a .txt file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-word.test.ts > pdf-to-word (requires pdf2docx) returns 202 (long hint) and the job completes with a docx",
@@ -8751,12 +8751,12 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Unicode filenames — specific requested patterns handles filename with ampersand and equals: file&name=special.jpg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Unicode filenames — specific requested patterns handles filename with backslashes: path\\to\\image.png",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Unicode filenames — specific requested patterns handles filename with picture frame emoji: 🖼️.jpg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/border with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/compress with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/convert with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/crop with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/resize with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/rotate with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/border with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/compress with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/convert with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/crop with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/resize with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-extended.test.ts > Zero-byte file uploads across tools rejects a 0-byte file to /api/v1/tools/image/rotate with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-final-gaps.test.ts > 1x1 pixel image through previously untested tools adds text overlay to 1x1 pixel image without crash",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-final-gaps.test.ts > 1x1 pixel image through previously untested tools beautifies a 1x1 pixel image without crash",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/adversarial-final-gaps.test.ts > 1x1 pixel image through previously untested tools converts 1x1 pixel PNG to JPEG without crash",
@@ -9067,12 +9067,12 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edge cases & adversarial inputs rejects a JSON body on multipart-only endpoint",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edge cases & adversarial inputs rejects a zero-byte file upload",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edge cases & adversarial inputs rejects double-encoded path traversal in download",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata preserves metadata with empty settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata strips specific fields via fieldsToRemove",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata writes metadata and returns downloadable file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata/inspect rejects request with no file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata/inspect returns no exif for metadata-free PNG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/edit-metadata/inspect returns parsed EXIF for JPEG with metadata",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata preserves metadata with empty settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata strips specific fields via fieldsToRemove",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata writes metadata and returns downloadable file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata/inspect rejects request with no file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata/inspect returns no exif for metadata-free PNG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Edit metadata POST /api/v1/tools/image/edit-metadata/inspect returns parsed EXIF for JPEG with metadata",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > File upload/download GET /api/v1/download/:jobId/:filename download is public (no auth required)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > File upload/download GET /api/v1/download/:jobId/:filename downloads an uploaded file successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > File upload/download GET /api/v1/download/:jobId/:filename returns 400 for null bytes in filename",
@@ -9093,32 +9093,32 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Health & Config GET /api/v1/config/auth returns authEnabled flag without auth",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Health & Config GET /api/v1/health also works with auth",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Health & Config GET /api/v1/health returns only status and version without auth",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image-enhancement processes an image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image-enhancement/analyze returns analysis data",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image/image-enhancement processes an image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement POST /api/v1/tools/image/image-enhancement/analyze returns analysis data",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement preserves JPEG format through enhancement",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Image Enhancement rejects empty file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal POST /api/v1/tools/noise-removal processes with quick tier",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal POST /api/v1/tools/image/noise-removal processes with quick tier",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal accepts JPEG input",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal returns 400 for empty file",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Noise Removal uses default settings when none provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr accepts language auto and enhance params",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr accepts quality param and returns text without engine field",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr backward compat: old engine param is still accepted",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr returns 400 for invalid quality value",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/ocr returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch accepts gap and backgroundColor settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch applies alignment setting",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch applies border and cornerRadius",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch handles resizeMode crop",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch handles resizeMode stretch",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch outputs jpeg when requested",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch respects quality setting for jpeg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch returns 400 with no images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch returns 400 with only one image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch stitches in grid mode with 2 columns",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch stitches two images horizontally with default settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/stitch stitches vertically",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr accepts language auto and enhance params",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr accepts quality param and returns text without engine field",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr backward compat: old engine param is still accepted",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr returns 400 for invalid quality value",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > OCR API POST /api/v1/tools/image/ocr returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch accepts gap and backgroundColor settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch applies alignment setting",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch applies border and cornerRadius",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch handles resizeMode crop",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch handles resizeMode stretch",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch outputs jpeg when requested",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch respects quality setting for jpeg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch returns 400 with no images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch returns 400 with only one image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch stitches in grid mode with 2 columns",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch stitches two images horizontally with default settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > POST /api/v1/tools/image/stitch stitches vertically",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Pipeline GET /api/v1/pipeline/tools excludes tools that are not pipeline-compatible",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Pipeline GET /api/v1/pipeline/tools includes AI tools registered for pipeline use",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Pipeline GET /api/v1/pipeline/tools includes factory-registered tools (resize, crop, convert)",
@@ -9181,24 +9181,24 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Smart crop format preservation trim mode with new mode name",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing Input format handling processes JPEG input",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing Input format handling processes WebP input",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert converts PNG to JPEG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert converts PNG to WebP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert rejects quality outside valid range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/convert rejects unsupported format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/crop crops an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/crop returns 400 when required crop fields are missing",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/crop returns 422 when crop exceeds image bounds",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert converts PNG to JPEG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert converts PNG to WebP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert rejects quality outside valid range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/convert rejects unsupported format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/crop crops an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/crop returns 400 when required crop fields are missing",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/crop returns 422 when crop exceeds image bounds",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/nonexistent returns 404 for a tool that does not exist",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize download URL from resize result is accessible",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize resizes an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize resizes by percentage",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 for invalid settings (negative width)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 for malformed settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/resize returns 400 with empty settings (no dimensions given)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/rotate flips horizontally",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/rotate rotates 90 degrees",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/rotate works with default settings (no rotation)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize download URL from resize result is accessible",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize resizes an image successfully",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize resizes by percentage",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 for invalid settings (negative width)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 for malformed settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/resize returns 400 with empty settings (no dimensions given)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/rotate flips horizontally",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/rotate rotates 90 degrees",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Tool processing POST /api/v1/tools/image/rotate works with default settings (no rotation)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Workspace integrity each job gets a unique workspace (no cross-contamination)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Workspace integrity tool processing creates both input and output in workspace",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/api.test.ts > Workspace integrity upload creates workspace with input dir",
@@ -10289,8 +10289,8 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Wrong file extension (magic byte detection) detects actual PNG format when filename says .jpg",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte / empty file uploads rejects a null-byte-only buffer with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte / empty file uploads rejects a zero-byte file with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/info with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/sharpening with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/image/info with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edge-cases.test.ts > Zero-byte file to info and border tools rejects a zero-byte file to /api/v1/tools/image/sharpening with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edit-metadata.test.ts > Author field writes author field (alias for artist)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edit-metadata.test.ts > Comprehensive field writing handles negative date shift",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/edit-metadata.test.ts > Comprehensive field writing removes specific fields and adds new ones simultaneously",
@@ -14257,8 +14257,8 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Optimize mode parameter variations optimizes with maximum colors (256)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Optimize mode parameter variations optimizes with minimum colors (2)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Optimize mode processes with custom color/effort settings",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/gif-tools/info returns metadata for an animated GIF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/gif-tools/info returns pages=1 for a static image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/image/gif-tools/info returns metadata for an animated GIF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > POST /api/v1/tools/image/gif-tools/info returns pages=1 for a static image",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Resize mode edge cases resize without dimensions or percentage passes through",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Resize mode edge cases resizes with both width and height",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/gif-tools.test.ts > Resize mode edge cases resizes with only height specified",
@@ -15069,34 +15069,34 @@
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/passport-photo.test.ts > passport-photo/generate rejects unknown country code without custom dimensions (400)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/passport-photo.test.ts > passport-photo/generate returns 422 when jobId workspace does not exist",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-metadata.test.ts > pdf-metadata validation (ungated) rejects title longer than 500 characters with 400",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image accepts custom DPI values",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image applies black and white color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image applies grayscale color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts a single page to JPG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts a single page to PNG with per-page URLs and ZIP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts multiple pages and returns JSON with ZIP URL",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts specific comma-separated pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to AVIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to GIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to TIFF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image converts to WebP format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image higher DPI produces larger images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image rejects DPI below minimum",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid page range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid settings (DPI above max)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for invalid settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for page number 0",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 for reversed page range (start > end)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image uses defaults when no settings provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image verifies ZIP can be downloaded",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image verifies images can be downloaded from per-page URLs",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/info returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/info returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/info returns page count for a valid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/preview returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf-to-image/preview returns thumbnails for all pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image accepts custom DPI values",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image applies black and white color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image applies grayscale color mode",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts a single page to JPG",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts a single page to PNG with per-page URLs and ZIP",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts multiple pages and returns JSON with ZIP URL",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts specific comma-separated pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to AVIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to GIF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to TIFF format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image converts to WebP format",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image higher DPI produces larger images",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image rejects DPI below minimum",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid page range",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid settings (DPI above max)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for invalid settings JSON",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for page number 0",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 for reversed page range (start > end)",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image uses defaults when no settings provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image verifies ZIP can be downloaded",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image verifies images can be downloaded from per-page URLs",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/info returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/info returns 400 when no file is provided",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/info returns page count for a valid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/preview returns 400 for invalid PDF",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > POST /api/v1/tools/pdf/pdf-to-image/preview returns thumbnails for all pages",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdf-to-image.test.ts > Preview endpoint edge cases returns 400 when no file is provided to preview",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/pdfa-convert.test.ts > pdfa-convert (requires ghostscript) produces a PDF/A candidate with valid PDF header",
"/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/integration/permissions.test.ts > API key ownership scoping admin can see all API keys",
+3 -2
View File
@@ -10,6 +10,7 @@
* If 501, the describe is skipped. If 200/202, we proceed with assertions.
*/
import { apiToolPath } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
@@ -43,7 +44,7 @@ async function isBundleInstalled(
]);
const res = await app.inject({
method: "POST",
url: `/api/v1/tools/${toolId}`,
url: apiToolPath(toolId),
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -81,7 +82,7 @@ async function postTool(
]);
return app.inject({
method: "POST",
url: `/api/v1/tools/${toolId}`,
url: apiToolPath(toolId),
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -9,6 +9,7 @@ import { mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { apiToolPath } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
@@ -50,7 +51,7 @@ async function postTool(
]);
return app.inject({
method: "POST",
url: `/api/v1/tools/${toolId}`,
url: apiToolPath(toolId),
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -76,7 +76,7 @@ describe.skipIf(!qpdfAvailable())("Document depth: split-pdf multipage hero", ()
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/split-pdf",
url: "/api/v1/tools/pdf/split-pdf",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -117,7 +117,7 @@ describe.skipIf(!qpdfAvailable())("Document depth: merge-pdf real heroes", () =>
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/merge-pdf",
url: "/api/v1/tools/pdf/merge-pdf",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -154,7 +154,7 @@ describe.skipIf(!gsAvailable())("Document depth: compress-pdf multipage hero", (
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/compress-pdf",
url: "/api/v1/tools/pdf/compress-pdf",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -191,7 +191,7 @@ describe("Document depth: pdf-to-image multipage hero", () => {
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/pdf-to-image",
url: "/api/v1/tools/pdf/pdf-to-image",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -223,7 +223,7 @@ describe("Document depth: pdf-to-image multipage hero", () => {
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/pdf-to-image/info",
url: "/api/v1/tools/pdf/pdf-to-image/info",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -5,6 +5,7 @@
* verifying output dimensions, file validity, and metadata via Sharp decode.
*/
import { apiToolPath } from "@snapotter/shared";
import sharp from "sharp";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../../fixtures/index.js";
@@ -48,7 +49,7 @@ async function postTool(
]);
return app.inject({
method: "POST",
url: `/api/v1/tools/${toolId}`,
url: apiToolPath(toolId),
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": ct,
@@ -205,7 +206,7 @@ describe("Image depth: extract metadata from EXIF hero", () => {
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/info",
url: "/api/v1/tools/image/info",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -233,7 +234,7 @@ describe("Image depth: extract metadata from EXIF hero", () => {
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/info",
url: "/api/v1/tools/image/info",
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -10,6 +10,7 @@ import { mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { ffmpegAvailable, probeMedia } from "@snapotter/media-engine";
import { apiToolPath } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
@@ -49,7 +50,7 @@ async function postTool(
]);
return app.inject({
method: "POST",
url: `/api/v1/tools/${toolId}`,
url: apiToolPath(toolId),
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": contentType,
@@ -15,7 +15,7 @@
* cannot silently drift when tools are added or removed.
*/
import { TOOLS } from "@snapotter/shared";
import { apiToolPath, TOOLS } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { getRegisteredToolIds } from "../../../apps/api/src/routes/tool-factory.js";
import { TOOL_DISPLAY_MODES } from "../../../apps/web/src/lib/tool-display-modes.js";
@@ -97,7 +97,7 @@ describe("catalog integrity launch gate", () => {
for (const tool of TOOLS) {
const res = await testApp.app.inject({
method: "POST",
url: `/api/v1/tools/${tool.id}`,
url: apiToolPath(tool.id),
headers: {
authorization: `Bearer ${adminToken}`,
"content-type": "application/json",
@@ -15,6 +15,7 @@
*/
import { spawnSync } from "node:child_process";
import { apiToolPath } from "@snapotter/shared";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { fixtures, readFixture } from "../../fixtures/index.js";
import {
@@ -58,7 +59,7 @@ async function postTool(
]);
return app.inject({
method: "POST",
url: `/api/v1/tools/${toolId}`,
url: apiToolPath(toolId),
headers: { authorization: `Bearer ${token}`, "content-type": ct },
body,
});
@@ -94,7 +95,7 @@ describe("cross-modality launch smoke", () => {
]);
const res = await app.inject({
method: "POST",
url: "/api/v1/tools/rotate",
url: "/api/v1/tools/image/rotate",
headers: { "content-type": contentType },
body,
});
+2 -1
View File
@@ -12,6 +12,7 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { apiToolPath } from "@snapotter/shared";
// ── Config ────────────────────────────────────────────────────────
const BASE = "http://localhost:13499";
@@ -530,7 +531,7 @@ async function main() {
let res: Response;
try {
res = await fetch(`${BASE}/api/v1/tools/${tool.id}`, {
res = await fetch(`${BASE}${apiToolPath(tool.id)}`, {
method: "POST",
body: form,
signal: controller.signal,
+2 -1
View File
@@ -3,6 +3,7 @@
import { execFileSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { apiToolPath } from "@snapotter/shared";
const BASE = "http://localhost:13499";
@@ -63,7 +64,7 @@ async function run(toolId: string, file: string, settings: Record<string, unknow
const fd = new FormData();
fd.append("file", new Blob([buf]), path.basename(file));
fd.append("settings", JSON.stringify(settings));
const res = await fetch(`${BASE}/api/v1/tools/${toolId}`, { method: "POST", body: fd });
const res = await fetch(`${BASE}${apiToolPath(toolId)}`, { method: "POST", body: fd });
if (res.status === 200) {
const j = (await res.json()) as { downloadUrl?: string };
if (j.downloadUrl) {