Skip to content

extract-skeleton.py silently returns empty for all current Claude sessions (10-line detection cap) #923

Description

@anthonygiuliano

Summary

ce-sessions' extract-skeleton.py silently returns an empty skeleton for every current Claude Code session, because its platform auto-detection only inspects the first 10 lines and current Claude session files front-load more than 10 non-message metadata records. This disables session-history synthesis across every skill that depends on it (ce-sessions, ce-compound's optional session pass, etc.) — and it fails silently (empty output, parse_errors: 0), so it reads as "no relevant prior sessions" rather than a bug.

Root cause

plugins/compound-engineering/skills/ce-sessions/scripts/extract-skeleton.py, platform auto-detection loop:

for line in sys.stdin:
    ...
    if not detected and len(buffer) <= 10:   # <-- caps detection to first 10 lines
        obj = json.loads(line)
        if obj.get("type") in ("user", "assistant"):
            detected = "claude"
        elif obj.get("type") in ("session_meta", "turn_context", "response_item", "event_msg"):
            detected = "codex"
        elif obj.get("role") in ("user", "assistant") and "type" not in obj:
            detected = "cursor"
...
handler = handlers.get(detected, handle_codex)   # <-- None falls through to codex

Current Claude Code session JSONL front-loads a metadata preamble before the first message. Observed first 10 record types in a real session:

1: last-prompt      6: attachment
2: custom-title     7: attachment
3: agent-name       8: attachment
4: mode             9: attachment
5: permission-mode 10: attachment

The first user/assistant record is at line 13. Because detection is capped at line 10, it never sees a message record, detected stays None, and handlers.get(detected, handle_codex) falls through to the codex handler. Every Claude record then fails the codex checks → user: 0, assistant: 0, tool: 0, parse_errors: 0 → empty skeleton.

Reproduces on a session that has 141 user + 300 assistant records — the parser reads all 1212 lines without error and extracts none.

Fix

Drop the 10-line cap so detection scans until it finds a decisive record (the if not detected: guard already short-circuits once set):

-    if not detected and len(buffer) <= 10:
+    if not detected:

Verified locally: the same session goes from user:0 assistant:0 tool:0 (88-byte empty skeleton) to user:26 assistant:106 tool:114 (59 KB skeleton with real content).

Optional hardening

The deeper trap is that an undetected platform falls through to handle_codex and produces empty output silently. Consider emitting a one-line stderr note when detected is None after the full scan, so a future format change surfaces as a visible warning instead of a silent "no sessions found." (Not required for the fix above.)

Affected

extract-skeleton.py is the shared extractor for ce-sessions; any skill routing session history through it (ce-sessions, ce-compound opt-in session pass) silently loses Claude session context until this lands. Found in v1.0.2 (e74e298).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions