1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# 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": "<abs>",
"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.
|