-
Notifications
You must be signed in to change notification settings - Fork 4.1k
feat: paste images in cn #7503
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
feat: paste images in cn #7503
Conversation
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.
7 issues found across 11 files
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| if (part.type === "text") { | ||
| return part.text; | ||
| } else if (part.type === "imageUrl") { | ||
| return "[Image]"; |
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.
Images are reduced to “[Image]” and no binary or URL is transmitted in remote mode, so pasted images won’t be available to the remote server.
Prompt for AI agents
Address the following comment on extensions/cli/src/ui/hooks/useChat.ts at line 343:
<comment>Images are reduced to “[Image]” and no binary or URL is transmitted in remote mode, so pasted images won’t be available to the remote server.</comment>
<file context>
@@ -308,20 +311,45 @@ export function useChat({
+ if (part.type === "text") {
+ return part.text;
+ } else if (part.type === "imageUrl") {
+ return "[Image]";
+ }
+ return "";
</file context>
| hasImages: !!(imageMap && imageMap.size > 0), | ||
| imageCount: imageMap?.size || 0, | ||
| }); | ||
| const newUserMessage = await formatMessageWithFiles( |
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.
Images are processed (resize/base64) even in remote mode where only a text placeholder is sent; avoid this upfront work by skipping image processing in remote mode or moving formatting after the remote-mode branch.
Prompt for AI agents
Address the following comment on extensions/cli/src/ui/hooks/useChat.ts at line 319:
<comment>Images are processed (resize/base64) even in remote mode where only a text placeholder is sent; avoid this upfront work by skipping image processing in remote mode or moving formatting after the remote-mode branch.</comment>
<file context>
@@ -308,20 +311,45 @@ export function useChat({
+ hasImages: !!(imageMap && imageMap.size > 0),
+ imageCount: imageMap?.size || 0,
+ });
+ const newUserMessage = await formatMessageWithFiles(
message,
attachedFiles,
</file context>
| ); | ||
|
|
||
| const output = lastFrame(); | ||
| expect(output).toContain("Start"); |
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.
Assertion is too weak to verify whitespace preservation; assert the expected trailing/leading spaces to prevent regressions.
Prompt for AI agents
Address the following comment on extensions/cli/src/ui/components/MemoizedMessage.formatDisplay.test.tsx at line 129:
<comment>Assertion is too weak to verify whitespace preservation; assert the expected trailing/leading spaces to prevent regressions.</comment>
<file context>
@@ -0,0 +1,144 @@
+ );
+
+ const output = lastFrame();
+ expect(output).toContain("Start");
+ expect(output).toContain("end");
+ expect(output).toContain('{"type":"unknown","data":{"some":"data"}}');
</file context>
| } | ||
|
|
||
| // WebP: RIFF + WEBP at offset 8 | ||
| if (signature[0] === 0x52 && signature[1] === 0x49 && buffer.length >= 12) { |
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.
Tighten the RIFF signature check for WebP detection to validate all four bytes (RIFF) before checking for WEBP at offset 8.
Prompt for AI agents
Address the following comment on extensions/cli/src/ui/hooks/useChat.helpers.ts at line 110:
<comment>Tighten the RIFF signature check for WebP detection to validate all four bytes (RIFF) before checking for WEBP at offset 8.</comment>
<file context>
@@ -19,6 +19,194 @@ import { shouldAutoCompact } from "../../util/tokenizer.js";
+ }
+
+ // WebP: RIFF + WEBP at offset 8
+ if (signature[0] === 0x52 && signature[1] === 0x49 && buffer.length >= 12) {
+ const webpSig = buffer.subarray(8, 12);
+ if (
</file context>
| if (signature[0] === 0x52 && signature[1] === 0x49 && buffer.length >= 12) { | |
| if (signature[0] === 0x52 && signature[1] === 0x49 && signature[2] === 0x46 && signature[3] === 0x46 && buffer.length >= 12) { |
| addImage(imageBuffer: Buffer): string { | ||
| this._imageCounter++; | ||
| const placeholder = `[Image #${this._imageCounter}]`; | ||
| this._imageMap.set(placeholder, imageBuffer); |
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.
Stores raw image buffers without validating size/count, risking excessive memory usage; enforce reasonable limits before storing.
Prompt for AI agents
Address the following comment on extensions/cli/src/ui/TextBuffer.ts at line 200:
<comment>Stores raw image buffers without validating size/count, risking excessive memory usage; enforce reasonable limits before storing.</comment>
<file context>
@@ -189,6 +193,26 @@ export class TextBuffer {
+ addImage(imageBuffer: Buffer): string {
+ this._imageCounter++;
+ const placeholder = `[Image #${this._imageCounter}]`;
+ this._imageMap.set(placeholder, imageBuffer);
+ this.insertText(placeholder);
+ return placeholder;
</file context>
| } else if (platform === "win32") { | ||
| // Windows: Use PowerShell to save clipboard image | ||
| await execAsync( | ||
| `powershell -command "Get-Clipboard -Format Image | Set-Content -Path '${tempImagePath}' -Encoding Byte"`, |
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.
Windows image save uses Set-Content on an Image object, producing invalid output; use Image.Save(...) to write a real PNG instead.
Prompt for AI agents
Address the following comment on extensions/cli/src/ui/hooks/useUserInput.ts at line 86:
<comment>Windows image save uses Set-Content on an Image object, producing invalid output; use Image.Save(...) to write a real PNG instead.</comment>
<file context>
@@ -10,6 +11,102 @@ interface ControlKeysOptions {
+ } else if (platform === "win32") {
+ // Windows: Use PowerShell to save clipboard image
+ await execAsync(
+ `powershell -command "Get-Clipboard -Format Image | Set-Content -Path '${tempImagePath}' -Encoding Byte"`,
+ );
+ } else if (platform === "linux") {
</file context>
| `powershell -command "Get-Clipboard -Format Image | Set-Content -Path '${tempImagePath}' -Encoding Byte"`, | |
| `powershell -command "$img=Get-Clipboard -Format Image; if ($img) { $img.Save('${tempImagePath.replace(/'/g, "''")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`, |
package.json
Outdated
| "prettier-plugin-tailwindcss": "^0.6.8", | ||
| "typescript": "^5.6.3" | ||
| }, | ||
| "optionalDependencies": { |
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.
Adds multiple platform-specific sharp packages as root optionalDependencies, but no code imports or uses sharp; this adds install time/size and maintenance overhead. Prefer adding 'sharp' only in the specific package that needs it (which will pull the correct platform binaries) or defer until the code actually uses it.
Prompt for AI agents
Address the following comment on package.json at line 20:
<comment>Adds multiple platform-specific sharp packages as root optionalDependencies, but no code imports or uses sharp; this adds install time/size and maintenance overhead. Prefer adding 'sharp' only in the specific package that needs it (which will pull the correct platform binaries) or defer until the code actually uses it.</comment>
<file context>
@@ -16,5 +16,13 @@
"prettier-plugin-tailwindcss": "^0.6.8",
"typescript": "^5.6.3"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "^0.33.5",
+ "@img/sharp-darwin-x64": "^0.33.5",
</file context>
|
🎉 This PR is included in version 1.12.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.12.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Description
Image pasting support in cn via ctrl+V
Summary by cubic
Add image pasting to the CLI chat via Ctrl+V. Pasted images appear as [Image #n] in the input, are sent as inline data URLs, and display as placeholders in history.
New Features
Dependencies