Skip to content

Suppress noise in system-info messages (#129)#133

Open
cboos wants to merge 1 commit intomainfrom
dev/system-info-cleanup
Open

Suppress noise in system-info messages (#129)#133
cboos wants to merge 1 commit intomainfrom
dev/system-info-cleanup

Conversation

@cboos
Copy link
Copy Markdown
Collaborator

@cboos cboos commented Apr 28, 2026

Closes #129.

Summary

Two visible artifacts of raw command-tag XML soup get cleaned up under one shared helper:

  1. System-info cards for subtype="local_command" entries. The harness emits typed slash commands as

    <command-name>/status</command-name>
    <command-message>status</command-message>
    <command-args></command-args>
    

    and dialog-dismissal hints as <local-command-stdout>Status dialog dismissed</local-command-stdout>. Both rendered verbatim before — now ℹ️ /status / ℹ️ Status dialog dismissed.

  2. Branch header previews when the branch's first user entry is itself a /cmd slash command. The same XML soup propagated into the body branch header, the session/graph index nav, and the fork-point box's per-branch link via SessionHeaderMessage.preview (introduced in Robust within-session fork rendering: collapse parallel-tool_use forks, consistent labels #131). They surfaced as

    Branch • 8d0ae973 • <command-name>/exit</command-name> <command-message>exit</command-me…
    

    Now: Branch • 8d0ae973 • /exit.

How

One shared helper + three thin call-sites:

  • factories/user_factory.py::simplify_command_tags(text) — strips the three known shapes (<command-name>, <local-command-stdout>, <local-command-stderr>), passthrough on no-match. Co-located with the existing create_slash_command_message etc. that already parse the same patterns into typed shapes.
  • factories/system_factory.py::create_system_message calls it for subtype == "local_command" only — gate is intent-documenting, not safety-providing (the helper is opportunistic by design).
  • utils.py::create_session_preview calls it on the way to the truncation step. Replaces the older extract_init_command_description (a one-shape <command-name>init + <command-contents>-only helper that returned a hardcoded English string and was asserted by zero tests). The general helper collapses /init to /init — same shape every other slash command gets, more consistent and shorter. The init-only helper was effectively dead code.

Test plan

  • TestSimplifyCommandTags — 6 direct unit tests (the three patterns, args, passthrough, command-name precedence over a coexisting stdout payload).
  • TestSystemMessageLocalCommandCleanup — 3 integration tests on create_system_message (slash command, dialog stdout, compact_boundary passthrough).
  • 4 new TestCreateSessionPreview cases for the slash-command / stdout / init paths.
  • just ci clean (1218 tests, ruff, pyright, ty).
  • Real-data verification on the BCT/clmail/monk teammates session (d602eb5f): Branch • 1addcb81 • /clmail:list /quit, Branch • 7a3bee4e • /exit, system-info cards now show ℹ️ /status and ℹ️ Status dialog dismissed.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Improved formatting of command messages in system outputs and session previews. Commands now display in simplified slash-command style for clearer, more readable presentation.
  • Tests

    • Added comprehensive test coverage for command message normalization and system message formatting.

Two related sites previously surfaced raw command-tag XML soup as
visible content:

1. ``SystemMessage`` rendering for ``subtype="local_command"`` system
   entries. The harness writes typed slash commands as

       <command-name>/status</command-name>
       <command-message>status</command-message>
       <command-args></command-args>

   and dialog-dismissal hints as
   ``<local-command-stdout>Status dialog dismissed</local-command-stdout>``.
   Both rendered verbatim through ``format_system_content`` /
   ``format_SystemMessage``, so a session that ran ``/status`` showed
   a system-info card with the literal XML rather than a clean
   ``ℹ️ /status``.

2. Branch headers whose first user entry is itself a ``/cmd`` slash
   command. ``_render_messages`` extracts text from the first user
   entry via ``extract_text_content`` and feeds it to
   ``create_session_preview``; for slash-command branches that yielded
   ``Branch • 8d0ae973 • <command-name>/exit</command-name>
   <command-message>exit</command-me…`` instead of the cleaner
   ``Branch • 8d0ae973 • /exit``.

The fix is a single shared helper and three thin call-sites:

- ``factories/user_factory.py::simplify_command_tags(text)`` — strips
  ``<command-name>X</command-name>`` (with optional ``<command-args>Y``)
  to ``"/X"`` / ``"/X Y"``, ``<local-command-stdout>X</...>`` and
  ``<local-command-stderr>X</...>`` to inner ``X``, otherwise
  passthrough. Safe to apply opportunistically — the no-match path
  returns the input unchanged.

- ``factories/system_factory.py::create_system_message`` calls it for
  ``subtype == "local_command"`` only. Other subtypes
  (``compact_boundary`` plain text, ``stop_hook_summary``,
  ``turn_duration``, …) are untouched.

- ``utils.py::create_session_preview`` calls it on the way to the
  truncation step. Replaces the older ``extract_init_command_description``
  (a one-shape, ``<command-name>init`` + ``<command-contents>``-only
  helper that returned a hardcoded English description and was
  asserted by zero tests). The general helper collapses ``/init`` to
  ``/init`` instead of the previous English string — same shape every
  other slash command gets, more consistent and shorter.

Tests in ``test/test_utils.py``:

- ``TestSimplifyCommandTags`` — six direct unit tests on the helper:
  the three patterns, passthrough on no-match, command-name winning
  over a coexisting stdout payload.
- ``TestSystemMessageLocalCommandCleanup`` — three integration tests
  on ``create_system_message``: slash command, dialog stdout,
  ``compact_boundary`` passthrough.
- Four new ``TestCreateSessionPreview`` cases for the slash-command
  / stdout / init paths through the preview pipeline.

Real-data verification on the BCT/clmail/monk teammates session:

  Branch • 1addcb81 • <command-name>/clmail:list</command-name> ...  →  Branch • 1addcb81 • /clmail:list /quit
  Branch • 7a3bee4e • <command-name>/exit</command-name> ...           →  Branch • 7a3bee4e • /exit
  ℹ️ <command-name>/status</command-name>...                           →  ℹ️ /status
  ℹ️ <local-command-stdout>Status dialog dismissed</...>               →  ℹ️ Status dialog dismissed

``just ci`` clean (1218 tests, ruff, pyright, ty all green).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

A new simplify_command_tags utility normalizes XML-like command tags into simplified user-facing text (e.g., /cmd args). This function is applied to system messages with local_command subtype and session preview generation, replacing hardcoded init-specific XML transformation logic.

Changes

Cohort / File(s) Summary
Factory & Export Setup
claude_code_log/factories/__init__.py, claude_code_log/factories/user_factory.py, claude_code_log/factories/system_factory.py
New simplify_command_tags utility added to normalize XML command tags into semantic slash-command strings. System message creation conditionally applies this transformation for local_command subtype. Exported via factories __all__.
Utils & Preview Generation
claude_code_log/utils.py
Session preview generation now uses simplify_command_tags instead of removed extract_init_command_description function. Generalized command-tag simplification replaces init-specific XML handling.
Test Coverage
test/test_utils.py
Comprehensive test additions covering simplify_command_tags unit tests (no-args, with-args, stdout/stderr extraction, passthrough), create_session_preview normalization behavior, and create_system_message integration tests for local_command subtype.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Command tags hop-skip-hop, no more XML flop!
Simplified to /cmd and /stats they drop,
Cleaner messages bloom where noisy bits once topped—
Claude's conversations just got quite cosmetic! 🌿✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective of the PR: suppressing XML noise in system-info messages by simplifying command tags.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #129: adds simplify_command_tags utility, integrates it into system_factory and utils for command tag simplification, and includes comprehensive tests.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the objective of suppressing XML noise in system messages; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/system-info-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@claude_code_log/factories/user_factory.py`:
- Around line 115-118: The code that builds the command string using name_match
and args_match currently returns bare command names (cmd) without a leading
slash; update the return logic so cmd is normalized to start with a single "/"
if it doesn't already (e.g., ensure cmd = cmd if cmd.startswith("/") else
f"/{cmd}"), then combine with args as before (using _COMMAND_ARGS_RE,
args_match, and the existing f-string) so you preserve arguments and avoid
double slashes.

In `@test/test_utils.py`:
- Around line 637-655: The test
test_create_session_preview_init_command_yields_slash_init is inconsistent: its
name and docstring expect a "/init" output but the assertion checks for "init".
Fix by making the expected value unambiguous — either change the assertion to
expect "/init" (if create_session_preview should return the slash-prefixed
command) or rename the test/docstring to reflect plain "init" if that is the
intended contract; locate the behavior in create_session_preview and related
cleanup logic (simplify_command_tags / extract_init_command_description) and
ensure the test and docstring match the actual output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b78038d-993d-4091-806f-26a25a474dcd

📥 Commits

Reviewing files that changed from the base of the PR and between 294ed3b and 6e57561.

📒 Files selected for processing (5)
  • claude_code_log/factories/__init__.py
  • claude_code_log/factories/system_factory.py
  • claude_code_log/factories/user_factory.py
  • claude_code_log/utils.py
  • test/test_utils.py

Comment on lines +115 to +118
cmd = name_match.group(1).strip()
args_match = _COMMAND_ARGS_RE.search(text)
args = args_match.group(1).strip() if args_match else ""
return f"{cmd} {args}".strip() if args else cmd
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Normalize bare command names to slash-prefixed form.

At Line 115-118, <command-name>init</command-name> is simplified to "init" rather than "/init", which breaks the intended unified /cmd rendering shape across previews/system-info.

🔧 Proposed fix
 def simplify_command_tags(text: str) -> str:
@@
     if name_match:
-        cmd = name_match.group(1).strip()
+        cmd = name_match.group(1).strip()
+        if cmd and not cmd.startswith("/"):
+            cmd = f"/{cmd}"
         args_match = _COMMAND_ARGS_RE.search(text)
         args = args_match.group(1).strip() if args_match else ""
         return f"{cmd} {args}".strip() if args else cmd
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@claude_code_log/factories/user_factory.py` around lines 115 - 118, The code
that builds the command string using name_match and args_match currently returns
bare command names (cmd) without a leading slash; update the return logic so cmd
is normalized to start with a single "/" if it doesn't already (e.g., ensure cmd
= cmd if cmd.startswith("/") else f"/{cmd}"), then combine with args as before
(using _COMMAND_ARGS_RE, args_match, and the existing f-string) so you preserve
arguments and avoid double slashes.

Comment thread test/test_utils.py
Comment on lines +637 to +655
def test_create_session_preview_init_command_yields_slash_init(self):
"""Replaces the previous hardcoded English description for ``/init``.

The old ``extract_init_command_description`` had a special-case
string ``"Claude Initializes Codebase Documentation Guide
(/init command)"`` that nothing tested or asserted on. The
general ``simplify_command_tags`` cleanup now collapses it to
the same ``/init`` shape every other slash command gets —
consistent and shorter.
"""
text = (
"<command-name>init</command-name>"
"<command-message>init</command-message>"
"<command-args></command-args>"
'<command-contents>{"text": "some init prompt"}</command-contents>'
)
preview = create_session_preview(text)
assert preview == "init"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test contract is internally inconsistent (/init vs init).

The method name/docstring says slash-init behavior, but Line 654 asserts "init". Align the assertion (or rename doc/test) so the expected contract is unambiguous.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/test_utils.py` around lines 637 - 655, The test
test_create_session_preview_init_command_yields_slash_init is inconsistent: its
name and docstring expect a "/init" output but the assertion checks for "init".
Fix by making the expected value unambiguous — either change the assertion to
expect "/init" (if create_session_preview should return the slash-prefixed
command) or rename the test/docstring to reflect plain "init" if that is the
intended contract; locate the behavior in create_session_preview and related
cleanup logic (simplify_command_tags / extract_init_command_description) and
ensure the test and docstring match the actual output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Suppress noise in system info messages

1 participant