Start a stopped session's process when a message is sent to it

Refusing was work handed back: read the status word, find the other
button, press it, type the message again. Sending plainly means "do this
now", and `--resume` puts the new process on the same conversation, so
nothing about the message changes -- only whether there was anything
there to read it.

`POST /sessions/{id}/message` now goes through the manager, which starts
a process first when the session is known to have exited. Only on
`exited`: `unknown` has a process that may well be reading its fifo, and
starting a second CLI on that guess is the fault `session::process`
exists to prevent, so the message goes to the driver as it always did.

The Start button and this ask one function, `start_if_exited`, and want
opposite answers from it -- "there is already a process" is a refusal
worth showing to somebody who pressed Start, and nothing at all to a
message being sent. Deciding it in one place under the one write lock is
also what keeps two requests that arrive together from starting two
CLIs.

Verified over the API and on the emulator: with the session reporting
`exited` and the composer showing a play button, typing a message and
pressing Send started the process, delivered the message and ran the
turn -- transcript order `idle`, `userMessage`, `running`, `idle` -- and
the button became a stop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-08-30 13:56:28 -04:00
1 parent 257f4c85c1
commit 4a122f7b25
4 files changed
+137 -17

No files matched your search

+6
View File
@@ -291,6 +291,12 @@ day:
which keeps the session and its transcript, and `POST .../start` brings
the process back on the same conversation — or delete the session, which
ends the conversation too.
- **Sending a message to a stopped session starts it.** `POST
.../message` goes through `SessionManager::send_message`, which starts a
process first when the session is known to have exited and then delivers
the message to the driver that has one behind it. Only on `exited`:
`unknown` has a process that may well be reading its fifo. So the Start
button is for when you want a process and nothing to say to it yet.
- **Each session directory now holds `process.json`, `stdin.fifo`,
`stdout.log` and `stderr.log`.** `stdout.log` is the driver's input, read
from the byte offset in `process.json`; removing either by hand while the