[Bug]: Informational Stop-hook summaries from Claude plugins show up as a warning notice after every turn#22949

opened21d agobyCcaitlon

Area

apps/server (Claude adapter notices) and apps/web (notice rendering)

Steps to reproduce

  1. Install a Claude Code plugin whose Stop hook prints a summary through systemMessage. The Semgrep Guardian plugin (2.7.0) does this: at the end of every turn it prints Semgrep Guardian: 40 scans this session across 14 files, 0 findings, 20 files skipped (...).
  2. Run a few turns in a Claude thread.

Expected behavior

A hook message that only reports status appears once, or collapsed, or not at all. Notices are kept for hook output that changes what happened, such as a blocked prompt, the case #21217 fixed.

Actual behavior

Claude Code emits each systemMessage as system/informational with a non-info level, prefixed Stop says: .... Since #21231 (merged 2026-10-18), ClaudeAdapterV2 turns every such message into a notice (message.subtype === "informational" && message.level !== "info"). The thread therefore gets an orange warning row after every turn. A long session with a background reviewer shows the same summary four times in one screen, with nothing to act on.

Impact

The rows are noise, but they look like warnings, so real hook notices (a blocked prompt, a failing gate) are easy to miss among them.

Version or commit

0.1.2-nightly.20261021.3457

Environment

macOS 27.0.1, Claude Code 2.1.306, Semgrep plugin 2.7.0

Possible directions: show only the latest notice per hook and source in a turn, collapse identical repeats, or keep Stop hook messages out of the warning style unless the hook blocked or failed.