Skip to content

feat(companion): user β†’ bot image attach/upload (completes images) - #422

Closed
claudiusthebot wants to merge 1 commit into
feat/companion-bot-imagesfrom
feat/companion-user-image-upload
Closed

feat(companion): user β†’ bot image attach/upload (completes images)#422
claudiusthebot wants to merge 1 commit into
feat/companion-bot-imagesfrom
feat/companion-user-image-upload

Conversation

@claudiusthebot

Copy link
Copy Markdown
Collaborator

What

Completes image support (#5) β€” the send direction. The composer gains an attach button; the picked image uploads to the bridge, renders inline in the thread, and its saved path is handed to the model so it can read it.

Bridge / engine

  • server: POST /upload (raw binary body, 25 MB cap, binary-safe reader) saves the file and returns { imagePath, path }. POST /send gains optional imagePath + attachmentPath (SendOptions); text may be empty when an image is attached.
  • index: saveUpload() writes to the workspace uploads dir under a safe, unique name; the upload handler registers it in the media map so it serves back via /media. emitUser() can carry an imagePath (renders in-thread; history keeps a [photo] placeholder). runTurn() appends [Attached image: <path>] to the prompt so the model reads the file.

Client

  • file_picker dependency β€” chosen over image_picker because it supports every target this app ships to (Windows/macOS/Linux + Android); image_picker has no desktop-Linux/Windows impl. macOS entitlements gain files.user-selected.read-only so the sandboxed build can read the pick.
  • BridgeClient.uploadImage() + send() attachment args; AppState.uploadImage() + sendMessage() attachment args.
  • composer: attach button, a removable image preview chip, and a pick β†’ upload (spinner) β†’ send flow. Send is enabled with text or an image; upload failures surface as a system note.

Test

tsc --noEmit clean Β· flutter analyze lib β†’ No issues Β· native-frontend + bridge suites (25) pass.

⚠️ Needs an on-device smoke test: the picker β†’ upload β†’ render loop can't be exercised headless here. Code is analyze/type-clean and the transport mirrors the existing bridge patterns, but please verify the pick + upload on a real device/desktop before relying on it.

Stacked on #421 (shares the /media + protocol foundation; both touch the native bridge). Merge #421 first.

πŸ€– Generated with Claude Code

Completes image support (the send direction). The composer gains an
attach button; the picked image uploads to the bridge, renders inline in
the thread, and its saved path is handed to the model so it can read it.

Bridge/engine:
- server: POST /upload (raw binary body, 25 MB cap, binary-safe reader)
  saves the file and returns { imagePath, path }. POST /send gains
  optional imagePath + attachmentPath (SendOptions); text may be empty
  when an image is attached.
- index: saveUpload() writes to the workspace uploads dir under a safe,
  unique name; the upload handler registers it in the media map so it
  serves back via /media. emitUser() can carry an imagePath (renders in
  the thread; history keeps a "[photo]" placeholder). runTurn() appends
  "[Attached image: <path>]" to the prompt so the model reads the file.

Client:
- file_picker dependency (chosen over image_picker for full desktop +
  Android support, matching this app's targets). macOS entitlements gain
  files.user-selected.read-only so the sandboxed build can read the pick.
- BridgeClient.uploadImage() + send() attachment args; AppState.uploadImage()
  and sendMessage() attachment args.
- composer: attach button, a removable image preview chip, and a
  pick β†’ upload (spinner) β†’ send flow. Send is enabled with text OR an
  image; upload failures surface as a system note.

tsc + flutter analyze clean; native-frontend + bridge suites (25) pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claudiusthebot added a commit that referenced this pull request Jul 1, 2026
Integrate companion overnight work (#415–#422)
@claudiusthebot

Copy link
Copy Markdown
Collaborator Author

Superseded by #423, which integrates the userβ†’bot image upload (along with #415–#422) and is now merged into main. Closing β€” the change is live.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant