Skip to content

Equality-Machine/ccshare

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ccshare

Share, browse, and resume Claude Code sessions — without leaking your paths or API keys.

ccshare turns a Claude Code session (~/.claude/projects/<hash>/<uuid>.jsonl) into a portable .ccsession bundle that's safe to send. Recipients can preview it in a browser (read-only) or import it and run claude --resume to pick up where you left off.

It also ships a local 3-pane web dashboard for browsing every session you've ever had, with markdown rendering and one-click export.

┌──────────────────┐    .ccsession    ┌──────────────────┐
│ ~/.claude/...    │  ─ scrubbed ─►   │ teammate's box   │
│ session.jsonl    │  ─ normalized ─► │ • view in browser│
│ (paths, secrets) │                  │ • or claude      │
│                  │                  │   --resume       │
└──────────────────┘                  └──────────────────┘

Status: v0.1.0. Single-file Python script, zero dependencies beyond stdlib. All 6 acceptance gates pass on every change (./verify.sh).


Why

A Claude Code session lives at ~/.claude/projects/<cwd-hash>/<uuid>.jsonl. You can't just send the file:

  • Paths are absolute and machine-specific. Your /Users/wq/Projects/foo means nothing on someone else's box, and claude --resume picks the project by hashing cwd.
  • Secrets leak. Tool results often contain API keys, tokens, env dumps that ended up there mid-debug.
  • Resume needs a real cwd. The recipient's filesystem won't have the same files in the same place.
  • Skills and MCP servers differ. A session that called /my-skill won't resume cleanly if the recipient doesn't have it.

ccshare handles all of this: redacts secrets (with a mandatory preview), normalizes paths into placeholders, packages the bundle, and remaps everything on import. The viewer never writes to the recipient's ~/.claude.


Install

git clone https://github.com/Equality-Machine/ccshare.git
cd ccshare
chmod +x src/ccshare
# optional: symlink onto your PATH
ln -s "$(pwd)/src/ccshare" ~/.local/bin/ccshare

Requires Python 3.10+. No pip install, no node modules.


Quickstart

As the sender

# 1. See your recent sessions
ccshare list

# 2. Preview what would be redacted (always do this first)
ccshare scan ~/.claude/projects/<hash>/<uuid>.jsonl

# 3. Package it
ccshare export-from-file ~/.claude/projects/<hash>/<uuid>.jsonl \
    --out share.ccsession --no-interactive

# Or by index from `list`:
ccshare export 1 --out latest.ccsession --no-interactive

The output .ccsession is a zip containing the rewritten transcript and a manifest with redaction summary + path mappings — typically <1MB for a normal session.

As the recipient

# View only — opens a browser, NEVER touches ~/.claude
ccshare view share.ccsession --port 7321

# Or import + register so claude --resume works
ccshare import share.ccsession --target ./imported --register --no-interactive
# → prints: cd ./imported && claude --resume <session-id>

As yourself: browse all your sessions

ccshare view-all --port 7321 --limit 100

A 3-pane dashboard in the browser:

  • Left: session cards (title, project, turn count, tool count)
  • Middle: rendered conversation with markdown, syntax-aware code blocks, expandable tool calls
  • Right: session metadata, files touched, tools used, skills, MCP servers, one-click Export .ccsession button (auto-redacts before download)

Filter sessions live with the search box. Useful for finding "that session where I figured out the OAuth bug last week".


What gets redacted / normalized

Redacted (replaced with [REDACTED:type]):

Type Pattern
Anthropic, OpenAI, OpenRouter API keys sk-ant-…, sk-…, sk-or-v1-…, sk-proj-…
GitHub tokens ghp_, gho_, ghu_, ghs_, ghr_
AWS access / secret keys AKIA…, AWS_SECRET_ACCESS_KEY=…
Slack tokens xoxb-, xoxp-, xoxa-, xoxr-, xoxs-
Email addresses *@*.tld
Private IPs in tool output 10.*, 192.168.*, 172.16-31.*

Normalized (placeholders preserved in manifest for reversibility):

What Placeholder
/Users/<you>/... {{HOME}}/...
Original cwd {{CWD}}
Git branch {{BRANCH}}

The manifest.json records every mapping, so import rewrites placeholders back to the recipient's environment.


Verification

./verify.sh is the dev loop. Every code change must keep all six gates green:

Gate What it proves
A Round-trip: export then import produces an equivalent transcript (3 fixtures: tiny / medium / complex)
B Resume works: imported session is registered to ~/.claude/projects/... so claude --resume finds it
C Viewer renders correctly (HTML structure check + screenshot evidence)
D Redaction recall = 100% on the adversarial fixture (20 needle secrets/PII items must all be caught)
E No /Users/<you>/* paths leak through; mappings are reversible
F 10-step end-to-end UX walkthrough
./verify.sh           # all gates
./verify.sh A         # single gate
SKIP_PEEKABOO=1 ./verify.sh   # skip the screenshot step

Day-0 setup pulls real sessions as test fixtures (gitignored — they contain your data) and runs the suite:

./tests/fixtures/bootstrap.sh
./verify.sh

The adversarial fixture (tests/fixtures/adversarial.jsonl + its expectations.json) is committed and serves as ground truth for redaction recall. If you find a leak, add a needle to the fixture and a counter-line to the expectations.


Architecture

Everything is in one ~1900-line Python file (src/ccshare), organized by section:

src/ccshare              single-file CLI
  ├─ Redaction patterns      regex bank + redactor
  ├─ Normalizer              path / cwd / branch placeholders
  ├─ Loader                  stream-parse jsonl events
  ├─ Packer                  write .ccsession (zip)
  ├─ Importer                unpack + remap + register session
  ├─ Viewer (cmd_view)       single-session browser preview
  └─ Dashboard (cmd_view-all) 3-pane multi-session HTTP server

tests/
  ├─ fixtures/
  │   ├─ tiny / medium / complex .jsonl    (gitignored, regenerated locally)
  │   └─ adversarial.jsonl + expectations  (committed; ground truth for Gate D)
  ├─ diff_session.py         Gate A — round-trip equivalence
  ├─ check_resume.py         Gate B — registration check
  ├─ check_viewer_html.py    Gate C — viewer DOM
  ├─ check_redactions.py     Gate D — recall
  ├─ check_normalize.py      Gate E — leak detection
  └─ gate_f_walkthrough.sh   Gate F — 10-step UX

docs/
  ├─ RUBRIC.md               every gate's pass criteria
  └─ peekaboo-probe.md       browser screenshot helpers

Single file is a deliberate choice: easy to drop into a teammate's ~/.local/bin/ and run with no install. If a module gets big enough to warrant splitting, it will earn its own file.


Roadmap

  • v0.1export-from-file, import, scan, view, view-all, list, export N, --register. Markdown rendering. In-page export from the dashboard. All 6 gates automated.
  • v0.2--with-files to package referenced files alongside the transcript. Interactive TUI for redaction preview.
  • v0.3 — visual baseline diff against committed PNG.
  • Maybe — Linear / Slack share targets, search across all sessions.

Anti-features (out of scope on purpose)

  • ❌ No cloud upload or "publish to cloud" service. Bundles are files; share them however you'd share any file (Lark, Signal, Drive, scp).
  • ❌ No encryption. Bundles are zip files. If the channel is sensitive, encrypt the channel.
  • ❌ No real-time collab.
  • ❌ No automatic file-snapshot resume restoration (--with-files is opt-in and packages copies, not snapshots).

Contributing

Pull requests welcome. The contract is simple:

  1. Don't break the gates. ./verify.sh must stay green. New behavior gets a new gate or extends an existing one.
  2. Adversarial fixture is ground truth for redaction. If you teach the redactor a new pattern, add a needle to adversarial.jsonl and a counter to expectations.json in the same PR.
  3. Single file unless there's a real reason. Modularity for its own sake is rejected; modularity that makes the code easier to test or reason about is welcome.

License

MIT. See LICENSE.


About

Built at Efflora by the AI Agent infrastructure team. We use this internally to share interesting Claude Code sessions among the team and to dig through our own session history.

If you find a leak the redactor missed, please file an issue with a minimal fixture — no real secrets, just the pattern.

About

Share, browse, and resume Claude Code sessions — without leaking your paths or API keys.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors