# The handoff, and the one platform hook it needs This plugin exists for a single step: **the generated prompt should not reach a clipboard.** It should open a chat session with the agent, already containing the prompt, pointed at a directory on this machine. That step is not finished, and the reason is worth writing down precisely, because it is a platform gap rather than an unwritten function. --- ## Why a plugin cannot do this today **`/api/chat` has no session-creation route.** Reading `src/servers/api/chat/chat.ts`, the surface is `GET /sessions`, `GET /sessions/:id`, `DELETE /sessions/:id`, the task verbs and the usage and model readers. There is no `POST /sessions`. A session is created by the **browser** opening `/api/chat/ws` and sending its first message. The socket is the constructor. So there is nothing a plugin's server can POST to in order to start one, and nothing it can hand a prompt to. That is a reasonable design — it keeps session lifetime tied to a live connection — but it means "start a session containing this text" is not expressible from a plugin. ## What is built `POST /api/m3e-canvas/_handoff` takes `{ prompt, title }`, holds it in memory against a one-time id with a ten-minute expiry, and answers: ```json { "id": "…", "chatUrl": "/chat/new?handoff=…", "ready": false } ``` `GET /api/m3e-canvas/_handoff/:id` collects it once and forgets it. A handoff belongs to whoever made it; another user asking is told it does not exist rather than that it is theirs. `ready: false` is the honest part of the response. **Nothing reads `?handoff=` yet.** Meanwhile `onExport` returns `false`, so the editor still writes the clipboard. The feature is degraded rather than absent: you get the prompt, you just paste it yourself — which is exactly what upstream does, so nothing is worse than before. ## What would finish it One small change, in the platform rather than here. `/chat/new` reads a `handoff` search parameter, and when present fetches `/api/m3e-canvas/_handoff/:id` and puts the prompt in the composer before the first send. That is a few lines in `SessionListPage`, and it is deliberately **not** written here for two reasons. It is a platform change, so it belongs to whoever owns the chat screen rather than arriving as a side effect of installing a drawing tool. And a plugin reaching into another surface's composer is the kind of coupling that is easy to add and unpleasant to find later. ### The shape worth arguing about first If this is worth doing at all, it is probably worth doing **generically** — `?handoff=/`, resolved against the plugin that minted it, so the next plugin that wants to hand work to the agent does not add a second parameter. `todo/sendoff/` is already circling the same idea from another direction. Until that is decided, the seam here is small enough to throw away and specific enough to be honest about what it does not do. ## The other half, unstarted Even with the composer prefilled, "the agent writes the app" needs somewhere to write it. A design has no notion of a project directory, and picking one is a product decision: - a directory the user names when handing off - a per-design directory remembered on the row - whatever the chat session's own working directory already is The third is the least work and probably the right default, since a session started from a dashboard already has a directory. It is not implemented, and the row has no column for it.