Releases: DazzleML/Claude-Session-Backup
v0.2.3 - pathkit slug disambig, csb resume cd/TTY fix, scan -d/-D/-s grammar
Claude-Session-Backup v0.2.3
claude-session-backup (csb) is a git-backed Claude Code session backup tool with timeline view, folder analysis, deletion detection, cross-platform plugin delivery, and session restore. v0.2.3 closes a curated bundle of bugs and grammar fixes around the "start at" path that csb list, csb scan, and csb resume derive for each session.
Prealpha notice: csb is functional and 226/226 tests pass, but it is not yet feature-complete. The first alpha release remains blocked on the same three items as v0.2.1 -- distilled conversation backup (#12), verified end-to-end JSONL restore (#13), and a CLI launcher for claude-code-history-viewer (#14). Use v0.2.3 for evaluation and active dogfooding; expect rough edges, bugs, and breaking changes until the alpha ships.
Why this release
v0.2.0 and v0.2.1 shipped the base tool and made it publicly installable. Real-world dogfooding immediately surfaced that "start at" -- the path csb tells you to cd to before running claude --resume <uuid> -- was wrong in several cases, and csb resume was effectively non-functional from a foreign cwd. v0.2.3 fixes all of that, plus the broader scan-command grammar issue where csb scan MyProject silently meant "search the cwd's MyProject/ subfolder" rather than "find sessions that mention MyProject." The fixes are grounded in an upstream claude-code source audit (#25, closed) that confirmed how the project-dir slug is actually set.
Highlights
csb resume <uuid>actually works from any cwd. Previously it printedcd <path>decoratively but never executed it, soclaude --resumeran in the wrong cwd and failed with "No conversation found." The fix has three layers: actual cwd handoff viasubprocess.run(cwd=target)(avoids Windowsos.execvpTTY-handoff issues), target derived from the slug-decoded path (the only cwd whose slug matches the JSONL's parent directory), and graceful fallback when the target folder has been deleted. (#24)csb scanterm vs. folder is now explicit. Barecsb scan MyProjectis now a metadata-search term (matches session name, project, or folder paths). Path-strict scope is reached via new flags:-d(folder + descendants),-D(this folder only),-s(start_folder only). Combinable:csb scan -d MyProject my-paperscopes by path then filters by term. There's also a./dirnameshortcut that auto-promotes to-d. This is a breaking change to the bare-positional semantics -- documented under "Migration notes" below. (#20)- Pathkit slug decoding handles ambiguous on-disk slugs correctly. When two real folders happen to encode to the same slug (e.g., a literal
New--Projectfolder AND a siblingNew\.Projectfolder), the decoder now picks the right one via a three-tier fallback chain that cross-checks against the JSONL's recordedcwdevents. Preserves #19's behavior unchanged for the common single-decoding case. (#23) csb list --top Nand--all-folders-- control how many "other" folders display under each session, with a persistentdisplay_top_foldersconfig key for users who want a non-default. The indexer change behind this also revealed the long tail of cwds that was previously truncated at index time, fixing missing(Nx)counts on the "start at" line. (#21)- "start at" reports the cwd that
claude --resumewill actually find the session under -- not the cwd-histogram mode from JSONL events. This was the original bug that kicked off the whole release wave; the fix shipped in63079b9and has been validated against real session data. (#19) - 226/226 tests pass (was 119 in v0.2.1; +107 net). New automated coverage focuses on parser grammar, SQL helpers with window-function gating, multi-candidate slug disambiguation across three tiers, and
cmd_resumesubprocess behavior with mocked-but-call-sequence-asserted launches. The companion human checklist (tests/checklists/v0.2.3__Feature__csb-scan-disambiguation.md) covers what the mocks can't -- realclaude --resumeexec, terminal rendering, cross-shell behavior.
What's new
csb resume actually works from any cwd (#24)
The pre-fix behavior was a long-standing alpha-blocker: csb resume <uuid> would print a cd <path> line and exec claude --resume <uuid>, but never actually change directory -- so claude ran in the wrong slug folder and failed.
# v0.2.2 and earlier (broken from any cwd != session's start_folder)
$ csb resume 5656447d
Resuming: CLAUDECODE__Rebuilding-Lost-Jsonl-Transcripts
ID: 5656447d-a250-45e0-9b21-dda1ccd8bbf2
cd C:\Users\Extreme
claude --resume 5656447d-a250-45e0-9b21-dda1ccd8bbf2
No conversation found with session ID: 5656447d-a250-45e0-9b21-dda1ccd8bbf2
In v0.2.3 the launch goes through subprocess.run([...], cwd=target), so claude inherits the right cwd and the user's terminal at the same time. Three layers fixed:
- The cd hint is now operative --
subprocess.run'scwd=parameter sets the child's cwd without mutating the parent. - The target is derived from the slug-decoded path via
pathkit.derive_start_at(jsonl_path)rather than the JSONL'sfirst_cwd. If the usercd-ed into a different folder before the first JSONL event was written,first_cwdand the slug-decoded path can diverge -- the slug-decoded path is the only cwd from whichclaude --resumewill find the file. - Using
subprocess.runinstead ofos.execvpis required on Windows: Python'sos.execvpthere is_spawnv(P_OVERLAY, ...)-- the parent process exits and a child spawns, but the controlling-TTY relationship doesn't transfer cleanly (claude TUI renders to stdout but stdin keystrokes go into the void).subprocess.runinherits the parent's stdin/stdout/stderr handles so the TUI works correctly.
csb scan grammar (#20)
The bare positional now means "filter by term." Path-strict scope uses explicit flags:
csb scan # cwd path-prefix (today's bare default preserved)
csb scan MyProject # broad metadata substring search (name, project, folders)
csb scan -d MyProject # path-strict: <cwd>\MyProject + descendants
csb scan -D MyProject # path-strict: <cwd>\MyProject only (no descendants)
csb scan -s MyProject # start_folder only -- "what sessions originated here?"
csb scan -d MyProject my-paper # scope-then-filter: MyProject + descendants AND mentions "my-paper"
csb scan -d MyProject* # trailing-* sibling-prefix expansion (matches MyProject, MyProject-fork, ...)
csb scan ./MyProject # shortcut: auto-promotes to `-d MyProject` (no flag-name to remember)
csb scan ./MyProject my-paper # shortcut composes with term filterHints emit on stderr (so --json stdout stays clean):
[info]when a term coincides with a cwd subfolder, suggesting-d <term>for path-strict search.[warning]when-d <pattern>resolves to a path that doesn't exist; gracefully falls back to broad-term search if a term was also given.
-d, -D, -s are mutually exclusive. The 2-positional shortcut form (./MyProject my-paper) is only allowed when the first positional is a ./ / .\ / . shortcut; csb scan MyProject my-paper (two bare terms) is rejected with a clear error suggesting the explicit -d form.
Pathkit multi-candidate disambiguation (#23)
When the slug C--code-New--Project happens to decode to two real folders on disk -- e.g., a literal New--Project AND a sibling New\.Project -- pathkit now picks the right one via a three-tier fallback:
| Tier | Signal | When |
|---|---|---|
| 1 | first_cwd matches a candidate exactly or as prefix-with-separator |
The session's first JSONL event recorded a cwd that lives under one of the candidates. The canonical "session-open cwd" answer. |
| 2 | folder_usage histogram (sum of matching cwd-counts) |
first_cwd doesn't match any candidate, but the JSONL's full cwd histogram weighs one candidate higher than the others. Subdirectory cwds count toward their parent. |
| 3 | Encoded-length heuristic | No JSONL signal helps. Falls back to #19's existing first-match return. Preserves prior behavior for callers without JSONL access. |
Path comparisons use os.path.normcase + os.path.normpath (case + separator + trailing-slash insensitive). Single-candidate slugs short-circuit -- zero perf change for the unambiguous case. The signature change is additive: decode_project_slug(slug, first_cwd=None, folder_usage=None) and derive_start_at(jsonl_path, first_cwd=None, folder_usage=None) both default to None, so #19-era callers work unchanged.
Folder-usage long tail and --top N / --all-folders (#21)
Pre-v0.2.3 the indexer truncated folder_usage to 1 + top_n_folders rows at index time, which made the long tail of cwds invisible regardless of any renderer flag. This release removes the index-time truncation entirely: every distinct cwd from the JSONL events is persisted, and the renderer truncates at display time.
csb list --top 5 # show top 5 "other" folders per session row
csb list --all-folders # show every cwd ever recorded for the sessionFor users who want a different default permanently, the new display_top_folders config key in ~/.claude/session-backup-config.json:
{
"display_top_folders": 5
}Negative values mean "show all" (equivalent to --all-folders). Resolution precedence: --all-folders > --top N > config > module default (3).
Note: existing index rows are still truncated until re-indexed. Run csb rebuild-index to backfill the long tail across all sessions; new sessions and any session touched by csb backup will pick up the new behavior on the next pass without a full rebuild.
"start at" semantics (#19, recap)
Thi...
v0.2.1 (prealpha) -- public repo, install flows, first PyPI publish
Maintenance release of claude-session-backup (csb) -- a git-backed Claude Code session backup tool with timeline view, folder analysis, deletion detection, cross-platform plugin delivery, and session restore. This release ships the repository publicly, fixes published-surface issues that surfaced along the way, and sets up repo infrastructure (traffic tracking, dashboards) for later automation.
Prealpha notice:
csbis functional and 73/73 tests pass, but it is not yet feature-complete and has not been broadly tested outside of active dogfooding. The first alpha release is blocked on three items: distilled conversation backup (#12), verified end-to-end restore (#13), and a CLI launcher for claude-code-history-viewer (#14). Use v0.2.1 for evaluation and early adoption; expect rough edges, bugs, and breaking changes until the alpha ships.
Why this release
v0.2.0 was cut while the repository was still private. With v0.2.1 the repository is public, the install flows are updated to match, and the README now speaks honestly about the project's maturity. This is the first release where someone can discover csb in the wild and succeed at installing it end-to-end.
Highlights
- Prealpha warning banner in README so anyone who lands on the repo sees the maturity level before they type
pip install .... Calls out the three alpha gates explicitly. - First PyPI publish --
pip install claude-session-backupnow works. The release workflow ran on the v0.2.1 tag and the package is live at https://pypi.org/project/claude-session-backup/. The GitHub-based install (pip install git+...) remains as an equivalent fallback. - Claude Code plugin install via marketplace URL -- no clone required. One command adds the marketplace; another installs the plugin.
- Numbered 5-step Quick Start that makes the Claude Code plugin install an explicit step. Without the plugin, the PreCompact hook isn't registered and compactions happen silently -- exactly the failure mode csb is meant to prevent. Previous Quick Start hid the plugin install inside the Automation section further down.
- Traffic tracking infrastructure -- nightly GitHub Actions workflow populates a public gist with install/download/clone/view counts, surfaced via the Installs badge and a
docs/stats/dashboard. Deployed viaghtraf; dashboard becomes live once GitHub Pages is enabled. docs/platforms.md-- honest verification matrix per platform (Windows verified, Linux/macOS designed for but not yet run end-to-end by the maintainer, BSD untested). Fixes the 404 the Platform badge was pointing at.- Version bump 0.2.0 → 0.2.1 across all four version locations (
_version.py,pyproject.tomldynamic version,.claude-plugin/plugin.json,.claude-plugin/marketplace.json). Stays PEP 440-clean sopip installpicks up updates without--pre.
What's in this release
Install paths (end-user)
# From PyPI (recommended)
pip install claude-session-backup
# From GitHub (equivalent fallback)
pip install git+https://github.com/DazzleML/Claude-Session-Backup.git
# From source (development / contributing)
git clone https://github.com/DazzleML/Claude-Session-Backup.git
cd Claude-Session-Backup
pip install -e ".[dev]"Claude Code plugin install -- cloneless
# Add the DazzleML marketplace (one-time)
claude plugin marketplace add "DazzleML/Claude-Session-Backup"
# Install the plugin
claude plugin install claude-session-backup@dazzle-claude-session-backupThe plugin registers PreCompact and SessionEnd hooks that automatically run csb backup --quiet before /compact (to preserve full conversation detail) and on session exit. Uses a Node.js bootstrapper (run-hook.mjs) to find the correct Python binary on each platform.
Commands
No new commands in this release -- the CLI surface is unchanged from v0.2.0. Full set for reference:
csb backup # Scan, index, git commit (noise + user)
csb backup --no-commit # Scan and index only
csb list [-n 20] # Timeline view (default: last-used)
csb list [keyword] # Filter by keyword in name/project/folders
csb list --sort {last-used|expiration|started|oldest|messages|size}
csb list --deleted # Show deleted sessions
csb scan [path] # Find sessions touching this directory
csb scan [path] -NU # Prefix-only match (skip folder-usage search)
csb status # Summary stats
csb show <session-id> # Detailed session info
csb search "query" # Search session metadata
csb restore <session-id> # Restore deleted session from git history
csb resume <session-id> # Launch claude --resume
csb rebuild-index # Reconstruct SQLite from scratch
csb config [key] [value] # View/edit configurationFixes
- Acknowledgement URL for the upstream Claude Code History Viewer author was pointing at the wrong person; corrected in the README's acknowledgements section.
- Installs badge URL was pointing at
DazzleTools/dazzlecmd's traffic gist (copy-paste artifact). Now points at csb's own public badge gist.
Documentation
docs/platforms.md-- cross-platform verification matrix and issue reporting template.CHANGELOG.mdadded in Keep-a-Changelog format with entries for v0.2.0 and v0.2.1.- Full README restructure so the "install → set up hooks → start using it" flow is linear and obvious.
Version history (0.2.x)
| Version | Key change |
|---|---|
| v0.2.1 | Current -- public-repo prep, prealpha banner, traffic tracking, install flow updates |
| v0.2.0 | csb list --sort, csb scan folder-usage search, cross-platform Claude Code plugin, two-commit backup model, timeline view with purge countdown, resume/restore |
Platform support
| Platform | Status |
|---|---|
| Windows 11 | Tested (primary dev platform) |
| Linux | Designed for -- not yet verified end-to-end by the maintainer |
| macOS (Intel + Apple Silicon) | Designed for -- not yet verified end-to-end by the maintainer |
| BSD (FreeBSD / OpenBSD) | Untested -- likely works, bug reports welcome |
See docs/platforms.md for per-platform notes and a reporting template.
Requirements
- Python 3.10+
- Git (for backup storage)
~/.claude/initialized as a git repository (git -C ~/.claude init)- Node.js (plugin users only) -- already installed if you're using Claude Code
Known limitations
- Three of four alpha-release criteria are still open (#12, #13, #14). Distilled backup, verified end-to-end restore, and
csb vieware all tracked for the next feature release. - GitHub Pages-backed stats dashboard becomes live only once Pages is enabled on the repo. The Installs badge will populate after the first scheduled run of the
traffic-badges.ymlworkflow (nightly at 3am UTC; can be triggered manually withgh workflow run "Track Downloads & Clones" -R DazzleML/Claude-Session-Backup). - CI runs Windows-only at the moment. Adding Linux + macOS runners to the matrix is scoped as a follow-up.
Full changelog since v0.2.0
Single commit: dfae68f -- feat: add prealpha banner, fix broken README links, deploy traffic tracking -- v0.2.1
See CHANGELOG.md for the categorized breakdown.
v0.2.0 (prealpha) -- sort, scan folder-usage, cross-platform hooks
First public release of claude-session-backup (csb) -- a git-backed Claude Code session backup tool with timeline view, folder analysis, deletion detection, cross-platform plugin delivery, and session restore.
Prealpha notice: The tool is functional and 73/73 tests pass, but the first alpha release is blocked on three remaining criteria: distilled conversation backup (#12), verified end-to-end restore (#13), and a CLI launcher for claude-code-history-viewer (#14). Use v0.2.0 for evaluation and early adoption; expect rough edges and rapid iteration.
Highlights
csb list --sort-- Sort sessions bylast-used(default),expiration,started,oldest,messages, orsize. Surface at-risk sessions before they're purged by Claude Code's cleanup.csb scanfolder-usage search -- Find sessions by the directories they actually worked in, not just where they started. Catches sessions that were launched from a parent folder but did real work somewhere else.- Cross-platform Claude Code plugin -- Install via
claude plugin marketplace add+claude plugin install. Uses a Node.js bootstrapper (run-hook.mjs) to find the correct Python binary on Windows, Linux, and macOS without shell operators. - Two-commit backup model -- Separates noise files (session transcripts, caches, telemetry) from user files (configs, skills, agents) into distinct commits. Aligns with
dz claude-cleanupclassification. - Timeline view with purge countdown -- Rich terminal formatting shows days remaining before each session is eligible for Claude Code's auto-cleanup, with color gradient from green to red.
- Session resume and restore --
csb resume <id>launchesclaude --resume;csb restore <id>recovers deleted sessions from git history.
What's in this release
New commands
csb backup # Scan, index, git commit (noise + user)
csb list [keyword] [--sort KEY] # Timeline with filter and sort
csb list --sort expiration # Sessions closest to purge first
csb scan [path] [-NU] # Find sessions touching a directory
csb resume <id> # Launch claude --resume
csb show <id> # Detailed session info
csb search "query" # Search session metadata
csb restore <id> # Restore from git history
csb status # Summary stats
csb rebuild-index # Reconstruct SQLite from diskNew plugin
Install the hook-based automation:
git clone https://github.com/DazzleML/Claude-Session-Backup.git
cd Claude-Session-Backup
claude plugin marketplace add ./
claude plugin install claude-session-backup@dazzle-claude-session-backupThe plugin registers PreCompact and SessionEnd hooks that automatically run csb backup --quiet before /compact (to preserve full conversation detail) and on session exit.
Platform support
- Windows (verified)
- Linux (plugin bootstrapper designed for, not yet verified end-to-end)
- macOS (plugin bootstrapper designed for, not yet verified end-to-end)
Requirements
- Python 3.10+
- Git (for backup storage)
~/.claude/initialized as a git repository
Full changelog since v0.1.3
Added
csb list --sortwith 6 choices (last-used,expiration,started,oldest,messages,size)csb scanfolder-usage search that matches sessions by their working directories, not just start foldercsb scan --no-usage/-NUopt-out to disable folder-usage searchhooks/scripts/run-hook.mjsNode.js hook bootstrapper (solvespythonvspython3cross-platform)find_sessions_by_folder_usage()inindex.pyfor SQL-backed folder queries- 11 new tests: 7 index sort tests, 4 CLI
--sortparse tests (73 total, up from 62)
Changed
hooks/hooks.json: PreCompact and SessionEnd now invokenode run-hook.mjsinstead ofpython backup-hook.pydirectly.claude-plugin/marketplace.json: renamed todazzle-claude-session-backupto avoid conflict with session-logger's marketplacegit_ops.pyNOISE_DIRS: addedprojects/andsession-envto matchdz claude-cleanupclassificationlist_sessions()signature: newsort_key="last-used"kwarg (backward compatible)README.md: plugin-based install is now the preferred automation path, manual settings.json kept as fallbackCONTRIBUTING.md: project structure now documents the plugin layer alongside the CLI package
Fixed
git_ops.pyhad a duplicatesession-enventry inNOISE_FILES(removed)
Known limitations
- Alpha criteria not yet met: distilled backup (#12), verified restore (#13), and CLI history-viewer launcher (#14) are all required for the first alpha release
csb scanfalse positive: matches sibling-prefix folders (C:\code\chrome-extensionmatchescsb scan chrome) -- acceptable for a discovery tool- Plugin cache is not auto-updated: after pulling new changes, you must
claude plugin uninstalland reinstall to refresh the cache - Stale index on
csb list: if you don't runcsb backupregularly, sort-by-expiration shows outdated data (#5)
Related releases
None -- this is the first public release.
Acknowledgements
This project draws inspiration from:
- claude-vault by @kuroko1t -- FTS5 search design, JSONL parsing patterns, Claude Code hook integration
- claude-code-history-viewer by @jhlee0409 -- full JSONL data model understanding, file restore patterns
- claude-session-logger -- real-time session logging infrastructure,
run-hook.mjspattern for cross-platform Python bootstrap
Links
- Repository: https://github.com/DazzleML/Claude-Session-Backup
- Issue tracker: https://github.com/DazzleML/Claude-Session-Backup/issues
- Roadmap: #1
- Alpha criteria: #12, #13, #14 (labeled
alpha-blocker)