Skip to content

feat: attach pasted image file paths like pasted images - #1123

Draft
josemonteiro wants to merge 4 commits into
masterfrom
feature/typed-image-paths
Draft

feat: attach pasted image file paths like pasted images#1123
josemonteiro wants to merge 4 commits into
masterfrom
feature/typed-image-paths

Conversation

@josemonteiro

@josemonteiro josemonteiro commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Pasting or dragging an image file path into the prompt now attaches the image inline just like pasting the image itself: the model receives it as an ImageContent block with the standard [Image #N] marker. Plain typed paths are left alone so filename mentions in prose don’t auto-attach.

Why

Previously, a pasted/dropped image path arrived as plain text, so the model could only see the image if it chose to call the read tool — whose upstream resize pipeline can silently drop the image, leaving the model blind with no surfaced error. Pasting the image itself worked because Kimchi’s input transform attaches pasted images directly. This change gives pasted/dropped paths the same parity while avoiding accidental attachments when the user simply types a filename.

What changed

  • src/utils/typed-image-paths.ts (new) — pure extractTypedImagePaths(text, cwd): quote-aware tokenizer, image-extension filter, URL/file:// rejection, ~ expansion + cwd resolution, size/type validation, dedup by resolved path preserving first-appearance order.
  • src/extensions/clipboard-image.ts — on session_start, subscribes to raw terminal input to detect bracketed-paste sequences; only when the current input originated from a paste or drop does the input handler convert matching image paths to ImageContent. Path images append after existing attachments so marker numbering stays consistent. Vision-less models keep plain text as the fallback.
  • src/utils/typed-image-paths.test.ts (new) — 18 extractor unit tests.
  • src/extensions/clipboard-image.test.ts — wiring tests updated to simulate paste via bracketed-paste markers; added test verifying typed paths are left untouched.
  • tests/e2e/tui/typed-image-path.test.ts — E2E updated to simulate paste/drop with bracketed-paste markers.

Verification

  • pnpm run check (biome + tsc): clean
  • Unit and E2E tests updated for the paste-only behavior

Typing an image path ("/Users/jose/Downloads/A-Cat.jpg what's this?") arrived as plain text, so the model only saw the image if it chose to call the read tool — whose upstream processImage/Photon resize pipeline can silently drop the image. Pasting the same image worked because the input transform attaches pasted images directly.

The clipboard-image input handler now extracts typed paths (absolute, ~/, relative, quoted) via the pure extractTypedImagePaths() util, validates them with readImageFileFromDisk(), and attaches them as ImageContent with the standard [Image #N] markers. Path images append after pasted/attached images so marker numbering and merge order are unchanged. Vision-less models keep plain text so the read tool remains the fallback.

Tests: 18 extractor unit tests, 7 input-handler wiring tests, 1 TUI e2e test (typed path -> marker visible -> image in request payload).

Co-Authored-By: Kimchi <noreply@kimchi.dev>
@josemonteiro josemonteiro added the new feature Introduces a new feature label Sep 2, 2026
@kimchi-review

kimchi-review Bot commented Sep 2, 2026

Copy link
Copy Markdown

Kimchi Code Review

Property Value
Commit f423f43
Author @josemonteiro
Files changed 0
Review status Completed
Comments 1 (1 warning)
Duration 134s

Summary

📊 Review Score: 88/100 (overall code quality — 0 lowest, 100 highest)
⏱️ Estimated effort to review: 3/5 (1 = trivial, 5 = very complex)

🧪 Tests: yes — Comprehensive coverage: unit tests for the new extractTypedImagePaths utility cover absolute/relative/~/ paths, quoting, punctuation stripping, dedup, URLs, missing files, and directories; integration tests in clipboard-image.test.ts cover marker numbering, vision-less model fallback, and missing-path behavior; an E2E TUI test verifies the full user turn attaches the image to the completion request.

📝 Found 1 issue(s). See inline comments for details.

What to expect

Kimchi will analyze the changes in this pull request and post:

  • A summary of the overall changes
  • Inline comments on specific lines with findings categorized by issue type

The review typically completes within a few minutes. This comment will be updated once the review is ready.

Interact with Kimchi
  • @getkimchi review — re-trigger a full review on the latest commit
  • @getkimchi summary — regenerate the PR summary
  • @getkimchi ignore — skip this PR (no review will be posted)
  • Reply to any inline comment to ask follow-up questions or request clarification
Configuration

Reviews are configured by your organization admin.
Review instructions, excluded directories, and severity thresholds can be adjusted per repository in the Kimchi dashboard.


Powered by Kimchi — AI-powered code review by CAST AI

@kimchi-review kimchi-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📊 Review Score: 88/100 (overall code quality — 0 lowest, 100 highest)
⏱️ Estimated effort to review: 3/5 (1 = trivial, 5 = very complex)

🧪 Tests: yes — Comprehensive coverage: unit tests for the new extractTypedImagePaths utility cover absolute/relative/~/ paths, quoting, punctuation stripping, dedup, URLs, missing files, and directories; integration tests in clipboard-image.test.ts cover marker numbering, vision-less model fallback, and missing-path behavior; an E2E TUI test verifies the full user turn attaches the image to the completion request.

📝 Found 1 issue(s). See inline comments for details.

Comment thread src/extensions/clipboard-image.ts Outdated
josemonteiro and others added 3 commits September 3, 2026 15:31
Detect bracketed-paste sequences in raw terminal input so typed image-path
mentions are left alone while pasted or dragged paths still get attached as
inline images. Updates unit and E2E tests.

Co-Authored-By: Kimchi <noreply@kimchi.dev>
- Remove defensive optional chaining on ctx.ui.onTerminalInput (required method)
- Extract teardownTerminalInput() helper to deduplicate session_start/shutdown cleanup
- Reset lastInputWasPaste on non-paste terminal input so paste-then-type
  doesn't wrongly attach image paths (sticky flag bug)
- Replace as-unknown-as cast in test mock with typed _mockTerminalInput handle
- Add regression test for paste-then-type scenario

Co-Authored-By: Kimchi <noreply@kimchi.dev>
The Enter key (\r) from terminal.submit() was hitting the else branch and
clearing lastInputWasPaste before the input handler ran, so pasted image
paths were never attached in the E2E test. Add hasTypedContent() to only
reset the flag on actual printable typed content, ignoring control keys
and CSI escape sequences.

Co-Authored-By: Kimchi <noreply@kimchi.dev>
@josemonteiro josemonteiro changed the title feat: attach typed image file paths like pasted images feat: attach pasted image file paths like pasted images Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new feature Introduces a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant