From e1119fa89a919914c2e388ddc9d9e83096ff7709 Mon Sep 17 00:00:00 2001 From: Lovebug MCP Date: Fri, 3 Jul 2026 09:48:28 +0000 Subject: [PATCH] =?UTF-8?q?mcp:=20project-plan=20=E2=80=94=20Dispatch=20At?= =?UTF-8?q?tachments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/Dev/dispatch-attachments.md | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Sources/Dev/dispatch-attachments.md diff --git a/Sources/Dev/dispatch-attachments.md b/Sources/Dev/dispatch-attachments.md new file mode 100644 index 0000000..877dad6 --- /dev/null +++ b/Sources/Dev/dispatch-attachments.md @@ -0,0 +1,53 @@ +--- +created: '2026-07-03' +path: Sources/Dev +project: dispatch-attachments +tags: +- dispatch +- python +type: project-plan +--- + +## Goal + +Add an attachment capability to the petal-dispatch web client so the user can send images to Lovebug in chat. The immediate goal is clipboard-pasted images reaching the Lovebug/conductor turn so Lovebug can see and discuss them. The longer-term goal is a durable per-session file share, documented here but not built yet. + +## Locked Decisions + +- P1 source is clipboard paste only. A file-picker and live screen-capture are out of P1 scope; the user is comfortable pasting. +- P1 target is the Lovebug/conductor turn only, not workers. +- P1 images are ephemeral with respect to petal-dispatch's message and journal DB. They are not persisted there, so the web chat log shows a small marker rather than the image, and render history stays unaffected. This was the user's explicit call. +- Images DO persist in the claude CLI session transcript, so Lovebug retains them across resume within the session. This is accepted and desired. +- P1 transport is a base64 image content-block on the stream-json user turn. No file storage in P1. +- No-build-step constraint holds. Frontend is inline JS and CSS in index.html. Backend is a petal_dispatch Python change. + +## Open Items + +- Token weight. A base64 image rides in the transcript and replays on every subsequent turn until the session compacts, so a large screenshot is recurring context cost. A later mitigation is client-side downscaling before send. +- Web-log marker design. Since the image is not stored for render, the log needs a small placeholder chip such as a paperclip glyph where the image would be. +- Fused restart timing. The backend change lands in the never-restart fused petal-dispatch, so activation needs a chosen restart window; the conversation resumes via the CLI resume path but the restart is disruptive. + +## Build Phases + +### Phase 1 — clipboard image into the conductor turn (active) + +Frontend, served live with no restart: +- Handle paste of an image into the composer. Hold it as base64 in memory, show a paperclip marker chip, and allow removing it before send. +- On send, include the image data alongside the existing chat POST body. + +Backend, needs a fused restart to activate: +- Accept the image on the chat endpoint. +- Build the stream-json user message with an image content-block plus the text block, and write that to the claude subprocess stdin. +- Do not write the image into the message or journal DB. Store only a lightweight marker so the log can show a placeholder. + +Outcome: the user pastes a screenshot, Lovebug sees and can discuss it, and render history is undisturbed. + +### Phase 2 — session file share (documented, future) + +A durable per-session file store on the server. Browser uploads land in a per-session folder under the run directory, and files are referenced by path into the relevant claude turn. Requirements: the share folder must sit inside the granted add-dir scope so worker processes can read uploads; upload safety covering size limits and type checks and path-traversal prevention; a listing and cleanup story; and correct host placement given the split ingress and executor topology. There is no current send-now access-later use case, so this stays parked until one appears. + +## Notes + +- The two-histories distinction is central. petal-dispatch's message DB drives the rendered web log; the claude CLI transcript drives Lovebug's replayed context. P1 deliberately writes to the second and not the first. +- Frontend serves live; only the Python backend needs the fused restart, so plan the cutover accordingly. +- Execution routes to a worker building against an isolated git worktree so the live-served checkout is not disturbed mid-build. \ No newline at end of file