Follow Discord
Sweep 23 Oct 2026 · 21:48Z Build v2.1.310 529 read Stable v2.1.308 Latest v2.1.309 Next v2.1.310 Feeds RSS JSON llms.txt llms-full.txt Unofficial
Prompt changes · v2.1.310 against v2.1.309

7 changes since v2.1.309, landing in 18 of 23 prompts.

Every prompt v2.1.310 sent, compared word for word with the capture before it. Each card is one edit, with every prompt it reached; the table after them shows where each one landed.

What changed 7

1

System reminder text · line 7

"Monitor" added as a line in a system reminder

The single word "Monitor" now appears on line 7 of an injected system reminder. The diff shows no surrounding context, so it may be a new entry in a list such as a tool name, but that cannot be confirmed. It landed in only 1 of 23 captures, so it is likely specific to one setup.

+1 −0 words

Monitor

2

Monitor tool description · whole description added

New Monitor tool streams background script output as chat notifications

Adds a Monitor tool that runs a script and turns each stdout line into a notification while Claude keeps working. Claude should use Bash run_in_background for a single notification and save Monitor for repeated events. The description also covers line-buffered pipes, filters that catch failure states as well as success, keeping output volume low, a 5-minute default timeout (10 at most) with re-arming, and a WebSocket source. It appeared in only 2 of 6 captures, so it may be limited to certain setups.

New in this release

+1035 −0 words

Copy 1 of 2 · 2 prompts, 5 model strings · whole description added

Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.

Pick by how many notifications you need:

- **One** ("tell me when the server is ready / the build finishes") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.

- **One per occurrence, until the monitor expires (re-arm to continue)** ("tell me every time an ERROR line appears") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).

- **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") → Monitor with a command that emits lines and then exits.

Your script's stdout is the event stream. Each line becomes a notification. Exit ends the watch.

# Each matching log line is an event

tail -f /var/log/app.log | grep --line-buffered "ERROR"

44 more lines

# Each file change is an event

inotifywait -m --format '%e %f' /watched/dir

# Poll GitHub for new PR comments and emit one line per new comment

last=$(date -u +%Y-%m-%dT%H:%M:%SZ)

while true; do

now=$(date -u +%Y-%m-%dT%H:%M:%SZ)

gh api "repos/owner/repo/issues/123/comments?since=$last" --jq '.[] | "\(.user.login): \(.body)"'

last=$now; sleep 30

done

# Node script that emits events as they arrive (e.g. WebSocket listener)

node watch-for-events.js

# Per-occurrence with a natural end: emit each CI check as it lands, exit when the run completes

prev=""

while true; do

s=$(gh pr checks 123 --json name,bucket)

cur=$(jq -r '.[] | select(.bucket!="pending") | "\(.name): \(.bucket)"' <<<"$s" | sort)

comm -13 <(echo "$prev") <(echo "$cur")

prev=$cur

jq -e 'all(.bucket!="pending")' <<<"$s" >/dev/null && break

sleep 30

done

**Don't use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.

**Script quality:**

- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.

- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn't kill the monitor.

- Poll intervals: 30s+ for remote APIs (rate limits), 0.5-1s for local checks.

- Write a specific `description` — it appears in every notification ("errors in deploy.log" not "watching logs").

- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)

**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.

# Wrong — silent on crash, hang, or any non-success exit

tail -f run.log | grep --line-buffered "elapsed_steps="

# Right — one alternation covering progress + the failure signatures you'd act on

tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"

For poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.

**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means "the lines you'd act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.

Stdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.

The script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Every monitor expires after `timeout_ms` (default 5 minutes, at most 10 minutes): it is killed and you get one notice with the event count. Re-arm it if you still need the watch; for a long watch (PR monitoring, log tails) set `timeout_ms` to the maximum and re-arm on each expiry, and widen the filter if an expiry with no events was unexpected. Use TaskStop to cancel early.

**ws source** — open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.

Monitor({

ws: {url: 'wss://events.example.com/stream', protocols: ['v1']},

description: 'deploy events',

})

Each text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as `[binary frame, N bytes]` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash — a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.

Prefer this over `command: 'websocat wss://…'` — it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.

Copy 2 of 2 · 1 prompt, 4 model strings · whole description added

Start a background monitor that streams events from a long-running script. Each stdout line is an event — you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.

Pick by how many notifications you need:

- **One** ("tell me when the server is ready / the build finishes") → use **Bash with `run_in_background`** and a command that exits when the condition is true, e.g. `until grep -q "Ready in" dev.log; do sleep 0.5; done`. You get a single completion notification when it exits.

- **One per occurrence, until the monitor expires (re-arm to continue)** ("tell me every time an ERROR line appears") → Monitor with an unbounded command (`tail -f`, `inotifywait -m`, `while true`).

- **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") → Monitor with a command that emits lines and then exits.

Your script's stdout is the event stream. Each line becomes a notification. Exit ends the watch.

# Each matching log line is an event

tail -f /var/log/app.log | grep --line-buffered "ERROR"

44 more lines

# Each file change is an event

inotifywait -m --format '%e %f' /watched/dir

# Poll GitHub for new PR comments and emit one line per new comment

last=$(date -u +%Y-%m-%dT%H:%M:%SZ)

while true; do

now=$(date -u +%Y-%m-%dT%H:%M:%SZ)

gh api "repos/owner/repo/issues/123/comments?since=$last" --jq '.[] | "\(.user.login): \(.body)"'

last=$now; sleep 30

done

# Node script that emits events as they arrive (e.g. WebSocket listener)

node watch-for-events.js

# Per-occurrence with a natural end: emit each CI check as it lands, exit when the run completes

prev=""

while true; do

s=$(gh pr checks 123 --json name,bucket)

cur=$(jq -r '.[] | select(.bucket!="pending") | "\(.name): \(.bucket)"' <<<"$s" | sort)

comm -13 <(echo "$prev") <(echo "$cur")

prev=$cur

jq -e 'all(.bucket!="pending")' <<<"$s" >/dev/null && break

sleep 30

done

**Don't use an unbounded command for a single notification.** `tail -f`, `inotifywait -m`, and `while true` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash `run_in_background` with an `until` loop instead (one notification, ends in seconds). Note that `tail -f log | grep -m 1 ...` does *not* fix this: if the log goes quiet after the match, `tail` never receives SIGPIPE and the pipeline hangs anyway.

**Script quality:**

- Every pipe stage must flush per line or matches sit in its buffer unseen: `grep` needs `--line-buffered`, `awk` needs `fflush()`. `head` cannot flush at all — `| head -N` delivers nothing until N matches accumulate, then ends the stream.

- In poll loops, handle transient failures (`curl ... || true`) — one failed request shouldn't kill the monitor.

- Poll intervals: 30s+ for remote APIs (rate limits), 0.5-1s for local checks.

- Write a specific `description` — it appears in every notification ("errors in deploy.log" not "watching logs").

- Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications — for a command you run directly (e.g. `python train.py 2>&1 | grep --line-buffered ...`), merge stderr with `2>&1` so its failures reach your filter. (No effect on `tail -f` of an existing log — that file only contains what its writer redirected.)

**Coverage — silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit — and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.

# Wrong — silent on crash, hang, or any non-success exit

tail -f run.log | grep --line-buffered "elapsed_steps="

# Right — one alternation covering progress + the failure signatures you'd act on

tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"

For poll loops checking job state, emit on every terminal status (`succeeded|failed|cancelled|timeout`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it — some extra noise is better than missing a crashloop.

**Output volume**: Every stdout line is a conversation message, so the filter should be selective — but selective means "the lines you'd act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.

Stdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.

The script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Every monitor expires after `timeout_ms` (default 5 minutes, at most 30 minutes): it is killed and you get one notice with the event count. Re-arm it if you still need the watch; for a long watch (PR monitoring, log tails) set `timeout_ms` to the maximum and re-arm on each expiry, and widen the filter if an expiry with no events was unexpected. Use TaskStop to cancel early.

**ws source** — open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.

Monitor({

ws: {url: 'wss://events.example.com/stream', protocols: ['v1']},

description: 'deploy events',

})

Each text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as `[binary frame, N bytes]` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash — a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.

Prefer this over `command: 'websocat wss://…'` — it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.

Its parameter schema, added with it

{

"$schema": "https://json-schema.org/draft/2020-12/schema",

"additionalProperties": false,

"properties": {

"command": {

"description": "Shell command or script. Each stdout line is an event; exit ends the watch.",

"type": "string"

},

38 more lines

"description": {

"description": "Short human-readable description of what you are monitoring (shown in notifications).",

"type": "string"

},

"timeout_ms": {

"default": 300000,

"description": "Kill the monitor after this deadline. Default 300000ms. Deadlines above 600000ms are capped to 600000ms. You are notified at expiry and can re-arm.",

"maximum": 3600000,

"minimum": 1000,

"type": "number"

},

"ws": {

"additionalProperties": false,

"description": "WebSocket to open. Each text frame is an event; binary frames are reported as a placeholder line. Socket close ends the watch. Cannot be combined with command.",

"properties": {

"protocols": {

"items": {

"pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$",

"type": "string"

},

"type": "array"

},

"url": {

"type": "string"

}

},

"required": [

"url"

],

"type": "object"

}

},

"required": [

"description",

"timeout_ms"

],

"type": "object"

}

3

Bash tool description · under “Instructions”

Bash blocks long leading sleeps and points polling to Monitor

Bash no longer advises polling with a check command or keeping sleeps short. It now says long leading sleep commands are blocked, Claude should poll with Monitor using an until-loop, and Claude must not chain shorter sleeps to get around the block. It appeared in 2 of 6 captures.

+45 −33 words

- If you must poll an external process, use a check command (e.g. `gh run view`) rather than sleeping first.

- If you must sleep, keep the duration short to avoid blocking the user.

- Long leading `sleep` commands are blocked. To poll until a condition is met, use Monitor with an until-loop (e.g. `until <check>; do sleep 2; done`) — you get a notification when the loop exits. Do not chain shorter sleeps to work around the block.

Landed in 2 of 23 prompts · main prompt 2/6

14 of 27 model strings in the default Claude Code prompt

claude-3-5-haiku, claude-3-5-sonnet, claude-3-7-sonnet, claude-3-opus, claude-haiku-4-5, claude-opus-4-5, claude-opus-4-6, claude-opus-4-7, claude-sonnet-4-0, claude-sonnet-4-5, claude-sonnet-4-6, claude-sonnet-5, claude-sonnet-5[1m], sonnet[1m]

Link to this change
4

CronCreate tool description · under “Durability”

CronCreate says to use Monitor, not cron, for live watching

Adds a note that CronCreate re-runs a prompt at fixed intervals. For watching logs, processes or command output and being notified as changes happen, Claude should use Monitor instead. It appeared in 2 of 6 captures.

+46 −0 words

## Not for live watching

CronCreate re-runs a prompt at fixed wall-clock intervals. To watch a log file, process, or command output and be notified the moment something changes, use the Monitor tool instead — Monitor streams events as they happen; cron polls on a schedule.

5

Bash tool description · under “Instructions”

Bash points to Monitor for streaming background process events

Adds a Bash instruction to use Monitor when streaming events from a background process, where each stdout line becomes a notification. For a one-shot wait until something finishes, Claude should keep using Bash with run_in_background. It appeared in 2 of 6 captures.

+28 −0 words

- Use the Monitor tool to stream events from a background process (each stdout line is a notification). For one-shot "wait until done," use Bash with run_in_background instead.

Landed in 2 of 23 prompts · main prompt 2/6

14 of 27 model strings in the default Claude Code prompt

claude-3-5-haiku, claude-3-5-sonnet, claude-3-7-sonnet, claude-3-opus, claude-haiku-4-5, claude-opus-4-5, claude-opus-4-6, claude-opus-4-7, claude-sonnet-4-0, claude-sonnet-4-5, claude-sonnet-4-6, claude-sonnet-5, claude-sonnet-5[1m], sonnet[1m]

Link to this change
6

Bash tool description · entry “`run_in_background` runs the command detached”

Bash run_in_background note says foreground sleep is blocked

Adds to the run_in_background entry that foreground sleep is blocked and that Claude should wait on a condition using Monitor with an until-loop. The rest of the entry is unchanged. It appeared in 2 of 6 captures.

+15 −0 words

Copy 1 of 2 · 15 prompts, 13 model strings · entry “`run_in_background` runs the command detached”

- `run_in_background` runs the command detached: it keeps running across turns stopped and you are re-invoked. No `&` needed. Foreground `sleep` is blocked; use Monitor with an until-loop to wait on a condition.

Copy 2 of 2 · 3 prompts, 13 model strings · entry “`run_in_background` runs the command detached”

- `run_in_background` runs the command detached: it keeps running across turns notified when it exits — do not poll its output file while waiting. Foreground `sleep` is blocked; use Monitor with an until-loop to wait on a condition.

7

Appended context (skills, environment) · at “Monitor”

Monitor added to the listed tools in appended context

The word Monitor now appears in the appended context, matching the arrival of the new Monitor tool. It appeared in 2 of 6 captures.

+1 −0 words

Monitor

Where each change landed

Every prompt the release sent, one row each. A number is a change from the list above; click it to jump there. Rows with more than one model string count them, because each model gets its own copy of the prompt.

Prompt 1 2 3 4 5 6 7 Status
Main prompt
Claude Code, default27 models · 4/27 14/27 4/27 14/27 13/27 16/27 6 changes
Claude Code, seeded with this account's feature flags27 models · · · · · · · unchanged
Claude Code, seeded with anonymous feature flags27 models · · · · · · · unchanged
Agent SDK, default27 models · 4/27 14/27 4/27 14/27 13/27 16/27 6 changes
Agent SDK, seeded with this account's feature flags27 models · · · · · · · unchanged
Agent SDK, seeded with anonymous feature flags27 models · · · · · · · unchanged
Auto-mode classifier
Auto-mode classifier1 model · · · · · · · unchanged
Session agents
claude1 model · · · · · ● ● 2 changes
Slash commands
/init1 model · · · · · ● ● 2 changes
/security-review1 model · · · · · ● ● 2 changes
/team-onboarding1 model · · · · · ● ● 2 changes
Compaction
Compaction instruction1 model · · · · · ● ● 2 changes
System reminders
Claude md1 model · · · · · ● ● 2 changes
Hook pretool block1 model · · · · · ● ● 2 changes
Read dup1 model · · · · · ● ● 2 changes
Read empty1 model · · · · · ● ● 2 changes
Read offset1 model · · · · · ● ● 2 changes
Skill run1 model · · · · · ● ● 2 changes
Todo nag1 model · · · · · ● ● 2 changes
Toolsearch deferred1 model ● ● · · · ● ● 4 changes
Subagents
explore1 model · · · · · ● ● 2 changes
general-purpose1 model · · · · · ● ● 2 changes
plan1 model · · · · · ● ● 2 changes

Did not change

28 tool descriptions are word for word the same, 3 moved and are listed above.

Agent AskUserQuestion CronDelete CronList DeferredToolPlaceholder Edit EnterPlanMode EnterWorktree ExitPlanMode ExitWorktree ListAgents NotebookEdit PushNotification Read ReportFindings ScheduleWakeup SendMessage Skill TaskCreate TaskGet TaskList TaskStop TaskUpdate ToolSearch WebFetch WebSearch Workflow Write

5 prompts did not move at all: Claude Code, seeded with this account's feature flags, Claude Code, seeded with anonymous feature flags, Agent SDK, seeded with this account's feature flags, Agent SDK, seeded with anonymous feature flags, Auto-mode classifier.

Set aside as capture noise

These change on every capture by construction, so they are masked before comparing and never counted as a change.

  • 358 billing header lines
  • 224 capture date lines
  • 224 host kernel lines
Feedback