
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
A Ruby tool to export Claude Code conversations to GitHub-flavored Markdown format, or using templates, styled to look similar to Claude Desktop conversations, GitHub or, really any other style, for easy reading.
<noai> I created this tool because, as I'm exploring using agentic coding tools, I've found myself wanting to share examples with friends and colleagues, so we can learn from each other. I have tried to fully vibe code this project, but I have, on occasion, gone rogue and hand coded tooling to help me and Claude better understand the JSONL structure or fix issues that it seemed to struggle with. I've used other tools, like Claude Desktop with Opus 4.1 and the humble web search. In fact, the very beginning of this project was conducted in Claude Desktop where I asked it to research tooling that already does what I was trying to do. </noai>
⚠️ Security Notice: This tool includes automatic secret detection, but always review your exports before sharing. You are responsible for ensuring no sensitive information is included in shared conversation exports.
gem install ccexport
If you don't have Ruby installed or aren't familiar with Ruby development, follow these steps:
macOS users: If you don't have Homebrew installed:
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Follow the "Next steps" instructions shown after installation to add Homebrew to your PATH
Windows users with WSL (Windows Subsystem for Linux):
# First, ensure you're running Ubuntu/Debian in WSL
# Install Homebrew for Linux
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Add Homebrew to your PATH (replace USERNAME with your actual username)
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.bashrc
source ~/.bashrc
# Install build dependencies
sudo apt-get update
sudo apt-get install build-essential
Ubuntu/Debian users (native Linux):
Recommended: Use Homebrew for easier dependency management
# Install Homebrew for Linux (same as WSL instructions)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Add Homebrew to your PATH
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.bashrc
source ~/.bashrc
# Install build dependencies
sudo apt-get update
sudo apt-get install build-essential
# Install basic dependencies
sudo apt-get update
sudo apt-get install curl git build-essential
# Note: You'll need to manually install TruffleHog and cmark-gfm
# TruffleHog: https://github.com/trufflesecurity/trufflehog#installation
# cmark-gfm: You may need to build from source or find alternative packages
If you don't have a Ruby version manager yet, we recommend rbenv:
# macOS with Homebrew
brew install rbenv ruby-build
# Ubuntu/Debian
sudo apt install rbenv
# Add rbenv to your shell
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
# or for zsh users:
echo 'eval "$(rbenv init -)"' >> ~/.zshrc
# Restart your terminal or run:
source ~/.bashrc # or ~/.zshrc
If you already use a different Ruby version manager:
# Install latest Ruby 3.4
rvm install 3.4
rvm use 3.4 --default
# Add Ruby plugin if not already added
asdf plugin add ruby
# Install latest Ruby 3.4
asdf install ruby latest:3.4
asdf global ruby latest:3.4
# Install latest Ruby 3.4
mise install ruby@3.4
mise global ruby@3.4
# Install latest Ruby 3.4
rbenv install 3.4.3
rbenv global 3.4.3
# Verify installation
ruby --version # Should show Ruby 3.4.3
# Install the gem
gem install ccexport
# Install required external tools (if you installed Homebrew)
brew install trufflehog cmark-gfm
# If you're using system package managers instead of Homebrew:
# - TruffleHog: https://github.com/trufflesecurity/trufflehog#installation
# - cmark-gfm: May require building from source on some Linux distributions
bundle install
brew install trufflehog
brew install cmark-gfm
on macOS)Run the exporter in any directory where you've used Claude Code:
# Basic usage - export all conversations
ccexport
require 'ccexport'
ClaudeConversationExporter.export
# Basic usage - export all conversations
ccexport
# Filter by date range
ccexport --from 2024-01-01 --to 2024-01-31
# Filter using timestamp format (copy from --timestamps output)
ccexport --from "August 09, 2025 at 06:03:43 PM"
# Export only today's conversations
ccexport --today
# Export from different project directory
ccexport --in /path/to/project
# Custom output directory
ccexport --out /path/to/output
# Export to specific markdown file with preview
ccexport --out myconversation.md --preview
# Include timestamps
ccexport --timestamps
# Generate HTML preview and open in browser
ccexport --preview
# Generate HTML preview without opening browser
ccexport --preview --no-open
# Use custom template
ccexport --preview --template mytemplate
# Use GitHub template
ccexport --preview --template github
# Process specific JSONL file
ccexport --jsonl /path/to/conversation.jsonl --out specific-conversation.md
# Silent mode (suppress all output)
ccexport --silent
# Complex example: custom project, date range, output, timestamps, and preview
ccexport --in /path/to/project --from 2024-01-15 --out ./my-exports --timestamps --preview
--in PATH
: Project path to export conversations from (default: current directory)--from DATE
: Filter messages from this date (YYYY-MM-DD or timestamp format from --timestamps output)--to DATE
: Filter messages to this date (YYYY-MM-DD or timestamp format from --timestamps output)--today
: Filter messages from today only (in your local timezone)--out PATH
: Custom output directory or specific file path (supports relative paths, use .md extension for specific file)--timestamps
: Show precise timestamps with each message for easy reference--preview
: Generate HTML preview and open in browser automatically--no-open
: Generate HTML preview without opening in browser (requires --preview)--template NAME_OR_PATH
: HTML template name (from templates dir) or file path (default: default)--jsonl FILE
: Process a specific JSONL file instead of scanning directories-s
, --silent
: Silent mode - suppress all output except errors--help
: Show usage informationrequire_relative 'lib/claude_conversation_exporter'
# Export from specific project path to custom output directory
exporter = ClaudeConversationExporter.new('/path/to/project', 'my-conversations')
result = exporter.export
puts "Exported #{result[:sessions_exported]} conversations"
puts "Total messages: #{result[:total_messages]}"
The exporter includes several built-in templates:
default
: Clean, modern styling with rounded corners and a warm color palettegithub
: Mimics GitHub's markdown rendering with GitHub's official color scheme and typographysolarized
: Beautiful Solarized color scheme with automatic light/dark mode detection based on user's system preferenceYou can also create custom templates by placing .html.erb
files in the lib/templates/
directory or by specifying a full file path.
The exporter creates Markdown files with:
For complete examples of the exported format, see the sample files in this repository:
These files demonstrate real conversation exports with:
The VIBE files showcase advanced features like collapsible tool sections, syntax highlighting, thinking message formatting, and proper message threading that would be impractical to show in README snippets.
The exporter automatically generates detailed logs of any messages that were skipped during processing. These logs are saved as JSONL files alongside your exported Markdown.
leaf summary message
: Summary messages at conversation endsapi error or meta message
: System errors and metadataempty or system-generated message
: Empty content or system messagesoutside date range
: Messages filtered by --from/--to options (not logged){"line":42,"reason":"api error or meta message","data":{"type":"meta","error":"rate_limit"}}
Each message in the exported Markdown includes HTML comments with Claude message IDs for easy cross-referencing. You can see this in action throughout the VIBE.md file where each message heading includes a comment like <!-- msg_01RMr1PPo2ZiRmwHQzgYfovs -->
.
This allows you to:
⚠️ IMPORTANT SECURITY NOTICE ⚠️
The exporter automatically scans conversation content for common secrets and sensitive information, then automatically redacts detected secrets before export. However, you are still responsible for reviewing your exports before sharing them publicly.
The tool uses TruffleHog, the industry-standard secret detection engine, to detect and redact:
When secrets are detected, the exporter:
[REDACTED]
placeholders*_secrets.jsonl
⚠️ Detected 3 potential secrets in conversation content (see conversation_secrets.jsonl)
Please review and ensure no sensitive information is shared in exports.
The generated *_secrets.jsonl
file contains structured data for each detection:
{"context":"message_msg_01ABC123_text","type":"secret","pattern":"AWS","confidence":false}
{"context":"message_msg_01XYZ789_text","type":"secret","pattern":"SlackWebhook","confidence":false}
Field explanations:
context
: Unique identifier for the message locationtype
: Always "secret" for TruffleHog detectionspattern
: TruffleHog detector name (e.g., "AWS", "Github", "SlackWebhook")confidence
: Boolean indicating if the secret was verified against the actual service--jsonl
option to process specific conversations when unsureOriginal content with secrets:
Here's my GitHub token: ghp_1234567890123456789012345678901234567890
AWS credentials: AKIA1234567890123456 secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Slack webhook: https://hooks.slack.com/services/T1234567890/B1234567890/abcdefghijklmnopqrstuvwx
Automatically redacted output:
Here's my GitHub token: [REDACTED]
AWS credentials: [REDACTED] secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Slack webhook: [REDACTED]
Note: TruffleHog focuses on high-confidence secret patterns. Some parts may remain unredacted if they don't match specific detection patterns, which reduces false positives but requires manual review.
Run the test suite:
bundle exec rspec
This Ruby implementation is based on the excellent claude-code-exporter JavaScript project by developerisnow. The original project provides the foundation for understanding Claude Code's session storage format and export patterns.
The GitHub-flavored Markdown formatting features were implemented with reference to the GitHub Markdown Cheatsheet, particularly the collapsed sections functionality.
--jsonl
optionbrew install trufflehog
brew install cmark-gfm
The repository includes comprehensive examples generated from the actual Claude Code conversation that was used to build this tool:
Note: The full version demonstrates the exporter's capability to handle large, multi-session conversations that span the entire development of this tool. The regular VIBE examples above are filtered to a manageable size for easy browsing and template comparison.
These examples showcase:
Use the included script to regenerate examples for all templates:
./generate_vibe_samples
This automatically creates VIBE sample files for each available template, making it easy to compare styling and features across all templates.
MIT License - feel free to use and modify as needed.
FAQs
Unknown package
We found that ccexport demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.