Skip to content

Ignore 'last-prompt' message type#112

Merged
cboos merged 3 commits intodaaain:mainfrom
jakeefr:fix/ignore-last-prompt-message-type
Apr 19, 2026
Merged

Ignore 'last-prompt' message type#112
cboos merged 3 commits intodaaain:mainfrom
jakeefr:fix/ignore-last-prompt-message-type

Conversation

@jakeefr
Copy link
Copy Markdown
Contributor

@jakeefr jakeefr commented Apr 17, 2026

Fixes #102. Added last-prompt to the silent-skip list in converter.py alongside file-history-snapshot and progress, so Claude Code's new trailing {type:last-prompt,...} line no longer triggers a 'not a recognised message type' warning.

Also maintain a small open source tool in the Claude Code space, happy to contribute more if useful.

Summary by CodeRabbit

  • Chores
    • Improved transcript import: certain internal metadata entries are now silently ignored and unknown entry types emit a warning during import unless run in silent mode.
  • Tests
    • Added regression tests covering silent skips, passthrough entries, and warning behavior for unknown transcript entry types.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 17, 2026

📝 Walkthrough

Walkthrough

load_transcript() in claude_code_log/converter.py now defines a module-level SILENT_SKIP_TYPES and silently drops JSONL entries whose type is in that set (including "file-history-snapshot" and "last-prompt"). Other unknown types may emit a warning when silent=False; unknown DAG entries still become passthrough nodes.

Changes

Cohort / File(s) Summary
Parser logic
claude_code_log/converter.py
Adds SILENT_SKIP_TYPES (a frozenset) and changes handling so entries with those type values are dropped silently; other unrecognised types optionally warn when silent=False, while entries with DAG fields (uuid/sessionId) are treated as passthrough nodes.
Tests — passthrough update
test/test_dag_integration.py
Adjusts fixture: final passthrough node type changed from file-history-snapshot to unknown-future-type to validate passthrough preservation for unknown types with DAG fields.
Tests — silent-skip behavior
test/test_silent_skip.py
New regression tests covering: silent drop of file-history-snapshot and last-prompt; progress converted to PassthroughTranscriptEntry when DAG fields present; warnings emitted for unknown non-DAG types when silent=False and suppressed when silent=True.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I hop through lines both new and old,
Two types I tuck away, quiet and bold.
Passthroughs stay when they leave a trace,
Silent skips vanish without a chase.
Hooray — the transcript stays tidy and gold!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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 'Ignore last-prompt message type' accurately reflects the main change: handling the last-prompt message type alongside file-history-snapshot.
Linked Issues check ✅ Passed The PR addresses issue #102 by implementing silent skipping of 'last-prompt' messages, though the solution evolved to use a broader DAG-aware refactoring that silently drops unknown types without DAG fields.
Out of Scope Changes check ✅ Passed All changes are within scope: the converter.py modification handles silent skipping of specified message types, test_dag_integration.py validates passthrough behavior, and test_silent_skip.py provides comprehensive regression testing.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@cboos
Copy link
Copy Markdown
Collaborator

cboos commented Apr 18, 2026

Thanks for your first contributed line ;-)

@cboos
Copy link
Copy Markdown
Collaborator

cboos commented Apr 19, 2026

"This branch has conflicts that must be resolved" - at first, I was puzzled by that, but there's an explanation:

The conflict: That silent-skip list no longer exists on main. PR #97 (DAG ordering) refactored load_transcript — it now uses a whitelist (user/assistant/summary/system/queue-operation), falls back to PassthroughTranscriptEntry for unknown types that have uuid+sessionId, and silently drops everything else.

So, basically, #102 is already fixed. I'll add a regression test, instead.

Z3N001 and others added 3 commits April 19, 2026 10:16
Claude Code now writes a trailing {type:last-prompt,...} line as the
last entry of session .jsonl files. Add it to the silent-skip list
alongside file-history-snapshot and progress, so it does not print a
'not a recognised message type' warning.

Fixes daaain#102
…elds

Before PR daaain#97's DAG refactor, load_transcript explicitly listed
internal message types (file-history-snapshot, progress) as silent
skips, and warned about anything else. The refactor replaced that
with an unknown → PassthroughTranscriptEntry fallback for entries with
uuid+sessionId, and an implicit drop for everything else — which also
silently drops types like custom-title and agent-name that Claude Code
introduced later, so they never show up for maintainers to notice.

Restore the old signal by reintroducing an explicit SILENT_SKIP_TYPES
frozenset and an else-branch warning:

- file-history-snapshot and last-prompt (fixes daaain#102) are listed and
  dropped without warning. Both lack uuid/sessionId in the wild.
- progress is intentionally NOT in the skip list — it has uuid, so
  the uuid+sessionId branch keeps it as PassthroughTranscriptEntry
  for DAG continuity (the existing test coverage in
  test_dag_integration.py relies on that).
- Everything else that reaches the else-branch prints a single-line
  warning quoting the unknown type so future metadata surfaces.

Update test_multiple_passthrough_types to use a generic
"unknown-future-type" label instead of "file-history-snapshot" for
its synthetic passthrough entry — the test was never representative
of real file-history-snapshot data (which has no uuid) and conflicted
with the silent-skip list.
Covers the four paths through load_transcript's non-conversation type
handling:

- file-history-snapshot, last-prompt: silent-skip path. No output on
  stderr/stdout, zero messages. Direct regression for daaain#102.
- progress: uuid+sessionId path. Preserved as PassthroughTranscriptEntry,
  silently (verifies it stays out of SILENT_SKIP_TYPES).
- custom-title, agent-name, future-metadata-type: else-branch warning
  path. Parameterised to make "what's on this path" explicit. Also
  checks that silent=True suppresses the warning.
- Unknown type with uuid: PassthroughTranscriptEntry fallback path,
  no warning.
@cboos cboos force-pushed the fix/ignore-last-prompt-message-type branch from 16c3b0d to a2f9b4c Compare April 19, 2026 08:29
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.

🧹 Nitpick comments (1)
claude_code_log/converter.py (1)

343-360: Preserve DAG nodes before applying silent skips.

SILENT_SKIP_TYPES is documented as non-DAG, but this branch now runs before the uuid + sessionId passthrough path. If Claude adds DAG fields to one of these metadata types later, it would be dropped and could create false roots. Prefer preserving DAG-bearing entries first, then silently skipping non-DAG metadata.

Proposed branch-order tweak
-                    elif entry_type in SILENT_SKIP_TYPES:
-                        # Internal Claude Code entries with no DAG fields.
-                        pass
-                    elif entry_dict.get("uuid") and entry_dict.get("sessionId"):
+                    elif entry_dict.get("uuid") and entry_dict.get("sessionId"):
                         # Unknown type with DAG-relevant fields — create a
                         # PassthroughTranscriptEntry to preserve DAG chain
                         # continuity (e.g. "attachment", "permission-mode").
                         messages.append(
                             PassthroughTranscriptEntry(
                                 uuid=entry_dict["uuid"],
                                 parentUuid=entry_dict.get("parentUuid"),
                                 sessionId=entry_dict["sessionId"],
                                 timestamp=entry_dict.get("timestamp", ""),
                                 type=entry_type,
                                 isSidechain=entry_dict.get("isSidechain", False),
                                 agentId=entry_dict.get("agentId"),
                             )
                         )
+                    elif entry_type in SILENT_SKIP_TYPES:
+                        # Internal Claude Code entries with no DAG fields.
+                        pass
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@claude_code_log/converter.py` around lines 343 - 360, The current branch
checks SILENT_SKIP_TYPES before the passthrough DAG-preserving branch, which can
drop entries that actually carry DAG fields; update the condition order in
converter.py so the branch that detects DAG-relevant entries (the check using
entry_dict.get("uuid") and entry_dict.get("sessionId") that constructs a
PassthroughTranscriptEntry and appends to messages) runs before the
SILENT_SKIP_TYPES check (entry_type in SILENT_SKIP_TYPES), or alternatively
enhance the SILENT_SKIP_TYPES branch to skip only when uuid/sessionId are
absent; ensure you reference entry_type, entry_dict, PassthroughTranscriptEntry
and messages when making the change so DAG-bearing entries are preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@claude_code_log/converter.py`:
- Around line 343-360: The current branch checks SILENT_SKIP_TYPES before the
passthrough DAG-preserving branch, which can drop entries that actually carry
DAG fields; update the condition order in converter.py so the branch that
detects DAG-relevant entries (the check using entry_dict.get("uuid") and
entry_dict.get("sessionId") that constructs a PassthroughTranscriptEntry and
appends to messages) runs before the SILENT_SKIP_TYPES check (entry_type in
SILENT_SKIP_TYPES), or alternatively enhance the SILENT_SKIP_TYPES branch to
skip only when uuid/sessionId are absent; ensure you reference entry_type,
entry_dict, PassthroughTranscriptEntry and messages when making the change so
DAG-bearing entries are preserved.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7905d07-dfac-4e0b-8570-64821e18ac38

📥 Commits

Reviewing files that changed from the base of the PR and between 16c3b0d and a2f9b4c.

📒 Files selected for processing (3)
  • claude_code_log/converter.py
  • test/test_dag_integration.py
  • test/test_silent_skip.py
✅ Files skipped from review due to trivial changes (1)
  • test/test_dag_integration.py

@cboos
Copy link
Copy Markdown
Collaborator

cboos commented Apr 19, 2026

Sorry for the "force push" ;-) I believe it was either that or closing the PR and recreating a new one.


  • b97ed68 Jake Weaver — original commit, preserved empty for attribution (GitHub shows author as Z3N001, which is jakeefr's linked handle for that commit email)
  • 2efd60d cboos — silent-skip list + unrecognised-type warning
  • a2f9b4c cboos — regression tests (10 tests, all 4 paths)

Net effect: fixes #102, restores the "notice new Claude Code types" signal that went dark after PR #97, and adds the first explicit test coverage for the non-conversation type dispatch. Local just test passes 871/871 (excluding pre-existing pagination env failures).

@cboos cboos merged commit 0fbcfcc into daaain:main Apr 19, 2026
11 of 12 checks passed
cboos added a commit to fuleinist/claude-code-log that referenced this pull request Apr 19, 2026
Claude Code writes per-session state snapshots to the transcript with
no uuid/parentUuid/timestamp — they are positional markers, not DAG
nodes. They arrive frequently (e.g. a `permission-mode` after every
mode toggle, an `agent-name`+`custom-title` pair after every /rename)
and would otherwise drown the unrecognised-type warning introduced on
top of daaain#112.

Four types land in the silent-skip list:

- permission-mode  : {permissionMode}
- custom-title     : {customTitle}
- agent-name       : {agentName}
- agent-color      : {agentColor}

All four will become load-bearing once we propagate their state onto
conversational messages in a follow-up (see daaain#94). Dropping them
silently for now is a strict improvement over the current state:
either noisy warnings (reinstated warning branch on top of daaain#112) or
silent loss (main).

Extend test_silent_skip with a parameterised case covering all four
and repoint the unrecognised-type parametrisation onto two
hypothetical future types, since the original custom-title / agent-name
samples now land on the silent path.
cboos added a commit that referenced this pull request Apr 19, 2026
…es (#113)

* Handle custom-title, agent-name, and agent-color transcript entry types

These session metadata entry types are generated by Claude Code but were
not recognized by the parser, causing 'Unknown transcript entry type' errors.

Changes:
- Make uuid and timestamp optional in PassthroughTranscriptEntry to support
  entry types that lack these fields
- Add custom-title, agent-name, and agent-color to ENTRY_CREATORS registry
- Update fallback in create_transcript_entry to handle any unknown type
  with a sessionId gracefully

* Extend SILENT_SKIP_TYPES with session-metadata types (#94)

Claude Code writes per-session state snapshots to the transcript with
no uuid/parentUuid/timestamp — they are positional markers, not DAG
nodes. They arrive frequently (e.g. a `permission-mode` after every
mode toggle, an `agent-name`+`custom-title` pair after every /rename)
and would otherwise drown the unrecognised-type warning introduced on
top of #112.

Four types land in the silent-skip list:

- permission-mode  : {permissionMode}
- custom-title     : {customTitle}
- agent-name       : {agentName}
- agent-color      : {agentColor}

All four will become load-bearing once we propagate their state onto
conversational messages in a follow-up (see #94). Dropping them
silently for now is a strict improvement over the current state:
either noisy warnings (reinstated warning branch on top of #112) or
silent loss (main).

Extend test_silent_skip with a parameterised case covering all four
and repoint the unrecognised-type parametrisation onto two
hypothetical future types, since the original custom-title / agent-name
samples now land on the silent path.

* Document session-state propagation plan for #94 follow-up

Spells out the deferred half of issue #94 — turning the now-silent
session-metadata types into a visible "Assistant · CCL (Monk)"
decoration on conversational messages, with colour tinting from
agent-color.

Covers: data shape (no uuid/timestamp, pure positional markers),
file-position propagation semantics (single self-contained session
file), six concrete change sites (MessageMeta fields, load_transcript
state tracker, private-attr channel onto pydantic entries,
create_meta forwarding, title_AssistantTextMessage decoration, CSS),
cache concerns, open questions (separator, colour palette,
permission-mode surfacing, session nav integration), and risks
(snapshot churn, private-attr subtlety, markdown heading compactor).

This PR does NOT complete #94. Wording here is deliberately free of
GitHub close keywords: #94 stays open as the tracker for the
state-propagation implementation documented in
work/session-state-propagation.md. The PR description should also
be edited to use a plain `#94` reference rather than a closing
keyword so merging does not auto-close the issue.

* Switch warning text to American spelling; tighten silent-skip tests

Two small follow-ups on top of the SILENT_SKIP_TYPES work.

The "unrecognised message type" warning landed in the prior PR using
the British spelling, matching the pre-#97 original phrasing. #94
explicitly called out the preferred `s/recognised/recognized/`, so
flip it here. Single user-facing string; the else-branch is only
reached for unknown types, so unlikely to bite anyone scraping logs.

CodeRabbit flagged the silent-skip test assertions — they used the
weak form `"unrecognised" not in captured.out`, which only catches a
specific substring and silently tolerates any other output the loader
might accidentally start printing. Switch every silent-path test to
call `load_transcript(..., silent=True)` and assert
`captured.out == ""`; the warn-path test keeps `silent=False` and
now matches the new American spelling.

---------

Co-authored-by: fuleinist <fuleinist@gmail.com>
Co-authored-by: Christian Boos <christian.boos@bct-technology.com>
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.

Ignore message type "last-prompt"

3 participants