-
Notifications
You must be signed in to change notification settings - Fork 339
Remove sharp dependency #145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Greptile OverviewGreptile SummaryThis PR removes the Key changes:
Approach: The resizing now executes in the browser context rather than in Node.js, which aligns with the CSP-safe design goal. The PNG parsing correctly reads the first 24 bytes to extract width/height from the IHDR chunk structure. Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as MCP Client
participant Handler as handleScreenshot
participant CDP as Chrome DevTools Protocol
participant Parser as parsePngDimensions
participant Browser as resizeImageInBrowser
participant Canvas as OffscreenCanvas
Client->>Handler: screenshot request
Handler->>CDP: Page.captureScreenshot (PNG, base64)
CDP-->>Handler: base64 screenshot data
Handler->>Parser: parse PNG dimensions
Parser->>Parser: decode first 24 bytes
Parser->>Parser: validate PNG signature
Parser->>Parser: extract width/height from IHDR
Parser-->>Handler: {width, height}
Handler->>Handler: calculate shrink factor
alt shrink < 1 (needs resize)
Handler->>Browser: page.evaluate with base64 data
Browser->>Browser: atob to decode base64
Browser->>Browser: create Blob from bytes
Browser->>Canvas: createImageBitmap from Blob
Canvas-->>Browser: ImageBitmap
Browser->>Canvas: OffscreenCanvas.drawImage
Browser->>Canvas: convertToBlob (PNG)
Browser->>Browser: btoa to encode as base64
Browser-->>Handler: resized base64 data
end
Handler->>Handler: register screenshot resource
Handler->>Client: return screenshot with dimensions
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 files reviewed, 2 comments
| let binary = ""; | ||
| for (let i = 0; i < resultBytes.length; i++) { | ||
| binary += String.fromCharCode(resultBytes[i]); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P0] String concatenation for binary data will corrupt the image. In JavaScript, strings are UTF-16 encoded and string concatenation with String.fromCharCode() can mangle bytes > 127. Large images (hundreds of KB) will trigger this, resulting in corrupted/invalid PNG data returned to the caller.
Use TextDecoder and proper binary handling instead:
| let binary = ""; | |
| for (let i = 0; i < resultBytes.length; i++) { | |
| binary += String.fromCharCode(resultBytes[i]); | |
| } | |
| const resultBytes = new Uint8Array(arrayBuffer); | |
| return btoa(String.fromCharCode(...resultBytes)); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/tools/screenshot.ts
Line: 81:84
Comment:
[P0] String concatenation for binary data will corrupt the image. In JavaScript, strings are UTF-16 encoded and string concatenation with `String.fromCharCode()` can mangle bytes > 127. Large images (hundreds of KB) will trigger this, resulting in corrupted/invalid PNG data returned to the caller.
Use `TextDecoder` and proper binary handling instead:
```suggestion
const resultBytes = new Uint8Array(arrayBuffer);
return btoa(String.fromCharCode(...resultBytes));
```
How can I resolve this? If you propose a fix, please make it concise.| const binaryString = atob(data); | ||
| const bytes = new Uint8Array(binaryString.length); | ||
| for (let i = 0; i < binaryString.length; i++) { | ||
| bytes[i] = binaryString.charCodeAt(i); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P0] Same binary corruption issue. String concatenation in a loop will corrupt bytes > 127 when decoding base64. For screenshots that are several hundred KB or more, this loop builds corrupted binary data that will fail bitmap creation or produce incorrect images.
Fix with spread operator:
| const binaryString = atob(data); | |
| const bytes = new Uint8Array(binaryString.length); | |
| for (let i = 0; i < binaryString.length; i++) { | |
| bytes[i] = binaryString.charCodeAt(i); | |
| } | |
| const binaryString = atob(data); | |
| const bytes = new Uint8Array(binaryString.length); | |
| for (let i = 0; i < binaryString.length; i++) { | |
| bytes[i] = binaryString.charCodeAt(i); | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/tools/screenshot.ts
Line: 55:59
Comment:
[P0] Same binary corruption issue. String concatenation in a loop will corrupt bytes > 127 when decoding base64. For screenshots that are several hundred KB or more, this loop builds corrupted binary data that will fail bitmap creation or produce incorrect images.
Fix with spread operator:
```suggestion
const binaryString = atob(data);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
```
How can I resolve this? If you propose a fix, please make it concise.Replaces the native sharp dependency with PNG header parsing and OffscreenCanvas-based image resizing. This approach: - Uses PNG IHDR chunk parsing for dimension extraction (no dependencies) - Leverages OffscreenCanvas and createImageBitmap for GPU-accelerated resizing - Bypasses CSP restrictions by working with raw binary data instead of URLs - Returns screenshot dimensions in the MCP response Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Replace Buffer.from/readUInt32BE with atob/Uint8Array/DataView in screenshot.ts - Replace fs.readFileSync with ESM JSON import in program.ts - Remove fs, path, and fileURLToPath imports Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Create src/local.ts that imports dotenv and re-exports from index - Remove dotenv import from src/index.ts (Smithery entry point) - Update src/program.ts to import from local.js for CLI usage This keeps src/index.ts clean for Smithery's serverless environment while preserving dotenv functionality for local development. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Remove dotenv from production dependencies - Add @dotenvx/dotenvx as dev dependency for local development - Delete src/local.ts (no longer needed) - Update program.ts to import directly from index.js This eliminates dotenv from the bundle entirely, making the codebase fully V8-compatible for Smithery deployment. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
85667aa to
c1f6df8
Compare
Summary
Eliminates the
sharpnative dependency by replacing it with browser-native alternatives for image processing. The screenshot tool now uses PNG header parsing for dimension extraction and OffscreenCanvas with createImageBitmap for GPU-accelerated resizing, working with raw binary data to bypass CSP restrictions.Changes
Testing
🤖 Generated with Claude Code