stella whistle

Broadcast steering guidance to every live non-interactive session on this machine, or a chosen few.

A message reaches a running run or goal session — foreground or daemon-supervised alike — without switching to its window: "stop running the full workspace build, let CI handle the gate" lands in every one of them at once.

Synopsis

stella whistle "<message>"
stella whistle "<message>" --session <id>
stella whistle "<message>" --session <id> --session <id>

How delivery works

Each targeted session binds a small Unix domain socket beside its existing session sidecar when it starts, and already carries stella-core's TurnSteering seam — the same one stella chat's > steer and stella-serve's POST /v1/turns/{id}/steer drive, one in-process, one over HTTP. stella whistle is a second process reaching that seam over the socket: it connects, sends the message, and waits for an acknowledgment.

Delivery lands at the target's next safe step boundary — strictly between model calls, never mid-tool. The turn is never paused; it absorbs the guidance and keeps going, wrapped as [whistle — steering from another session] <message> so the model reads it as a priority directive rather than an ordinary trailing remark.

Targeting

Omit --session and the broadcast reaches every session stella resume --list shows as live. Pass --session <id> (repeatable) to narrow it to specific sessions instead — an id that is not currently live, or never existed, is reported unreachable rather than silently dropped.

$ 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 non-zero when any targeted session could not be reached, after printing every session's outcome.

What is reachable today

Foreground stella run, any wrapper-plugin-driven turn, and both of stella chat's interactive modes — the default one and --plain's — are all reachable. So are daemon-supervised runs of the same, since supervision launches the identical code path.

Interactive mode mints a steering tap per turn and has none between turns, so its socket is bound to a session-scoped relay instead. A whistle at a session sitting idle is delivered, held, and put in front of the model the moment the next turn opens; one during a running turn lands at that turn's next step boundary like any other.

Not reachable yet:

  • stella-serve-hosted turns are a separate binary. It has a steer route of its own, but a served session registers in no registry stella whistle can enumerate, and neither its address nor its token reaches a file on disk — so this is a discovery problem before it is a transport one.

Platform support

Unix only — tokio::net::UnixListener has no Windows counterpart, and stella ships no Windows binary yet. On a non-Unix build every session reports unreachable rather than the command silently doing nothing.