A session manager for Claude Code that creates isolated workspaces with automatic documentation.
Claude Code doesn't require a project. You can spin up an instance to debug an API, troubleshoot home automation, research a hardware problem, or explore any idea that comes to mind.
But conversations get lost. You discover key insights, create useful scripts, figure out a tricky configuration - then the session ends and it's gone.
cs gives every task a home:
cs debug-api # Investigate that flaky endpoint
cs homeassistant # Fix your smart home setup
cs router-config # Document your network settings
cs research-llms # Explore a topic, keep your notesEach session is a persistent workspace - documentation and secrets that survive across conversations.
No git repo required. No project structure needed. Just a name for what you're working on.
-
Isolated session workspaces - Each session has its own directory with structured documentation
-
Documentation templates - Pre-configured markdown files for the session narrative and outcome
-
Automatic git version control - Every session gets a local git repo; in-session edits are autosaved to a shadow ref for crash recovery
-
Session locking - PID-based lock prevents the same session from being opened in two terminals simultaneously; use
--forceto override. cs also treats a session as live when its statusline heartbeat is fresh — in the TUI (■ live · unlocked),cs -live, and thecs -usagemarker — so a conversation opened outside cs still registers as live. The destructive guards (cs -rm/-archive/-spawn) stay on the strict PID lock, so a session whose process is gone is still removable without--force -
Deterministic Claude-session resume - Each session pre-allocates a conversation UUID in the gitignored
.cs/local/state, socs <name>resumes the exact conversation viaclaude --resume <uuid>, not the most-recent one--continuemight pick from a sibling. Aps-based guard refuses to launch a second claude for the same conversation (it counts a process only when the UUID follows--session-id,--resume/-ror--parent-session-id, so a leftover Bash-tool child carrying the id does not block a relaunch;--forceoverrides), and every launch passes--nameplus a per-session/colorso parallel sessions stay visually distinct. -
Per-session memory path redirect - cs points Claude Code's built-in auto-memory writer at
<session>/.cs/memory/(viaCLAUDE_COWORK_MEMORY_PATH_OVERRIDE) so durable facts land in the session instead of the global project store. The harness owns how memory files are written (naming, frontmatter,MEMORY.mdindex); cs owns only the storage path. -
Conversation rotation - a heavy conversation can hand off to a fresh one without losing context: the
rotateskill (self-invoked, or nudged once per conversation at 65% context) writes a lineage-stamped handoff to.cs/handoffs/and arms it, then/clearcontinues from it without leaving Claude Code — and continues on its own, since the session wakes itself a moment later and starts the handoff's next step with nothing typed (CS_NO_ROTATION_WAKE=1to wait for a word instead). Exiting and answeringrat the nextcs <name>launch does the same;ddiscards the handoff.cs -conversationsshows the resulting chain. Thecsmod, a Claude Code function-hooks plugin the installer deploys and every cs launch enables, puts a1: rotate this conversationbutton above the prompt once context reaches 40% (CS_ROTATE_BUTTON_CTXmoves it), beside2: wrap up this session, which asks first, since a wrap runs two Opus passes and replaces the summary:2opens the engine's own dialog —Run /wrap for this session?, withYes, wrap upandNot now— and only the yes runs it (once a wrap finishes, its last pass writes.cs/local/wrappedand the key hides until the next turn that starts from a prompt, so a finished wrap is not offered again); the rotate press runs/rotate, and once the handoff is armed the band draws1: /clear and continue from the handoffalone and runs the/clearitself. The mod presses the button for you once a turn ends past 80% context: it runs/rotate, and once the handoff is armed the capsule counts down 20 seconds to the/clear(press1to go now, send a prompt to stop it).CS_ROTATE_FORCE_CTX=<percent>moves that threshold andCS_ROTATE_FORCE_CTX=offturns it off; the first launch on a machine says so once.CS_NO_FUNCTION_HOOKS=1withholds the mod; see docs/hooks.md. -
Release notes in the session - when a launch finds a newer cs, the
cs-updatemod (a function-hooks plugin the installer deploys beside thecsmod) opens one pane with the full changelog for every version above the installed one, once per load of the mod (a launch, or a plugin reload), in the conversation cs launched:1runscs -updatein place (the new files take effect on the next launch; the pane keeps the outcome until you close it),Esccloses it, and/cs-updatebrings it back./config→cs-update.showReleaseNotesturns the launch pane off;/cs-updatestill works.CS_NO_FUNCTION_HOOKS=1withholds both mods. -
Works outside the
cslauncher - a session is any directory containing.cs/, so the hooks find it whethercs <name>started the conversation or you opened the folder in a front end that cannot export environment into it — Claude Code desktop, an IDE, a plugin. A terminal is the exception, because there a session is entered by runningcs:claudetyped in a session directory stays cs-blind.csstill owns creating sessions and the launch experience (resume prompt, rotation menu, statusline, tmux spawner); what carries over is the documentation, narrative, timeline, autosave, and scope grounding. The session's recorded conversation stays with thecslaunch, so a conversation opened another way — or a teammate claude working in the same folder — contributes to the session without becoming the onecs <name>resumes. When one of those is newer than the recorded conversation, the next launch says so and names it, rather than resuming the older one in silence:A newer conversation was opened here outside cs: 11111111-2222-4333-8444-555555555555 Resuming the recorded one instead. To continue the newer: claude --resume 11111111-2222-4333-8444-555555555555Drop
.cs/local/disabledinto a session to opt it out.
- Prose hygiene - the
prose-hygieneskill carries the full AI-slop taxonomy (phrases, structures, voice rules) that no regex can catch;/summaryapplies it with a subagent judge that scores.cs/summary.mdand returns concrete rewrites. See skills/prose-hygiene/SKILL.md - Auto-grounded scope - On each code-work prompt, the
scope-prompthook injects a bounded context block — matching tracked files, recent commits, and a working-tree diff — grounding Claude in the current codebase before it acts. Capped at 8000 bytes; opt out per-session withCS_SCOPE_DISABLE=1. Each run also appends a stage trace to the machine-local.cs/local/scope-prompt.trace, so a run the hook's timeout kills leaves a trail naming the stage it hung on; on a slow machine the hook skips the scan onceCS_SCOPE_BUDGET_MS(1500 ms) has passed and still delivers the digests and notes; opt out withCS_SCOPE_TRACE_DISABLE=1. The same hook asks Claude to question an ambiguous request rather than guess at it; skip one turn with a leading~, or the session withCS_CLARIFY_DISABLE=1. It also names the day when it changes: a conversation that lives across midnight gets one line saying what today is and what date it last heard, and nothing on any other prompt; opt out withCS_DATE_REMINDER_DISABLE=1. See docs/hooks.md - Prompt rewriting - Type a rough prompt, press
ctrl+g, and the composer holds a precise engineering request you can review, edit and send. cs points$EDITORat a rewrite shim, so Claude Code's own external-editor round-trip does the substitution; nothing is sent on your behalf, and every failure leaves your text exactly as typed. Claude Code blanks the interface for the round-trip, so the shim fills that screen: your prompt held in a margin rule that breathes while the rewrite runs, the engine and model answering it, and the time left against the timeout — shown only where something actually enforces one.CS_REWRITE_PROGRESSpicks the style —screen, anativeline in Claude Code's own idiom, a bare centredline, or astaticone-liner. Nothing interrupts a rewrite from the keyboard — the terminal sendsctrl+cto Claude Code too, ending the session — so the timeout is the only bound.CS_REWRITE_PROVIDER=openaior=geminirewrites with that vendor instead: each prefers its CLI when the binary is on PATH (codex,agy, on your subscription) and falls back to the vendor's API when it is not. Append-api(gemini-api,openai-api) to reach the API past an installed CLI, which is roughly eight times faster and the only way to Gemini's lite tier;claude-apicalls Anthropic's Messages endpoint rather than driving Claude Code.CS_REWRITE_PROVIDER=grokreaches xAI's OpenAI-compatible endpoint onXAI_API_KEYorGROK_API_KEY— API-only, since xAI ships no rewriter CLI to prefer — defaulting togrok-4.3, the fastest xAI model measured that never resolved an unspecified thing by fiat.CS_REWRITE_MODELsets the model on every arm. Opt out withCS_REWRITE_DISABLE=1. See docs/hooks.md - Second opinion at a decision point - When claude-council or the codex plugin is present, the Stop hook appends a standing note naming what each one offers:
/claude-council:advise, which puts the conversation itself to external models instead of a question you retype, and/codex:reviewbefore you call built work done. Claude judges whether a moment qualifies. It checks with you before running the council, because the digest goes to third-party providers, and it only offers/codex:review, which is yours to type. One note whatever you have installed, at most once every 30 minutes, and silent when you have neither. See docs/hooks.md - Voice drafting -
/write-as-medrafts messages, replies, PR text, or docs in your own writing voice. On first use it distills your typed messages from Claude Code transcripts into an editable profile at~/.claude-sessions/.voice/profile.md; drafting loads the profile and writes as you. Writing that lives outside the transcripts (an exported chat, sent mail) goes in~/.claude-sessions/.voice/sources/*.mdand every build appends it to the corpus.
- Agent state -
cs -liveand the TUI'sstaterow show what Claude Code says each session is doing right now —busy,waiting,idle— read from the per-session records Claude Code publishes under~/.claude/sessions/. A record outlives a crash, so cs believes one only while its pid is alive and still reports the process start time the record holds; otherwise a recycled pid would keep a dead session looking busy. Hosts that publish no records (Claude Code before 2.1.224, or withoutjqfor the shell reader) simply show no state - Cross-session search -
cs -search <query>greps across all sessions' narrative, memory, and README - Health checks -
cs -doctorreports status of Keychain backend, hook registration, shadow-ref freshness, auto-memory writability, status line registration, Claude Code settings audit (hooks/MCPs/permissions/env vars counts), cumulative token usage for the current project, whether the cs and cs-update mods ran, and an authority section listing every hook that injects into the model's context together with the switch that turns each one off - Usage attribution -
cs -usageshows which sessions are consuming the 5-hour and weekly rate-limit windows: per-session input/output token sums (deduplicated by API request, cache-read excluded), anchored at the true reset boundaries when the cs status line is active.cs -usage <name>breaks one session down per conversation with a lifetime column. Both views fold in every subagent and workflow-agent transcript beneath a conversation, however deep Claude Code nests them, while the model column stays the conversation's own. AREADS>350Lcolumn counts Read tool results over 350 lines asuntargeted/all ~tokens: a read is targeted when the model's own Read call carried an offset or a limit, so a bare read the harness capped at its line limit still counts as untargeted, and the token figure is the untargeted characters at four per token, the share a size gate could have intercepted. Subagent transcripts keep the file text in the tool result itself rather than in a file record; the column counts both shapes. Reads made through Bash (cat,head) carry no file shape in the transcript and are not counted. - Session tags -
cs -tag add apitags the current session in its README frontmatter (tags: [api]— the same field Obsidian indexes);cs -list --tag apifilters the listing, and the picker filters live with#apiin the search query (combining with fuzzy name search). Tags show in the preview card. Theencryptedtag marks a session that keeps its notes in an encrypted volume (.cs/memorylinked into the mount): the picker draws a lock beside its name and avaultline in the preview readinglockedorunlocked, from whether.cs/memoryresolves, and the status line draws the same lock after the session name. The lock is a Nerd Font glyph, drawn once this machine has confirmed its font (the status line'scs -statusline capsanswer); until then both showenc. - Encrypted sessions - A session can keep its notes, Claude Code's config and cs's own files on an encrypted volume by linking four names under
.cs/into its mountpoint:memory,plans,claude-config(Claude Code's config dir for the session, so transcripts and prompt history never reach~/.claude) andprivate(cs's own log, mail, queue, traces, rotation handoffs and checkpoints). While the volume is not mounted, cs refuses to open the session and writes nothing in plaintext in its place. With the volume mounted inside the session,cs -rmrefuses to remove the session, and neither/finishnorcs -uninstalldeletes through it. On macOS,cs -encrypt <name>sets this up for an existing session. Every open then asks for the password, and the volume unmounts when the session's Claude Code exits. Some files stay outside the vault; the docs list them. See docs/session-layout.md. - Session archive -
cs -archive <name>drops a tracked.cs/archivedmarker that hides a finished session from the picker,cs -list, andcs -search(the marker syncs with the session, so archiving on one machine archives everywhere).cs -list --archivedlists only archived sessions,cs -search <q> --include-archivedsearches them, and the picker toggles visibility withA(archived rows render dimmed) and archives or unarchives the selected session witha. Opening an archived session unarchives it.
- Walk-away supervision - a draining queue is watched by circuit breakers: too many tool failures in one task (default 5,
CS_QUEUE_MAX_FAILURES), context past 85% (CS_QUEUE_MAX_CTX), or the 5-hour rate-limit window past 85% (CS_QUEUE_MAX_5H) parks the queue with a debrief instead of feeding the next task — nothing is lost,cs -queue startre-arms. Everything that happened while you were away (tasks done, breaker trips) lands in a per-machine journal: a one-line digest surfaces once on your return, andcs -queue logshows the full history. - Cross-session mail -
cs -msg <session> "note"drops a message in another session's machine-local mailbox (--kind notify|task|text|result;taskalso lands in its walk-away queue). Delivery is atomic — each message is its own file, written whole and renamed into place, so concurrent senders can never interleave. Bodies may be up to 64KB, and a lone-body reads from stdin (cs -msg <session> -). The recipient sees the unread bodies inlined into its context on every prompt until it reads them withcs -msg(bounded to 5, truncated;taskkind shows a count-only label since it is already queued). Same-machine only; attribution is unauthenticated by design. - Threads - every message carries a thread id, and the sender keeps its own copy, so an exchange can be re-read from either end — including after a rotation, when an agent otherwise has no way to find out what it already said.
cs -msg --reply <thread> "body"answers without naming the peer (it comes from the thread; naming a different one is an error, not an override), andcs -msg thread <id>prints the conversation ordered by what answers what — not by time, since a question and its reply usually land in the same whole second. - Mail wakes - unread mail takes a turn instead of waiting for a keystroke, so agent-to-agent work advances unattended. A session that just finished a turn is woken at that boundary; a session already parked at the prompt is woken by Claude Code's file watcher noticing the delivery, which arrives as a system-reminder rather than as synthesised typing. Either way the wake names who the new mail is from, so the woken session knows its correspondent before it opens the mailbox. Fires once per arrival, never for
taskkind (the queue owns those), never while a walk-away drain is running, and only in the launched conversation — not in teammates sharing the mailbox. Bounded byCS_MAIL_WAKE_MAX(default 5) wakes between prompts so two sessions cannot volley forever;CS_NO_MAIL_WAKE=1silences it without swallowing the message. - tmux spawner -
cs -spawn <name>opens a session in a cs-owned tmux session (tmux attach -t cs);--brief <file>hands it a brief it reads at its first turn (landing as the session's.cs/brief.md),--task "..."seeds and arms its walk-away queue so it starts working unattended, and the spawner hears back over cross-session mail when the queue drains. Same-machine only. - Features from inside a session - the
featureskill (/feature fix-auth) writes a brief from the conversation and spawns<base>@fix-authas a parallel worktree session with it, so a session can hand off a feature and keep working. The spawn keeps its permission prompt;/finish fix-authlands the result.
-
Status line -
cs-statuslinerenders Claude Code's status bar as one line of rounded capsules on the terminal's own background: an identity capsule (the Claude mark, a darker coral (red in a 16-colour terminal) from the end of a turn until your next prompt; the session name; a queued-task count and an unread cross-session mail count when there are any, both read from.cs/local/; the git branch with ahead/behind and dirty counts; the model and its effort level in Claude Code's own/effortcolours), a context capsule whose pie icon fills with the band, and a quota capsule: the 5-hour window always, the weekly window beside it from 50%, and on a Fable session its model window in a capsule of its own from 50% (each gaining a reset countdown as it fills) — branch, model, context and limits all from the status-line JSON plus one bounded git call every five seconds, with no transcript parsing; a warm render forks nothing but the interpreter and onejq, so it survives a loaded machine. Colour is state: amber ink past a warn threshold, a red capsule at crit. The rounded capsule ends are the one glyph that needs a patched font, so the installer shows a sample once and asks whether they render; until a machine has answered, the capsules have square ends (cs -statusline caps on|off|askrevisits it). On a Fable session it folds Fable's own weekly window, which is model-scoped and so appears in none of the rate limits Claude Code puts on stdin, into the same rule; that one figure is fetched out of band into a machine-global cache, never from the render, and only while Fable is the active model — using Claude Code's own credential, which cs reads and never writes. It writes two machine-local files as it renders —.cs/local/context-pctand.cs/local/limits— which is what makes the liveness heartbeat andcs -usage's reset anchoring work. Session cost is available as an opt-in segment. Enable or remove it any time withcs -statusline enable|disable; choose and order segments withCS_STATUSLINE_SEGMENTS. cs auto-detects the terminal's light/dark theme (override withCS_TERM_THEME;cs -detect-themeshows the result). A companioncs-subagent-statuslinestyles the agent-panel rows so each running subagent shows the model driving it, its own context %, and elapsed time;cs -statusline enableregisters both (Claude Code reads the registration at startup, so restart it to see them). See docs/statusline.md -
iTerm2 awareness - inside iTerm2 the session color tints the tab (native escapes, reset on exit), and with iTerm2 shell integration installed a finished turn bounces the dock until your next prompt.
CS_NO_ITERM2=1disables the bounce;cs -doctorreports the integration surface.
- Secure secrets handling - Store sensitive data in the OS keychain (value read from stdin, never written to a file); exportable as age-encrypted files for backup
- Bash command audit trail - Every Bash command Claude runs is logged to
.cs/local/session.log(machine-local, never git-synced) with timestamps - Update notifications - Checks for updates and notifies when new versions are available. When an update is pending, cs shows the release notes for every version above the installed one: the
cs-updatemod's pane inside the session (see Release notes in the session above), a compact summary card in the launch banner only whenCS_NO_FUNCTION_HOOKS=1withholds that mod, and the full notes undercs -update --check. - Verified updates - Updates are downloaded from GitHub Releases and verified with SHA-256 checksums; additionally verified with minisign signatures when available
- Claude Code
- Bash 3.2+ (macOS system bash supported)
jqfor hook configurationgitfor local session history and crash recovery- Windows: WSL2 (see Installation → Windows); native Windows and Git Bash are not supported
bash -c "$(curl -fsSL https://raw.githubusercontent.com/hex/claude-sessions/main/install.sh)"Or clone and run ./install.sh.
⚠️ Always review install.sh before running scripts from the internet.
The installer:
- Adds
cs,cs-secrets,cs-statusline,cs-subagent-statusline, andcs-tuito~/.local/bin/ - Installs the cs hooks to
~/.claude/hooks/cs/for session tracking (including thescope-promptauto-grounding hook on UserPromptSubmit) - Adds
/summary,/checkpoint,/sweep, and/wrapcommands, thestore-secret,prose-hygiene,rotate,finish,feature, andwrite-as-meskills, and thecsandcs-updatemods to~/.claude/ - Installs shell completions for bash and zsh
- Configures hook entries in
~/.claude/settings.json
Install inside a WSL2 distro exactly as on Linux (the command above). cs targets macOS and Linux; native Windows and Git Bash are not supported.
The platform is detected automatically. It decides one thing — whether secrets go to the macOS keychain or to an encrypted file — and CS_PLATFORM_OVERRIDE=macos|wsl|linux forces that choice for testing. Any other value is refused rather than treated as "not macOS".
- Sessions — Isolated workspaces, each with their own git repo and documentation.
cs debug-apicreates one; running it again resumes it. - Narrative (
.cs/memory/narrative.<actor>.md) — A per-actor lab notebook for findings, observations, and ideas during a session. Each co-developer writes their own file (so shared sessions never conflict) and reads it in full on resume. A teammate's file you only read from the line the resume digest names, never the whole thing. The notebook is append-only — a disproven entry gets a dated correction, never an edit — andcs -narrative rotate(run by/wrap, by the session manager's Rotate narrative entry, flagged at conversation start, by the Stop hook and bycs -doctor;cs <name> -narrative rotatereaches a session you are not in) moves the oldest sections verbatim into.cs/narrative-archive/<actor>/once a file passesCS_NARRATIVE_MAX_BYTES(224 KiB, under the Read tool's 256 KiB ceiling), keeping aCS_NARRATIVE_KEEP_BYTES(112 KiB) tail. Stored as native Claude Code memory files; see docs/session-layout.md for how that works. - Checkpoints (
.cs/checkpoints/) — Labelled narrative snapshots you can save mid-session with/checkpoint, capturing the narrative, changes, and the current git HEAD. - Timeline (
.cs/timeline.jsonl) — A structured event log recording session starts, ends, and checkpoints as newline-delimited JSON. - Auto-memory (
.cs/memory/) — Claude Code's persistent operational notes, redirected into the session and cleaned up withcs -rm.
cs # Open the session manager (TUI)
cs . # Open the session you are standing in
cs -tui # Interactive session manager, from anywhere
cs -- <session-name> # '--' ends the options, for launchers that insert one
cs <session-name> # Create or resume a session
cs <session-name> --force # Override active session lock
cs <base>@<feature> # Create/resume a parallel feature worktree off <base>
cs <base> -features # List a base's feature worktrees and their merge readiness
cs <base> -finish <feature> # Open <base> and run /finish for <feature> (integrate, then retire the worktree)
cs -adopt <name> # Adopt current directory as a session
cs -whoami # Show the current actor (for shared, multi-person sessions)
cs -who # Show who contributed to shared memory/narrative (git history)
cs -search <query> # Search across all sessions
cs -checkpoint "<label>" # Snapshot git state + narrative (also: list, show <name>)
cs -narrative rotate # Archive the oldest narrative sections once the file passes its budget (/wrap runs this)
cs <name> -narrative rotate Scan report · 2026-10-05
- ✓ Prohibited terms or links
- ✓ Repository eligibility
- ✓ slopscore.md paperwork
- ✓ Content policy
- ✓ Risk review
From the balcony · 0 of 2 clapped
Schnitzel and Cap'm Slop read it and passed. Their reasons are on the balcony, with every other verdict.
Critics are accounts on this site with no GitHub account behind them. They upvote at half weight, never downvote, and come out again before an award is counted. Who they are.
report this listing
— log in to report
0 comments
log in to comment.