fix(session): alert for an agent waiting on artifact comments

An agent that publishes an artifact arms a monitor for its comments and
ends its turn. Claude Code shows that on the footer as `1 Artifact
comment monitor`, and #473 put that chip on the list of background work,
so the session counted as watching and its idle prompt opened already
acknowledged. Unlike every other chip on the list, that monitor waits
on the user: the agent hears nothing until somebody comments.

Claude's `watchingLine` now refuses any footer that carries the chip,
through a lookahead over the whole row, so a shell running beside the
monitor cannot report the session as watching either.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Michael Grundberg
2026-09-25 07:50:25 +02:00
co-authored by Claude Opus 5.5
parent 5ae574374f
commit a9b48320a3
4 changed files with 52 additions and 2 deletions
+36 -1
View File
@@ -133,7 +133,6 @@ describe('watchingLabel', () => {
'1 MCP task',
'1 background dynamic workflow',
'2 remote dynamic workflows',
'1 Artifact comment monitor',
'2 teams',
];
for (const label of labels) {
@@ -141,6 +140,42 @@ describe('watchingLabel', () => {
}
});
it('reports no watching while the agent waits for comments on an artifact', () => {
// An agent that publishes an artifact arms a monitor for its comments and ends its
// turn. That monitor waits on the user, so the idle alert has to reach them. The
// singular footer is a live capture from 2026-09-25; the plural is assumed.
expect(
watchingLabel(pane('⏵⏵ bypass permissions on · 1 Artifact comment monitor · ← for agents'), CLAUDE_WATCHING)
).toBeNull();
expect(
watchingLabel(pane('⏵⏵ bypass permissions on · 2 Artifact comment monitors · ← for agents'), CLAUDE_WATCHING)
).toBeNull();
});
it('lets a comment monitor outrank other background work on the same row', () => {
// A shell beside the monitor is still running, but the agent needs the user all the
// same, and the chip order on the footer must not decide that. The second row is
// the one that needs the `^` in front of the lookahead.
expect(
watchingLabel(
pane('⏵⏵ bypass permissions on · 1 shell · 1 Artifact comment monitor · ← for agents'),
CLAUDE_WATCHING
)
).toBeNull();
expect(
watchingLabel(
pane('⏵⏵ bypass permissions on · 1 Artifact comment monitor · 1 shell · ← for agents'),
CLAUDE_WATCHING
)
).toBeNull();
});
it('still refuses a footer cut off in the middle of the comment monitor', () => {
expect(
watchingLabel(pane('⏵⏵ bypass permissions on · 1 shell · 1 Artifact comment moni…'), CLAUDE_WATCHING)
).toBeNull();
});
it('says nothing about a pane that is running nothing', () => {
expect(watchingLabel(NOTHING_RUNNING, CLAUDE_WATCHING)).toBeNull();
expect(watchingLabel('', CLAUDE_WATCHING)).toBeNull();