Conversation
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>
📝 WalkthroughWalkthroughA new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (5)
claude_code_log/factories/__init__.pyclaude_code_log/factories/system_factory.pyclaude_code_log/factories/user_factory.pyclaude_code_log/utils.pytest/test_utils.py
| 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 |
There was a problem hiding this comment.
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.
| 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" | ||
|
|
There was a problem hiding this comment.
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.
Closes #129.
Summary
Two visible artifacts of raw command-tag XML soup get cleaned up under one shared helper:
System-info cards for
subtype="local_command"entries. The harness emits typed slash commands asand dialog-dismissal hints as
<local-command-stdout>Status dialog dismissed</local-command-stdout>. Both rendered verbatim before — nowℹ️ /status/ℹ️ Status dialog dismissed.Branch header previews when the branch's first user entry is itself a
/cmdslash 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 viaSessionHeaderMessage.preview(introduced in Robust within-session fork rendering: collapse parallel-tool_use forks, consistent labels #131). They surfaced asNow:
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 existingcreate_slash_command_messageetc. that already parse the same patterns into typed shapes.factories/system_factory.py::create_system_messagecalls it forsubtype == "local_command"only — gate is intent-documenting, not safety-providing (the helper is opportunistic by design).utils.py::create_session_previewcalls it on the way to the truncation step. Replaces the olderextract_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/initto/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 oncreate_system_message(slash command, dialog stdout,compact_boundarypassthrough).TestCreateSessionPreviewcases for the slash-command / stdout / init paths.just ciclean (1218 tests, ruff, pyright, ty).Branch • 1addcb81 • /clmail:list /quit,Branch • 7a3bee4e • /exit, system-info cards now showℹ️ /statusandℹ️ Status dialog dismissed.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests