shelbi message
View as markdownshelbi message [OPTIONS] [ID] [KIND] [BODY]
shelbi message status <MSG_ID>ID, KIND, and BODY are optional at the parser (so the status subcommand
parses) but required for the base shelbi message form — omitting any of them
there is a runtime error.
shelbi message pushes a message to a task's assigned
workspace through a file-based message log at
<worktree>/.shelbi/messages/<task-id>.log. Each call appends one durable JSON
line (msg_id, ts, kind, an optional in_response_to, and body) and
prints queued <msg-id> → <task> (<kind>) followed by a note that delivery is
not yet confirmed. The worker reads the log from where it left off at the end of
each turn and folds any new messages into what it's doing. The msg-id (shaped m-<millis>-<pid>) is what
shelbi message status takes.
shelbi message does not type text or Enter into the session, so the session's
verified-submit mechanism intentionally does not apply. Runner hooks consume
the file record. Keeping this path file-based avoids duplicate delivery and lets
the message survive a session restart.
Queued is not delivered
The push being durable is not the same as the worker having read it. A worker
only drains and acknowledges its messages at the end of a turn, which for a busy
worker can be well after you send. So a plain shelbi message reports the
message as queued, not delivered, and does not print a success check.
To learn the real outcome, either block on it or query it:
--wait[=SECS]blocks until the worker confirms delivery (default 120s), and exits non-zero if the window elapses with no confirmation.shelbi message status <msg-id>reports the current state (delivered,queued,unconfirmed,undeliverable, or an unknown id) from the durable events stream, exiting 0 only when the worker has acked.
A message queued while the worker is running is delivered at the worker's next turn end, however many messages came before it. If the session dies first, it is delivered at the next turn end after that task's session resumes.
Undeliverable messages
A message to a task that is already done, or with no worker session running, is
refused. It exits non-zero and is recorded as ack=undeliverable with a
reason (done or no_session), so shelbi message status reports it later. It
is not written to the log, so it will not be delivered if a worker starts later:
send it again if it still applies. A refused --in-response-to reply leaves the
question open in shelbi question list.
A task that is unassigned, whose workspace or machine is no longer declared, or whose worktree doesn't exist yet is an error, and nothing is written or recorded.
<KIND> classifies the message so the workspace knows how to treat it:
| Kind | Meaning |
|---|---|
reply | Response to a workspace's request-clarification. Pair with --in-response-to <question-id>. |
directive | Course correction — "stop what you're doing, the spec changed." |
context | Additional background info the workspace should fold in. |
send vs message
send and message are easy to confuse. They both get words to a running
workspace, but through different channels:
shelbi send | shelbi message | |
|---|---|---|
| Channel | Keystrokes into the live session | JSON record in the message log file |
| Durability | Message text is ephemeral; delivery verdict is recorded in events.log | Durable record in <worktree>/.shelbi/messages/<task-id>.log |
| Delivery proof | Session submission is verified; no worker semantic ack | Worker acks the msg_id at its next turn; query with status or block with --wait |
| Typed / classified | Free text | reply / directive / context |
| Reach for it when | A quick, live nudge to a pane | A message that must survive, be logged, and be confirmed |
Rule of thumb: use shelbi send for an off-the-cuff nudge,
and shelbi message when the workspace genuinely needs to receive, record, and
act on the message.
Arguments
| Argument | Type | Default | Description |
|---|---|---|---|
[ID] | string | — | Task id whose assigned workspace receives the message. Required for the base message form. |
[KIND] | reply | directive | context | — | Message kind. Required for the base message form. |
[BODY] | string | — | Message body. Required for the base message form. |
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--in-response-to <QUESTION-ID> | string | — | Question id this message replies to (sets in_response_to). Typically paired with kind = reply. |
--wait [<SECS>] | int | 120 when bare | Block until the worker confirms delivery, polling the events stream. Exits non-zero if the window elapses without an ack=worker. |
-p, --project <PROJECT> | string | env / cwd lookup | Project to operate on. Defaults to $SHELBI_PROJECT, or the registered project whose work_dir contains the current directory. |
A push first checks that the hub daemon runs the same version as this CLI. On a
mismatch it offers to restart the daemon; with the global -y it restarts
without asking; non-interactively (or while workspaces are busy) it stops and
tells you to run shelbi daemon restart. message status skips this check.
Subcommands
shelbi message status <MSG_ID>
Report a pushed message's delivery state from events.log, keyed on the
msg_id that shelbi message printed. Prints delivered and exits 0 when the
worker has acked, so a script can gate on it. Otherwise it exits non-zero with
queued (no ack yet), unconfirmed (the daemon's ack window passed with no
ack; a late ack can still land), undeliverable (refused when it was sent, with
the reason), or unknown message id (never pushed, or too old to still be in
recent events.log history).
Examples
Send a course correction to the workspace working add-auth:
shelbi message add-auth directive "hold off — the auth spec changed, wait for the updated task"Reply to a workspace's clarification question:
shelbi message add-auth reply "yes, use the existing session table" --in-response-to q-004Once the reply is queued, --in-response-to also marks the stored question
answered, so it drops off shelbi question list. Read a question in full with
shelbi question show <id> before you answer it.
Fold in extra background without redirecting the work:
shelbi message add-auth context "the staging DB is seeded with the fixtures you'll need"Send a directive and block until the worker confirms it read it (fail the script if it does not within 90 seconds):
shelbi message add-auth directive "the auth spec changed, wait for the update" --wait 90Check delivery of an earlier push without blocking:
shelbi message status m-1785764991921-86377See also
shelbi questionlists and shows the clarification questions a reply answers.shelbi send— the ephemeral counterpart: types a message straight into the workspace's pane instead of the durable message log.- Workspaces — what a workspace is and how a task gets assigned to one.