claude-code-log 1.1.1__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/CHANGELOG.md +19 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/CLAUDE.md +2 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/PKG-INFO +25 -1
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/README.md +24 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/cache.py +92 -18
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/cli.py +95 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/converter.py +598 -126
- claude_code_log-1.2.0/claude_code_log/dag.py +794 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/system_factory.py +25 -2
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/transcript_factory.py +15 -3
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/renderer.py +31 -3
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/system_formatters.py +43 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/global_styles.css +19 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/message_styles.css +43 -1
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/project_card_styles.css +25 -1
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/search.html +10 -5
- claude_code_log-1.2.0/claude_code_log/html/templates/components/session_nav.html +70 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/session_nav_styles.css +108 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/index.html +8 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/transcript.html +64 -3
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/tool_formatters.py +20 -2
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/markdown/renderer.py +40 -4
- claude_code_log-1.2.0/claude_code_log/migrations/004_html_pagination_variant.sql +69 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/models.py +50 -1
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/renderer.py +813 -128
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/tui.py +8 -12
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/utils.py +74 -44
- claude_code_log-1.2.0/dev-docs/dag.md +589 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/rendering-architecture.md +1 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/pyproject.toml +1 -1
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/uv.lock +1 -1
- claude_code_log-1.2.0/work/phase-c-agent-transcripts.md +87 -0
- claude_code_log-1.2.0/work/session-state-propagation.md +233 -0
- claude_code_log-1.1.1/claude_code_log/html/templates/components/session_nav.html +0 -39
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/.claude/settings.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/.claude/skills/tool-renderer/SKILL.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/.github/workflows/ci.yml +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/.github/workflows/claude.yml +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/.gitignore +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/.vscode/settings.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/CONTRIBUTING.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/LICENSE +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/__init__.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/__init__.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/assistant_factory.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/meta_factory.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/tool_factory.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/factories/user_factory.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/__init__.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/ansi_colors.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/assistant_formatters.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/renderer_code.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/edit_diff_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/filter_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/page_nav_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/pygments_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/search_inline.html +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/search_inline_script.html +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/search_results_panel.html +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/search_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/timeline.html +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/timeline_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/timezone_converter.js +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/templates/components/todo_styles.css +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/user_formatters.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/html/utils.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/image_export.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/markdown/__init__.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/migrations/001_initial_schema.sql +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/migrations/002_html_cache.sql +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/migrations/003_html_pagination.sql +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/migrations/__init__.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/migrations/runner.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/parser.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/py.typed +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/claude_code_log/renderer_timings.py +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/FOLD_STATE_DIAGRAM.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/css-classes.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/implementing-a-tool-renderer.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/assistant/assistant.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/assistant/assistant.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/assistant/assistant_sidechain.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/assistant/assistant_sidechain.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/assistant/thinking.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/assistant/thinking.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/file_history_snapshot.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/file_history_snapshot.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/queue_operation.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/queue_operation.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/summary.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/summary.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/system_info.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/system/system_info.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/AskUserQuestion-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/AskUserQuestion-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/AskUserQuestion-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/AskUserQuestion-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/AskUserQuestion-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/AskUserQuestion-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Bash-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Bash-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Bash-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Bash-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Bash-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Bash-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/BashOutput-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/BashOutput-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/BashOutput-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/BashOutput-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Edit-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Edit-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Edit-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Edit-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Edit-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Edit-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/ExitPlanMode-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/ExitPlanMode-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/ExitPlanMode-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/ExitPlanMode-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/ExitPlanMode-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/ExitPlanMode-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Glob-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Glob-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Glob-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Glob-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Grep-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Grep-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Grep-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Grep-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/KillShell-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/KillShell-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/KillShell-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/KillShell-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/KillShell-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/KillShell-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/LS-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/LS-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/LS-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/LS-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/MultiEdit-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/MultiEdit-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/MultiEdit-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/MultiEdit-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/MultiEdit-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/MultiEdit-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Read-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Read-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Read-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Read-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Read-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Read-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Task-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Task-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Task-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Task-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/TodoWrite-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/TodoWrite-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/TodoWrite-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/TodoWrite-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebFetch-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebFetch-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebFetch-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebFetch-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebSearch-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebSearch-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebSearch-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/WebSearch-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Write-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Write-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Write-tool_result_error.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Write-tool_result_error.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Write-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/Write-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/exit_plan_mode-tool_result.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/exit_plan_mode-tool_result.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/exit_plan_mode-tool_use.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/tools/exit_plan_mode-tool_use.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/bash_input.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/bash_input.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/bash_output.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/bash_output.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/command_output.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/command_output.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/image.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/image.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user_command.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user_command.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user_sidechain.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user_sidechain.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user_slash_command.json +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages/user/user_slash_command.jsonl +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/messages.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/rendering-next.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/dev-docs/restoring-archived-sessions.md +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/justfile +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/mise.toml +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/stubs/pygments/__init__.pyi +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/stubs/pygments/formatter.pyi +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/stubs/pygments/formatters/__init__.pyi +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/stubs/pygments/lexer.pyi +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/stubs/pygments/lexers/__init__.pyi +0 -0
- {claude_code_log-1.1.1 → claude_code_log-1.2.0}/stubs/pygments/util.pyi +0 -0
|
@@ -6,6 +6,25 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
## [1.2.0] - 2026-04-19
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Preserve agentId anchors in parallel-Task stitch + tool-param UI fix (#115)**
|
|
14
|
+
- **Per-level output files for --detail and --compact (#114)**
|
|
15
|
+
- **Handle custom-title, agent-name, and agent-color transcript entry types (#113)**
|
|
16
|
+
- **Ignore 'last-prompt' message type (#112)**
|
|
17
|
+
- **Detail levels and compact rendering of conversations (#96)**
|
|
18
|
+
- **Skip PassthroughTranscriptEntry in _render_messages**
|
|
19
|
+
- **Integrate agent transcripts into the DAG (Phase C) (#99)**
|
|
20
|
+
- **Implement DAG-based message ordering (Phases A+B) (#97)**
|
|
21
|
+
- **Fix slow test hitting real ~/.claude/projects (5GB) (#109)**
|
|
22
|
+
- **feat: add --session-id flag for exporting a single (#103)**
|
|
23
|
+
- **Fix search broken when HTML saved with different filename (#106)**
|
|
24
|
+
- **Add Grep tool renderer with pattern in title (#107)**
|
|
25
|
+
- **Fix TUI square bracket escaping issue (#105)**
|
|
26
|
+
|
|
27
|
+
|
|
9
28
|
## [1.1.1] - 2026-03-10
|
|
10
29
|
|
|
11
30
|
### Changed
|
|
@@ -47,6 +47,8 @@ claude-code-log --from-date "last week"
|
|
|
47
47
|
|
|
48
48
|
See @CONTRIBUTING.md for detailed development setup, testing, architecture, and release process.
|
|
49
49
|
|
|
50
|
+
**Before pushing, always remind the user to run `just ci`.**
|
|
51
|
+
|
|
50
52
|
### Claude-Specific Testing Tips
|
|
51
53
|
|
|
52
54
|
**Always use `-n auto` for parallel test execution:**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-log
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Convert Claude Code transcript JSONL files to HTML
|
|
5
5
|
Project-URL: Homepage, https://github.com/daaain/claude-code-log
|
|
6
6
|
Project-URL: Issues, https://github.com/daaain/claude-code-log/issues
|
|
@@ -66,6 +66,7 @@ uvx claude-code-log@latest --open-browser
|
|
|
66
66
|
- **Rich Message Types**: Support for user/assistant messages, tool use/results, thinking content, images
|
|
67
67
|
- **System Command Visibility**: Show system commands (like `init`) in expandable details with structured parsing
|
|
68
68
|
- **Markdown Rendering**: Server-side markdown rendering with syntax highlighting using mistune
|
|
69
|
+
- **Detail Levels & Compact Mode**: `--detail full|high|low|minimal` filters by verbosity and `--compact` merges repeated section headings — pairs well with `--format md` to feed past conversations back to an LLM for analysis or experience building
|
|
69
70
|
- **Floating Navigation**: Always-available back-to-top button and filter controls
|
|
70
71
|
- **CLI Interface**: Simple command-line tool using Click
|
|
71
72
|
|
|
@@ -81,6 +82,7 @@ This tool helps you answer questions like:
|
|
|
81
82
|
- **"How can I share my Claude Code conversation with others?"**
|
|
82
83
|
- **"What's the timeline of my project development?"**
|
|
83
84
|
- **"How can I analyse patterns in my Claude Code usage?"**
|
|
85
|
+
- **"How can I feed a past session back to an LLM for analysis or experience building?"**
|
|
84
86
|
|
|
85
87
|
## Usage
|
|
86
88
|
|
|
@@ -164,6 +166,27 @@ claude-code-log /path/to/directory --from-date "yesterday" --to-date "today"
|
|
|
164
166
|
claude-code-log /path/to/directory --from-date "3 days ago" --to-date "yesterday"
|
|
165
167
|
```
|
|
166
168
|
|
|
169
|
+
### Feeding Past Conversations to an LLM
|
|
170
|
+
|
|
171
|
+
The combination `--detail low --format md --compact` produces condensed Markdown suitable as context for an LLM to review or distill patterns from past work:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Session → compact Markdown for LLM review
|
|
175
|
+
claude-code-log transcript.jsonl --detail low --format md --compact -o session.md
|
|
176
|
+
|
|
177
|
+
# Whole project history
|
|
178
|
+
claude-code-log /path/to/project --detail low --format md --compact
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`--detail` levels (smallest → largest output):
|
|
182
|
+
|
|
183
|
+
- `minimal` — user + assistant text only
|
|
184
|
+
- `low` — interaction-focused; keeps WebSearch, WebFetch, and Task (agent delegations) as key signals
|
|
185
|
+
- `high` — detailed but cleaned; drops system/hook noise
|
|
186
|
+
- `full` — everything (default)
|
|
187
|
+
|
|
188
|
+
`--compact` merges consecutive same-type sections in Markdown so runs of assistant responses share one heading instead of repeating `### 🤖 Assistant:` for each.
|
|
189
|
+
|
|
167
190
|
## Project Hierarchy Output
|
|
168
191
|
|
|
169
192
|
When processing all projects, the tool generates:
|
|
@@ -228,6 +251,7 @@ Markdown export provides a lightweight, portable alternative to HTML:
|
|
|
228
251
|
- **Code Preservation**: Syntax highlighting hints via fenced code blocks
|
|
229
252
|
- **Embedded Viewer**: TUI includes built-in Markdown viewer with table of contents
|
|
230
253
|
- **Image Support**: Configurable image handling (placeholder, embedded base64, or referenced files)
|
|
254
|
+
- **`--compact` Mode**: Merge consecutive same-type section headings — most useful with `--detail low` or `minimal` where tool stripping creates runs of Assistant or User sections
|
|
231
255
|
|
|
232
256
|
## Installation
|
|
233
257
|
|
|
@@ -42,6 +42,7 @@ uvx claude-code-log@latest --open-browser
|
|
|
42
42
|
- **Rich Message Types**: Support for user/assistant messages, tool use/results, thinking content, images
|
|
43
43
|
- **System Command Visibility**: Show system commands (like `init`) in expandable details with structured parsing
|
|
44
44
|
- **Markdown Rendering**: Server-side markdown rendering with syntax highlighting using mistune
|
|
45
|
+
- **Detail Levels & Compact Mode**: `--detail full|high|low|minimal` filters by verbosity and `--compact` merges repeated section headings — pairs well with `--format md` to feed past conversations back to an LLM for analysis or experience building
|
|
45
46
|
- **Floating Navigation**: Always-available back-to-top button and filter controls
|
|
46
47
|
- **CLI Interface**: Simple command-line tool using Click
|
|
47
48
|
|
|
@@ -57,6 +58,7 @@ This tool helps you answer questions like:
|
|
|
57
58
|
- **"How can I share my Claude Code conversation with others?"**
|
|
58
59
|
- **"What's the timeline of my project development?"**
|
|
59
60
|
- **"How can I analyse patterns in my Claude Code usage?"**
|
|
61
|
+
- **"How can I feed a past session back to an LLM for analysis or experience building?"**
|
|
60
62
|
|
|
61
63
|
## Usage
|
|
62
64
|
|
|
@@ -140,6 +142,27 @@ claude-code-log /path/to/directory --from-date "yesterday" --to-date "today"
|
|
|
140
142
|
claude-code-log /path/to/directory --from-date "3 days ago" --to-date "yesterday"
|
|
141
143
|
```
|
|
142
144
|
|
|
145
|
+
### Feeding Past Conversations to an LLM
|
|
146
|
+
|
|
147
|
+
The combination `--detail low --format md --compact` produces condensed Markdown suitable as context for an LLM to review or distill patterns from past work:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Session → compact Markdown for LLM review
|
|
151
|
+
claude-code-log transcript.jsonl --detail low --format md --compact -o session.md
|
|
152
|
+
|
|
153
|
+
# Whole project history
|
|
154
|
+
claude-code-log /path/to/project --detail low --format md --compact
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`--detail` levels (smallest → largest output):
|
|
158
|
+
|
|
159
|
+
- `minimal` — user + assistant text only
|
|
160
|
+
- `low` — interaction-focused; keeps WebSearch, WebFetch, and Task (agent delegations) as key signals
|
|
161
|
+
- `high` — detailed but cleaned; drops system/hook noise
|
|
162
|
+
- `full` — everything (default)
|
|
163
|
+
|
|
164
|
+
`--compact` merges consecutive same-type sections in Markdown so runs of assistant responses share one heading instead of repeating `### 🤖 Assistant:` for each.
|
|
165
|
+
|
|
143
166
|
## Project Hierarchy Output
|
|
144
167
|
|
|
145
168
|
When processing all projects, the tool generates:
|
|
@@ -204,6 +227,7 @@ Markdown export provides a lightweight, portable alternative to HTML:
|
|
|
204
227
|
- **Code Preservation**: Syntax highlighting hints via fenced code blocks
|
|
205
228
|
- **Embedded Viewer**: TUI includes built-in Markdown viewer with table of contents
|
|
206
229
|
- **Image Support**: Configurable image handling (placeholder, embedded base64, or referenced files)
|
|
230
|
+
- **`--compact` Mode**: Merge consecutive same-type section headings — most useful with `--detail low` or `minimal` where tool stripping creates runs of Assistant or User sections
|
|
207
231
|
|
|
208
232
|
## Installation
|
|
209
233
|
|
|
@@ -1140,8 +1140,17 @@ class CacheManager:
|
|
|
1140
1140
|
|
|
1141
1141
|
return row["page_size_config"] if row else None
|
|
1142
1142
|
|
|
1143
|
-
def get_page_data(
|
|
1144
|
-
|
|
1143
|
+
def get_page_data(
|
|
1144
|
+
self, page_number: int, variant_suffix: str = ""
|
|
1145
|
+
) -> Optional[PageCacheData]:
|
|
1146
|
+
"""Get cache data for a specific page.
|
|
1147
|
+
|
|
1148
|
+
Args:
|
|
1149
|
+
page_number: Page number (1-indexed).
|
|
1150
|
+
variant_suffix: Detail/compact variant infix (e.g. ``""``,
|
|
1151
|
+
``".low"``, ``".low.compact"``). Each variant has its
|
|
1152
|
+
own pagination cache row.
|
|
1153
|
+
"""
|
|
1145
1154
|
if self._project_id is None:
|
|
1146
1155
|
return None
|
|
1147
1156
|
|
|
@@ -1149,8 +1158,9 @@ class CacheManager:
|
|
|
1149
1158
|
# Get page info
|
|
1150
1159
|
page_row = conn.execute(
|
|
1151
1160
|
"""SELECT * FROM html_pages
|
|
1152
|
-
WHERE project_id = ? AND
|
|
1153
|
-
|
|
1161
|
+
WHERE project_id = ? AND variant_suffix = ?
|
|
1162
|
+
AND page_number = ?""",
|
|
1163
|
+
(self._project_id, variant_suffix, page_number),
|
|
1154
1164
|
).fetchone()
|
|
1155
1165
|
|
|
1156
1166
|
if not page_row:
|
|
@@ -1247,8 +1257,16 @@ class CacheManager:
|
|
|
1247
1257
|
total_output_tokens: int,
|
|
1248
1258
|
total_cache_creation_tokens: int,
|
|
1249
1259
|
total_cache_read_tokens: int,
|
|
1260
|
+
variant_suffix: str = "",
|
|
1250
1261
|
) -> None:
|
|
1251
|
-
"""Update or insert page cache entry.
|
|
1262
|
+
"""Update or insert page cache entry.
|
|
1263
|
+
|
|
1264
|
+
Args:
|
|
1265
|
+
variant_suffix: Detail/compact variant infix (e.g. ``""``,
|
|
1266
|
+
``".low"``). Each variant owns its own cache row; the
|
|
1267
|
+
UNIQUE constraint is on (project_id, variant_suffix,
|
|
1268
|
+
page_number).
|
|
1269
|
+
"""
|
|
1252
1270
|
if self._project_id is None or not session_ids:
|
|
1253
1271
|
return
|
|
1254
1272
|
|
|
@@ -1256,13 +1274,14 @@ class CacheManager:
|
|
|
1256
1274
|
# Insert or update page
|
|
1257
1275
|
conn.execute(
|
|
1258
1276
|
"""INSERT INTO html_pages
|
|
1259
|
-
(project_id, page_number, html_path,
|
|
1277
|
+
(project_id, variant_suffix, page_number, html_path,
|
|
1278
|
+
page_size_config, message_count,
|
|
1260
1279
|
first_session_id, last_session_id, first_timestamp, last_timestamp,
|
|
1261
1280
|
total_input_tokens, total_output_tokens,
|
|
1262
1281
|
total_cache_creation_tokens, total_cache_read_tokens,
|
|
1263
1282
|
generated_at, library_version)
|
|
1264
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1265
|
-
ON CONFLICT(project_id, page_number)
|
|
1283
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1284
|
+
ON CONFLICT(project_id, variant_suffix, page_number)
|
|
1266
1285
|
DO UPDATE SET
|
|
1267
1286
|
html_path = excluded.html_path,
|
|
1268
1287
|
page_size_config = excluded.page_size_config,
|
|
@@ -1279,6 +1298,7 @@ class CacheManager:
|
|
|
1279
1298
|
library_version = excluded.library_version""",
|
|
1280
1299
|
(
|
|
1281
1300
|
self._project_id,
|
|
1301
|
+
variant_suffix,
|
|
1282
1302
|
page_number,
|
|
1283
1303
|
html_path,
|
|
1284
1304
|
page_size_config,
|
|
@@ -1299,8 +1319,9 @@ class CacheManager:
|
|
|
1299
1319
|
# Get the page ID
|
|
1300
1320
|
row = conn.execute(
|
|
1301
1321
|
"""SELECT id FROM html_pages
|
|
1302
|
-
WHERE project_id = ? AND
|
|
1303
|
-
|
|
1322
|
+
WHERE project_id = ? AND variant_suffix = ?
|
|
1323
|
+
AND page_number = ?""",
|
|
1324
|
+
(self._project_id, variant_suffix, page_number),
|
|
1304
1325
|
).fetchone()
|
|
1305
1326
|
page_id = row["id"]
|
|
1306
1327
|
|
|
@@ -1318,13 +1339,18 @@ class CacheManager:
|
|
|
1318
1339
|
conn.commit()
|
|
1319
1340
|
|
|
1320
1341
|
def is_page_stale(
|
|
1321
|
-
self,
|
|
1342
|
+
self,
|
|
1343
|
+
page_number: int,
|
|
1344
|
+
page_size_config: int,
|
|
1345
|
+
variant_suffix: str = "",
|
|
1322
1346
|
) -> tuple[bool, str]:
|
|
1323
1347
|
"""Check if a page needs regeneration.
|
|
1324
1348
|
|
|
1325
1349
|
Args:
|
|
1326
|
-
page_number: The page number to check
|
|
1327
|
-
page_size_config: The current page size configuration
|
|
1350
|
+
page_number: The page number to check.
|
|
1351
|
+
page_size_config: The current page size configuration.
|
|
1352
|
+
variant_suffix: Detail/compact variant infix; each variant's
|
|
1353
|
+
cache is checked independently.
|
|
1328
1354
|
|
|
1329
1355
|
Returns:
|
|
1330
1356
|
Tuple of (is_stale: bool, reason: str)
|
|
@@ -1334,7 +1360,7 @@ class CacheManager:
|
|
|
1334
1360
|
if self._project_id is None:
|
|
1335
1361
|
return True, "no_cache"
|
|
1336
1362
|
|
|
1337
|
-
page_data = self.get_page_data(page_number)
|
|
1363
|
+
page_data = self.get_page_data(page_number, variant_suffix)
|
|
1338
1364
|
if page_data is None:
|
|
1339
1365
|
return True, "not_cached"
|
|
1340
1366
|
|
|
@@ -1409,15 +1435,21 @@ class CacheManager:
|
|
|
1409
1435
|
|
|
1410
1436
|
return html_paths
|
|
1411
1437
|
|
|
1412
|
-
def get_page_count(self) -> int:
|
|
1413
|
-
"""Get the number of cached pages for this project.
|
|
1438
|
+
def get_page_count(self, variant_suffix: str = "") -> int:
|
|
1439
|
+
"""Get the number of cached pages for this project and variant.
|
|
1440
|
+
|
|
1441
|
+
Orphan-cleanup loops in the converter must pass the same
|
|
1442
|
+
``variant_suffix`` used for rendering, otherwise they'd count
|
|
1443
|
+
pages across variants and delete live pages of another variant.
|
|
1444
|
+
"""
|
|
1414
1445
|
if self._project_id is None:
|
|
1415
1446
|
return 0
|
|
1416
1447
|
|
|
1417
1448
|
with self._get_connection() as conn:
|
|
1418
1449
|
row = conn.execute(
|
|
1419
|
-
"""SELECT COUNT(*) as cnt FROM html_pages
|
|
1420
|
-
|
|
1450
|
+
"""SELECT COUNT(*) as cnt FROM html_pages
|
|
1451
|
+
WHERE project_id = ? AND variant_suffix = ?""",
|
|
1452
|
+
(self._project_id, variant_suffix),
|
|
1421
1453
|
).fetchone()
|
|
1422
1454
|
|
|
1423
1455
|
return row["cnt"] if row else 0
|
|
@@ -1556,6 +1588,47 @@ def get_all_cached_projects(
|
|
|
1556
1588
|
return result
|
|
1557
1589
|
|
|
1558
1590
|
|
|
1591
|
+
def find_session_in_cache(
|
|
1592
|
+
session_id: str,
|
|
1593
|
+
projects_dir: Path,
|
|
1594
|
+
db_path: Optional[Path] = None,
|
|
1595
|
+
) -> list[tuple[str, str]]:
|
|
1596
|
+
"""Find a session by ID or prefix across all projects in cache.
|
|
1597
|
+
|
|
1598
|
+
Standalone function that queries the cache database directly.
|
|
1599
|
+
|
|
1600
|
+
Args:
|
|
1601
|
+
session_id: Full session ID or prefix to match.
|
|
1602
|
+
projects_dir: Path to the projects directory (for default DB location).
|
|
1603
|
+
db_path: Optional explicit path to the cache database.
|
|
1604
|
+
|
|
1605
|
+
Returns:
|
|
1606
|
+
List of (project_path, full_session_id) tuples for all matches.
|
|
1607
|
+
"""
|
|
1608
|
+
actual_db_path = db_path or get_cache_db_path(projects_dir)
|
|
1609
|
+
if not actual_db_path.exists():
|
|
1610
|
+
return []
|
|
1611
|
+
|
|
1612
|
+
try:
|
|
1613
|
+
conn = sqlite3.connect(actual_db_path, timeout=30.0)
|
|
1614
|
+
conn.row_factory = sqlite3.Row
|
|
1615
|
+
try:
|
|
1616
|
+
rows = conn.execute(
|
|
1617
|
+
"""SELECT p.project_path, s.session_id
|
|
1618
|
+
FROM sessions s
|
|
1619
|
+
JOIN projects p ON s.project_id = p.id
|
|
1620
|
+
WHERE s.session_id = ? OR s.session_id LIKE ?
|
|
1621
|
+
ORDER BY s.first_timestamp DESC""",
|
|
1622
|
+
(session_id, f"{session_id}%"),
|
|
1623
|
+
).fetchall()
|
|
1624
|
+
return [(row["project_path"], row["session_id"]) for row in rows]
|
|
1625
|
+
finally:
|
|
1626
|
+
conn.close()
|
|
1627
|
+
except (sqlite3.Error, OSError) as e:
|
|
1628
|
+
logger.debug("Failed to find session in cache: %s", e)
|
|
1629
|
+
return []
|
|
1630
|
+
|
|
1631
|
+
|
|
1559
1632
|
__all__ = [
|
|
1560
1633
|
"CacheManager",
|
|
1561
1634
|
"CachedFileInfo",
|
|
@@ -1563,6 +1636,7 @@ __all__ = [
|
|
|
1563
1636
|
"PageCacheData",
|
|
1564
1637
|
"ProjectCache",
|
|
1565
1638
|
"SessionCacheData",
|
|
1639
|
+
"find_session_in_cache",
|
|
1566
1640
|
"get_all_cached_projects",
|
|
1567
1641
|
"get_cache_db_path",
|
|
1568
1642
|
"get_library_version",
|
|
@@ -14,11 +14,13 @@ from .converter import (
|
|
|
14
14
|
convert_jsonl_to,
|
|
15
15
|
convert_jsonl_to_html,
|
|
16
16
|
ensure_fresh_cache,
|
|
17
|
+
generate_single_session_file,
|
|
17
18
|
get_file_extension,
|
|
18
19
|
process_projects_hierarchy,
|
|
19
20
|
)
|
|
20
21
|
from .cache import (
|
|
21
22
|
CacheManager,
|
|
23
|
+
find_session_in_cache,
|
|
22
24
|
get_all_cached_projects,
|
|
23
25
|
get_cache_db_path,
|
|
24
26
|
get_library_version,
|
|
@@ -506,6 +508,31 @@ def _clear_output_files(input_path: Path, all_projects: bool, file_ext: str) ->
|
|
|
506
508
|
default=2000,
|
|
507
509
|
help="Maximum messages per page for combined transcript (default: 2000). Sessions are never split across pages.",
|
|
508
510
|
)
|
|
511
|
+
@click.option(
|
|
512
|
+
"--session-id",
|
|
513
|
+
default=None,
|
|
514
|
+
help="Export a single session by ID (full ID or prefix). Project path is optional — looks up the session globally via cache.",
|
|
515
|
+
)
|
|
516
|
+
@click.option(
|
|
517
|
+
"--detail",
|
|
518
|
+
type=click.Choice(["full", "high", "low", "minimal"], case_sensitive=False),
|
|
519
|
+
default="full",
|
|
520
|
+
help=(
|
|
521
|
+
"Detail level for output. "
|
|
522
|
+
"full: everything; "
|
|
523
|
+
"high: detailed but cleaned (no system/hook noise); "
|
|
524
|
+
"low: interaction-focused + key signals; "
|
|
525
|
+
"minimal: user + assistant messages only."
|
|
526
|
+
),
|
|
527
|
+
)
|
|
528
|
+
@click.option(
|
|
529
|
+
"--compact",
|
|
530
|
+
is_flag=True,
|
|
531
|
+
help=(
|
|
532
|
+
"Merge consecutive same-category headings in Markdown output. "
|
|
533
|
+
"Markdown-only — a no-op for HTML."
|
|
534
|
+
),
|
|
535
|
+
)
|
|
509
536
|
@click.option(
|
|
510
537
|
"--debug",
|
|
511
538
|
is_flag=True,
|
|
@@ -528,6 +555,9 @@ def main(
|
|
|
528
555
|
output_format: str,
|
|
529
556
|
image_export_mode: Optional[str],
|
|
530
557
|
page_size: int,
|
|
558
|
+
session_id: Optional[str],
|
|
559
|
+
detail: str,
|
|
560
|
+
compact: bool,
|
|
531
561
|
debug: bool,
|
|
532
562
|
) -> None:
|
|
533
563
|
"""Convert Claude transcript JSONL files to HTML or Markdown.
|
|
@@ -537,6 +567,10 @@ def main(
|
|
|
537
567
|
# Configure logging to show warnings and above
|
|
538
568
|
logging.basicConfig(level=logging.WARNING, format="%(levelname)s: %(message)s")
|
|
539
569
|
|
|
570
|
+
from .models import DetailLevel
|
|
571
|
+
|
|
572
|
+
detail_level = DetailLevel(detail.lower())
|
|
573
|
+
|
|
540
574
|
try:
|
|
541
575
|
# Handle TUI mode
|
|
542
576
|
if tui:
|
|
@@ -648,6 +682,60 @@ def main(
|
|
|
648
682
|
_launch_tui_with_cache_check(input_path)
|
|
649
683
|
return
|
|
650
684
|
|
|
685
|
+
# Handle --session-id: export a single session by ID
|
|
686
|
+
if session_id is not None:
|
|
687
|
+
if input_path is None:
|
|
688
|
+
# Global lookup via cache
|
|
689
|
+
effective_projects_dir = projects_dir or get_default_projects_dir()
|
|
690
|
+
matches = find_session_in_cache(session_id, effective_projects_dir)
|
|
691
|
+
if not matches:
|
|
692
|
+
click.echo(
|
|
693
|
+
f"Error: Session '{session_id}' not found in cache. "
|
|
694
|
+
"Try providing a project directory path, or run "
|
|
695
|
+
"claude-code-log first to populate the cache.",
|
|
696
|
+
err=True,
|
|
697
|
+
)
|
|
698
|
+
sys.exit(1)
|
|
699
|
+
if len(matches) > 1:
|
|
700
|
+
# Check if all matches resolve to the same session ID
|
|
701
|
+
unique_ids = {m[1] for m in matches}
|
|
702
|
+
if len(unique_ids) > 1:
|
|
703
|
+
click.echo(
|
|
704
|
+
f"Error: Ambiguous session ID prefix '{session_id}' "
|
|
705
|
+
"matches multiple sessions:",
|
|
706
|
+
err=True,
|
|
707
|
+
)
|
|
708
|
+
for proj_path, sid in matches:
|
|
709
|
+
click.echo(f" {sid[:8]} in {proj_path}", err=True)
|
|
710
|
+
sys.exit(1)
|
|
711
|
+
input_path = Path(matches[0][0])
|
|
712
|
+
session_id = matches[0][1]
|
|
713
|
+
else:
|
|
714
|
+
# Convert project path if needed
|
|
715
|
+
if not input_path.exists() or (
|
|
716
|
+
input_path.is_dir() and not list(input_path.glob("*.jsonl"))
|
|
717
|
+
):
|
|
718
|
+
claude_path = convert_project_path_to_claude_dir(
|
|
719
|
+
input_path, projects_dir
|
|
720
|
+
)
|
|
721
|
+
if claude_path.exists():
|
|
722
|
+
input_path = claude_path
|
|
723
|
+
|
|
724
|
+
output_path = generate_single_session_file(
|
|
725
|
+
output_format,
|
|
726
|
+
input_path,
|
|
727
|
+
session_id,
|
|
728
|
+
output,
|
|
729
|
+
not no_cache,
|
|
730
|
+
image_export_mode,
|
|
731
|
+
detail=detail_level,
|
|
732
|
+
compact=compact,
|
|
733
|
+
)
|
|
734
|
+
click.echo(f"Successfully exported session to {output_path}")
|
|
735
|
+
if open_browser:
|
|
736
|
+
click.launch(str(output_path))
|
|
737
|
+
return
|
|
738
|
+
|
|
651
739
|
# Handle default case - process all projects hierarchy if no input path and --all-projects flag
|
|
652
740
|
if input_path is None:
|
|
653
741
|
input_path = projects_dir or get_default_projects_dir()
|
|
@@ -685,6 +773,8 @@ def main(
|
|
|
685
773
|
output_format,
|
|
686
774
|
image_export_mode,
|
|
687
775
|
page_size=page_size,
|
|
776
|
+
detail=detail_level,
|
|
777
|
+
compact=compact,
|
|
688
778
|
)
|
|
689
779
|
|
|
690
780
|
# Count processed projects
|
|
@@ -737,6 +827,11 @@ def main(
|
|
|
737
827
|
not no_cache,
|
|
738
828
|
image_export_mode=image_export_mode,
|
|
739
829
|
page_size=page_size,
|
|
830
|
+
detail=detail_level,
|
|
831
|
+
compact=compact,
|
|
832
|
+
# User's `-o` path is a one-off export, not a cached artifact:
|
|
833
|
+
# don't occupy a cache slot keyed by an arbitrary destination.
|
|
834
|
+
update_cache=output is None,
|
|
740
835
|
)
|
|
741
836
|
if input_path.is_file():
|
|
742
837
|
click.echo(f"Successfully converted {input_path} to {output_path}")
|