stella whistle
Send steering instructions to every live non-interactive session on this machine, or to a few you pick.
A message reaches a running run or goal session, whether it's running in the foreground or supervised by a daemon, without you switching to its window. For example, "stop running the full workspace build, let CI handle the gate" lands in every matching session at once.
Synopsis
stella whistle "<message>"
stella whistle "<message>" --session <id>
stella whistle "<message>" --session <id> --session <id>
stella whistle "<message>" --deepHow delivery works
Each session you can reach opens a small Unix domain socket next to its normal session files when it starts. It listens on the same steering channel that stella chat's > command and stella-serve's POST /v1/turns/{id}/steer also use, one from inside the process and one over HTTP. stella whistle is a separate process that connects to that same channel over the socket, sends your message, and waits for confirmation it arrived.
Your message lands at the target's next safe point, always between model calls, never in the middle of using a tool. The current turn is never paused; it takes in your message and keeps going. The model sees it wrapped as [whistle — steering from another session] <message>, so it reads it as an instruction to prioritize rather than just another passing comment.
Targeting
Leave off --session and your message reaches every session that stella resume --list shows as currently live. Pass --session <id> (you can repeat this flag) to send it to specific sessions only. If an id isn't currently live, or never existed, stella reports it as unreachable instead of just skipping it silently.
$ stella whistle "stop running the full workspace build, let CI handle the gate"
delivered ses-1785956826121-25167 stella: migrate the config loader to serde
unreachable ses-1785956700004 stella: fix the flaky test (no listener — the session isn't currently reachable)stella whistle exits with a non-zero code if any target session could not be reached, after it prints the outcome for every session. Every target is contacted at the same time, so a session whose socket is stale slows down only its own line.
Reaching a session's workers
A whistle normally lands on a session's lead — the agent you talk to. An interactive session can also be driving worker lanes (a task worker, a sidecar prompt), and those never hear a plain whistle. Add --deep and the same message lands at each live worker lane's next safe point as well:
stella whistle "stop touching the release branch" --deepA session with no workers treats --deep exactly like a plain whistle.
Broadcasting from inside a session
You do not need a second terminal. In stella chat, type the message with a broadcast address in front of it:
>@all stop touching the release branch
>@ses-1785956826121-25167 run the tests first
>@all --deep stop touching the release branch>@all reaches every other live session on this machine, >@<id> one of them, and --deep right after the address reaches their worker lanes too. The outcome for every session appears as a note in your transcript, in the same rows the command prints. The message goes out at once — it never waits behind your own agent's turn — and your own session is never a target of its own broadcast.
Stopping the room, and keeping what you said
The lines above steer. To stop every agent instead, put three arrows in front of the address and a bang run after it:
>>> @agents ! stop the compile
>>> @agents !! use short sentences
>>> @agents !!! do not force-pushEach target's running turn stops at its next safe point, and your words run next there. The three arrows are deep, so worker lanes hear them with no flag to remember. @agents and @all both mean the room; one session id in their place aims the same line at one session.
The bang run says how hard the words push, exactly as it does when you type it with no address (stella chat):
| Line | What it does |
|---|---|
>>> @agents ! <text> | stops every live session and runs the words there |
>>> @agents !! <text> | the same, and keeps the words as guidance for this workspace |
>>> @agents !!! <text> | the same, and keeps the words as a rule |
What is kept is one context record, written once for the workspace by the session you typed in. Sessions that start later read it the ordinary way. A stop aimed at the room reaches your own session too, because you are in the room; a stop aimed at one other id leaves you alone.
A fourth bang is a typo, not a stronger rule, so >>> @agents !!!! … broadcasts nothing and goes out as the prompt it reads as.
The stella whistle command has no flag for this yet: the stop is a composer form today.
What is reachable today
Foreground stella run, any turn driven by a wrapper plugin, and both of stella chat's interactive modes (the default one and --plain) can all receive a whistle. So can daemon-supervised runs of the same, since supervision uses the exact same code path.
Interactive mode opens a fresh steering channel for each turn, so between turns it listens through a session-level channel instead. If you whistle an idle session, the message waits and gets shown to the model as soon as the next turn starts. If you whistle a session mid-turn, it arrives at that turn's next safe point, just like any other message.
Not reachable yet:
- Sessions hosted by
stella-serverun in a separate program. It has its own steering route, but a session it hosts is not listed in any registrystella whistlecan check, and neither its address nor its access token is saved to a file on disk. So right now, the problem is finding these sessions, not sending to them.
Platform support
This command only works on Unix systems, because the underlying tool (tokio::net::UnixListener) has no Windows version, and stella does not ship a Windows binary yet. On any non-Unix build, every session is reported as unreachable instead of the command doing nothing silently.