examples/hooks: add snap_pack_on_stop.py for auto-pack on session end#55490
Open
achiii800 wants to merge 1 commit intoanthropics:mainfrom
Open
examples/hooks: add snap_pack_on_stop.py for auto-pack on session end#55490achiii800 wants to merge 1 commit intoanthropics:mainfrom
achiii800 wants to merge 1 commit intoanthropics:mainfrom
Conversation
Adds a robust opt-in `Stop` hook example that packs the current Claude Code session JSONL into a portable, lossless `.snap.jsonl` artifact when the session ends, then drops it at a configurable path (`$CLAUDE_SNAP_DROP_PATH`, default `~/Documents/claude-snaps`). The intended use case is hands-off cross-device session handoff — point `$CLAUDE_SNAP_DROP_PATH` at an iCloud Drive / Dropbox / Syncthing folder, and packed sessions auto-sync to other devices where they can be loaded into a Claude chat as continuation context. The hook depends on the `claude-snap` codec (https://github.com/achiii800/claude-snap, https://pypi.org/project/claude-snap/) which is a ~600-LOC pure-stdlib lossless codec for Claude Code session JSONLs with byte-identical roundtrip — distinct from existing tools in the space (claude-mem summarizes, cctrace transcribes, claude-conversation-extractor renders to markdown). It's the only one that produces a single portable artifact that roundtrips byte-for-byte. Robustness: - Soft-fails if `claude-snap` isn't on PATH (never crashes Claude Code) - Honors `CLAUDE_SNAP_DISABLED=1` for ad-hoc disable without editing settings - Configurable destination via `CLAUDE_SNAP_DROP_PATH` env var - Uses `subprocess.run` with arg lists (no shell injection surface) - 60s timeout on the pack invocation - Smoke-tested for happy path, missing-binary, disabled-flag, and empty-stdin cases Wiring instructions are in the file's docstring; users opt in by adding the hook entry to `~/.claude/settings.json`. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This was referenced May 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a robust opt-in
Stophook example that packs the current Claude Code session JSONL into a portable, lossless.snap.jsonlartifact when the session ends, then drops it at a configurable path ($CLAUDE_SNAP_DROP_PATH, default~/Documents/claude-snaps).The intended use case is hands-off cross-device session handoff — point
$CLAUDE_SNAP_DROP_PATHat an iCloud Drive / Dropbox / Syncthing folder, and packed sessions auto-sync to other devices where they can be loaded into a Claude chat as continuation context.This addresses one of the recurring requests in the cross-device-session cluster (#31992, #29847, #44063, #47926, #51816 — all variations of "let me move my session to another device"). It's not the official feature; it's a working example users can wire into their own settings today, while the official UX is being designed.
Why a hook example, not a CLI flag
The CLI flag conversation lives in #31992 ("Cross-machine session resume"). This PR doesn't try to add that — it adds the example users can wire up today using the existing hook system + an external codec.
Dependency
The hook calls into claude-snap (PyPI) — a ~600-LOC pure-stdlib lossless codec for Claude Code session JSONLs with byte-identical roundtrip. Distinct from existing tools in the space:
Soft import: if
claude-snapisn't on PATH, the hook noops with a stderr message — Claude Code is never affected.Robustness
claude-snapis missing (no crashes)CLAUDE_SNAP_DISABLED=1for ad-hoc disable without editing settingsCLAUDE_SNAP_DROP_PATHenv varsubprocess.runwith arg lists (no shell injection surface)Test plan
claude-snapis not on PATH<session-id>.snap.jsonlat$CLAUDE_SNAP_DROP_PATHwhen claude-snap is installed and a transcript path is providedCLAUDE_SNAP_DISABLED=1~/.claude/projects/🤖 Generated with Claude Code