[Bug]: Artifact comment auto-replies never arm in Claude threads: every composer message reaches Claude Code as turnOrigin "sdk"#24131

opened7d agobyRrolfilho

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

Prerequisites: Claude Code logged in with a claude.ai account, "env": {"CLAUDE_CODE_ARTIFACT": "1"} in ~/.claude/settings.json (see #14816), and a claude.ai artifact you own. Any artifact works; ask Claude to publish a one-line HTML page if you have none.

  1. In a T3 Claude thread, send: Watch https://claude.ai/artifact/<id>. Claude calls ArtifactComments with action: "watch". The watch connects, and the result says auto-replies are not armed.
  2. On the artifact page, leave a comment and use Send to Claude. The T3 thread does not wake.
  3. Confirm the turn origin. Find the thread's transcript (the newest .jsonl under ~/.claude/projects/<project-dir>/) and run:
    shell
    1jq -c 'select(.type=="user" and (.message.content|type)=="string") | {entrypoint, turnOrigin, text: .message.content[0:40]}' <transcript>.jsonl
    Every message typed in the T3 composer shows "turnOrigin": "sdk".
  4. Ask Claude to stop the watch (on: false), then send Watch https://claude.ai/artifact/<id> again. The watch is refused for the rest of the session.
  5. Control: in a terminal, run claude in the same project and send the same Watch message. Auto-replies arm, and a comment sent to Claude gets a reply.

Expected behavior

The watch arms comment auto-replies, as it does in a terminal claude session. A comment sent to Claude wakes the thread, and Claude replies in the comment thread.

Actual behavior

The watch connects, but auto-replies never arm. The tool result says:

auto-replies arm only when the user asks for the watch in their own message, and no message from the user started this turn

A comment sent to Claude does not wake the thread.

Control: on the same machine, with the same settings and the same artifact, a terminal claude session armed auto-replies on a typed Watch <url>. The first comment sent to Claude got an auto-reply.

After one stop, every later watch request in that session is refused, including one I typed myself in the composer:

Not watching: watching this artifact was stopped earlier in this session, and this request did not come in a turn this session can verify the user started (a task notification, a wakeup, or a stop receipt started it — or a typed /command, whose origin is not recorded).

Likely cause

Claude Code records every user message T3 sends with turnOrigin: "sdk". Claude Code's artifact watch arms auto-replies only on a turn it can verify the user started, and an sdk turn does not qualify. The session transcript shows it for all three of my messages:

1{"entrypoint": "sdk-ts", "turnOrigin": "sdk", "promptId": "<uuid>", "version": "2.1.309"} "Monitor https://claude.ai/artifact/..."
2{"entrypoint": "sdk-ts", "turnOrigin": "sdk", "promptId": "<uuid>", "version": "2.1.309"} "help me fix this"
3{"entrypoint": "sdk-ts", "turnOrigin": "sdk", "promptId": "<uuid>", "version": "2.1.309"} "Watch https://claude.ai/artifact/..."

The gate lives in Claude Code, not in T3. I don't know whether the Agent SDK lets a host mark a message as typed by the user. If it does, T3 should set that on composer messages. If it doesn't, this needs an upstream request to Anthropic, and a note in T3 that comment auto-replies don't work in T3 threads.

Related: #13978 (the same watcher shows in the Agents panel as a working agent) and #14816 (Artifact tool enabled by default in Claude threads).

Impact

Major degradation or frequent failure

Version or commit

T3 Code (Beta) 0.1.2

Environment

macOS 26.6.2, desktop app; Claude Code 2.1.309 (entrypoint sdk-ts), Opus 5.5, auto permission mode

Workaround

Don't stop a watch in a T3 thread: after a stop, the session can't restart it. Ask Claude to read the comments on demand instead of relying on auto-replies, or run the watch from a terminal claude session.

Synced from GitHub

Follow-up: an SDK host can mark a message as human-typed. anthropics/claude-code#102828 shows Claude Desktop messages recorded with origin: {"kind":"human"}, turnOrigin: "human", promptSource: "sdk". T3 composer messages in my transcript show origin: null, turnOrigin: "sdk", promptSource: "sdk". So the likely fix is in T3: set the human origin on messages typed in the composer, and keep sdk for automated sends (wakeups, scheduled tasks, orchestration messages).