# Write to a file: design Date: 2026-10-16. Status: approved in brainstorming, not implemented. ## Goal The quickshell canvas's To .md operation (quickshell repo, `docs/superpowers/specs/2026-10-16-file-ops-design.md`) asks the model to rewrite a PDF as Markdown and wants the reply in a file, not in the chat. A new command does a one-off request with attachments and writes the reply to disk. ## Protocol In: `{"type": "write", "files": [abs paths], "prompt": "...", "dir": "", "name": "report.md"}`. Out, besides the usual `state`: - `progress {chars}`: the reply's length so far, at most once a second; - `written {path}`: the file is in place; - `error {message, turn: true}`: refused or failed, and nothing is written. ## Behaviour - The request is built like an `ask` (`attach()`, `wire()`, the vision check) but carries no history and adds nothing to the conversation or `history.db`; no `user` or `token` events are sent. - Thinking is off for it: no one reads the reasoning, and it delays the file. No tools are offered. - It shares the turn counter: it stops a reply in flight first, and `stop` ends it, hanging up on llama-server as for a reply. A stopped or failed write leaves no file. - `dir` must be absolute; it is created if missing. The reply goes to a temporary name there and is renamed to the first free name of `name`, `name (1)`, `name (2)` with the suffix kept. - `name` is taken as a base name only; a `/` in it is refused. - A reply wrapped in one Markdown code fence (models often do) is unwrapped. ## Testing `--test` gains: a write against the fake server streaming Markdown lands under a free name next to an existing one, with no conversation row; a stopped write leaves no file; a fenced reply is unwrapped; a relative `dir` and a `name` with `/` are refused.