Sandbox
@jeapostrophe/jc

macOS session manager for Claude Code

jc is a macOS window for orchestrating multiple Claude Code sessions across projects. It keeps each session’s notes, terminal, and layout together so you can send the next message, move to another session, and come back without reconstructing context.

45 stars1 forksRustUpdated 19d ago
Who it's for

Builders who use Claude Code across several projects and want a single session switcher.

What it delivers

You can keep Claude Code working in one project while you draft and switch to another without losing session context.

What it does

Multi-session picker

Shows every running session across projects in one picker, with markers for active, dormant, disabled, and new sessions.

Draft and send from TODO.md

Uses a project TODO.md with a `### WAIT` marker so you can draft the next instruction, then send it with Cmd-Enter.

Per-session pane layouts

Restores each session’s pane layout, cursor position, and terminal scrollback when you switch back.

Embedded Claude terminal

Runs Claude Code in an embedded terminal inside the app window.

Project and file navigation

Lets you open project files, jump to symbols and headings, and search lines from inside the app.

Session lifecycle management

Starts new sessions, resumes existing ones, and tracks session state in TODO.md and local config files.

How to get it

  1. 1Run
    # Build and run as macOS .app bundle
    ./make.sh
    
    # Or run directly via cargo
    cargo run -p jc-app
    
    # Register a project directory
    cargo run -p jc-app -- .

README

jc icon

jc

Orchestrate multiple Claude Code sessions across projects.
Draft, send, and switch — all from one window.

CI MIT License macOS Rust + GPUI

Why · Getting Started · Keybindings · Design · Architecture

jc screenshot — 3-pane layout with Claude terminal, TODO editor, and code viewer

Why

Claude takes minutes per task. If you wait, you get four cycles an hour. If you switch to another session while Claude works, you get twelve — but only if you can come back without losing your place.

jc keeps your place outside your head. Each session's notes live in the project's TODO.md, under a ### WAIT marker: you type the next instruction there whenever you think of it, and Cmd-Enter sends it and files it into the message log. Coming back to a session means reading what you already wrote, not reconstructing it.

Switching is cheap. Cmd-P lists every session in every project; each session keeps its own pane layout, cursor position, and terminal scrollback, restored on switch-back. A red * marks the sessions whose Claude terminal has printed something since you last had it on screen, so the picker tells you where the work moved while you were elsewhere. Desktop notifications stay out of the way — only a blocked session (permission prompt, API error) interrupts you, and only when jc isn't the front app.

See DESIGN.md for the full rationale.

Getting Started

# Build and run as macOS .app bundle
./make.sh

# Or run directly via cargo
cargo run -p jc-app

# Register a project directory
cargo run -p jc-app -- .

Config and state live in ~/.config/jc/ (config.toml, state.toml, theme.toml).

Core Concepts

Projects and Sessions

A project is a code repository registered with jc. Each project has one or more sessions — ongoing Claude Code conversations. Sessions are defined in the project's TODO.md:

# Claude
## Refactor auth module
> uuid=abc123-def456-...
### Message 0
first instruction sent to claude
### Message 1
second instruction
### WAIT
Notes for next message go here.

The ### WAIT marker separates what you've sent from what you're drafting. Everything below WAIT is draft text — jc never treats it as log, even if it contains a quoted ### Message N heading. When you send (Cmd-Enter), the draft becomes a numbered message and WAIT moves below it — so you have the recent history of what you asked.

The log is bounded: each send keeps the 25 most recent messages of that session and drops the rest, so a long-running session settles into a sliding window (### Message 76 through ### Message 100). jc applies the same bound to every session when it starts, so sessions you have not touched in a while get collected too; the first time it shortens a file it leaves a TODO.md.bak beside it.

One exception: truncation stops at a message still waiting on a @jc(...) scheduled send, so it can never cancel one. That session's log stays as long as it needs to until the send fires. Numbers are never reused, so a message keeps the number it was sent under. jc never sends TODO.md to Claude — messages are delivered to the session terminal and Claude resumes from its own transcript — so dropping old entries costs it no context.

jc mints the session UUID itself. A new session launches claude --session-id <uuid> under a freshly generated v4 UUID that is written to TODO.md at the same moment; existing sessions are resumed on startup with claude --resume <uuid>. If Claude has since garbage-collected a session's transcript, jc relaunches it with --session-id under the same UUID instead — you lose the conversation, but the heading, its message log, and its WAIT notes stay exactly where they were. /clear is handled transparently — the UUID in TODO.md is rewritten in place, with no terminal relaunch.

Per-session metadata lives on > lines under the heading. > uuid= and > last= are managed by jc; add > dangerous by hand to spawn that session's claude with --dangerously-skip-permissions (takes effect on next spawn). See ARCH.md for the full list.

The > uuid= line, not the heading text, is what identifies a session — everything jc writes into TODO.md is addressed by it. Rename a heading to whatever you like, and give two headings the same name if that is what you want; sends and scheduled deliveries still land on the right one.

Session Activity

The Cmd-P session picker marks each session with a single character:

MarkerMeaning
red *This session's Claude terminal has printed output since you last had it on screen
green >The session you're on now
yellow ~In TODO.md but not running — pick it to adopt
grey ~Disabled ([D])
blue +A registered project with no sessions yet

Sessions sort activity-first, then by recency; the session you're on sorts last, since you're already there. The marker clears when you switch away from a session, so it always means "since you last had it on screen", and the session you're currently on never shows one.

Views

The window has 1, 2, or 3 panes (Cmd-1/2/3). Any of the five views can go in any pane via Cmd-O.

ViewDescription
Claude TerminalClaude Code CLI in an embedded terminal.
General TerminalSeparate shell per session for running tests, inspecting output.
Code ViewerSyntax-highlighted source with tree-sitter outline navigation.
TODO EditorMarkdown editor for session notes. Drafting area below WAIT, message history above.
Global TODOView of ~/.claude/TODO.md.

Per-session pane layouts are saved and restored on session switch.

Keybindings

Press Cmd-? for the in-app overlay.

Global

KeyAction
Cmd-1 / 2 / 3Set pane layout
Cmd-[ / ]Focus previous / next pane
Cmd-OOpen picker (pane views + project files)
Cmd-Shift-ODrill-down picker (symbols / TODO headings)
Cmd-PSession picker (all projects)
Cmd-Shift-PProject actions
Cmd-FSearch lines in current editor
Cmd-SSave file
Cmd-EnterSend draft below WAIT to the Claude terminal
Cmd-.Jump to WAIT
Cmd-`Next session (round-robin across all projects)
Cmd-Alt-↑/↓Scroll other pane by lines
Cmd-Alt-PageUp/PageDownScroll other pane by pages
Cmd-?Keybinding help
Cmd-W / Cmd-M / Cmd-QClose window / minimize / quit

View-Specific

KeyActionView
Cmd-RReload from diskCode
Cmd-C / Cmd-VCopy / PasteTerminal
Cmd-= / - / 0Font size +/-/resetTerminal

Picker

KeyAction
EnterConfirm
Escape / Ctrl-CCancel
↓ / Ctrl-NNext
↑ / Ctrl-PPrevious
PageDown / PageUpMove 10 items
Cmd-Shift-BackspaceToggle session disabled (session picker)

Workflow

Draft → Send → Switch

  1. Cmd-. jumps to the WAIT marker in the TODO editor, creating it if the session doesn't have one.
  2. Type the next instruction there. It's a plain Markdown buffer — write it over several sittings if you like, while Claude works on the last one.
  3. Cmd-Enter sends the draft to the Claude terminal, files it as ### Message N, and stamps > last=.
  4. Cmd-P to move to another session while that one runs. Your panes, cursor, and terminal scrollback come back when you return.
  5. Sessions that printed something while you were away carry a red * in the picker.

Navigate Code

  1. Cmd-O → fuzzy search over the project's git-tracked and untracked files (M = modified, R = recently opened), or jump straight to one of the five pane views.
  2. Cmd-Shift-O → tree-sitter symbol outline for the focused Code pane, or the heading outline for a TODO pane.
  3. Cmd-F → fuzzy line search within the focused editor.
  4. Edits made outside jc are picked up automatically; if you have unsaved edits, jc three-way merges them and only asks when the merge conflicts.

Manage Sessions

  1. jc . from a repo to register a project. A second jc . routes to the running instance over the IPC socket.
  2. Cmd-Shift-P lists what you can start in the current project: dormant TODO.md sessions (*), a brand-new session (+), and Claude transcripts on disk that TODO.md doesn't know about (~).
  3. Cmd-P switches between running sessions across every project, and adopts dormant ones.
  4. Cmd-Shift-Backspace in the session picker toggles [D] on a session's heading, so it stays in TODO.md but no longer starts with jc.

Contributing

PRs welcome. Preferably have your Claude open one against mine — I don't accept human-authored code.

Further Reading

  • Don't Wait for Claude — Article explaining the workflow philosophy behind jc

  • PLAN.md — Task checklist

  • DESIGN.md — Design principles, why not an editor plugin, remote workflow philosophy

  • ARCH.md — Implementation details: session lifecycle, terminal pipeline, hooks, TODO.md format

Star History

Star History ChartStar History Chart

Files in the repo

Repository payload21 top-level entries
  • .github
  • data
  • jc-app
  • jc-core
  • jc-terminal
  • scripts
  • vendor
  • .gitignore
  • ARCH.md
  • Cargo.lock
  • Cargo.toml
  • CLAUDE.md
  • DESIGN.md
  • icon.png
  • LICENSE
  • make.sh
  • PLAN-nvim.md
  • PLAN.md
  • README.md
  • rustfmt.toml
  • screenshot.png

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More tools

JuliusBrussee/
caveman

🪨 why use many token when few token do trick — Claude Code skill that cuts 65% of tokens by talking like caveman

105k
1 add
MemPalace/
mempalace

The best-benchmarked open-source AI memory system. And it's free.

59k
stablyai/
orca

Orca is the ADE for working with a fleet of parallel agents. Run any coding agent with your own subscription. Available on desktop, mobile and remote runtime.

66k

A cross-platform desktop All-in-One assistant for Claude Code, Codex, OpenCode, OpenClaw, Grok Build & Hermes Agent. Only official website: ccswitch.io

132k

Never stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors

64k
headroomlabs-ai/
headroom

Compress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.

71k