Skip to main content

cc-session-control

tmux-first workbench (TUI + headless CLI) for the agent CLIs on one machine — Claude Code, Codex CLI, and Kimi Code: sessions across all three, plus Claude Code background agents and Remote Control.

CLI command: csctl

Features

  • Sessions Tab — One machine-wide list of Claude Code, Codex, and Kimi Code sessions (CLI column: cc/cx/km), discovered from each CLI's own on-disk state — not just sessions csctl started. Resume tmux-first (Enter resumes into a project-labelled window in the shared csctl tmux session via each CLI's native resume command; t bare-terminal fallback; R backgrounds into tmux; f forks where the CLI supports it; ⧉ marks tmux-resident sessions), terminate, and delete; a cleanup submenu (c) prunes empty/short Claude sessions and sweeps orphan artifact directories, zombie session files, and aged global entries (cleanup models Claude state only)
  • Projects Tab — The startup tab / launcher: Enter opens a CLI chooser (active providers only, claude focused first — so Enter-Enter starts claude) to open a new project-labelled window in the shared csctl tmux session; x/k jump straight to codex/kimi; start/stop Claude RC servers per project (o/s), toggle per-project auto Remote Control (c), show running/stopped/dead states
  • Background agents Tab — List Claude Code background agent jobs; take over, respawn, watch their timeline, stop, or remove them

Non-Claude liveness is deliberately conservative (ADR-0005). A real resume target in argv (codex resume <sid-or-unique-name> / kimi --session <sid>) has priority; csctl's own identity-checked tmux dispatch metadata is a supplement for dispatched windows, and is essential after Kimi rewrites its argv at runtime. A brand-new session started from the launcher (the Enter chooser or x/k) has no sid yet, so it stays unbound, as does any other bare-launched TUI; unbound processes are never stop/takeover targets.

Kimi can close that gap opt-in via its official hooks: add this to ~/.kimi-code/config.toml and every kimi session — bare-launched ones included — self-reports its pid↔session binding (verified on Kimi Code 0.34.0; csctl re-verifies pid identity and process start time per entry, so stale or forged entries never bind):

[[hooks]]
event = "SessionStart"
command = "csctl _kimi-hook"
timeout = 5

[[hooks]]
event = "SessionEnd"
command = "csctl _kimi-hook"
timeout = 5

The hook fires when a session materializes (a TUI's first prompt), and the binding appears on csctl's next refresh.

All agent sessions csctl dispatches — new, resumed, forked, backgrounded, or background-agent respawns — share the tmux session named csctl; their window names retain the project. Existing live sessions in older or user-created tmux sessions are entered in place and are never migrated automatically. Managed Remote Control servers remain isolated in the configurable rc session.

Built with urwid.

UI language: Simplified Chinese (notifications and status text). CLI output is in English.

Requirements

  • Python 3.12+
  • At least one supported agent CLI installed and authenticated: Claude Code, Codex CLI, and/or Kimi Code — each is discovered automatically when its state home exists (~/.claude, ~/.codex, ~/.kimi-code; official relocation variables CODEX_HOME / KIMI_CODE_HOME are honored). Several codex identities on one machine are supported by declaring their homes — see Configuration below
  • tmux (the primary session-lifecycle carrier: launch, resume, background, and survive terminal/SSH disconnects; managed Remote Control servers also use it)
  • Linux / WSL. Other POSIX systems are not supported; without /proc, csctl shows degraded state and refuses destructive actions whose safety it cannot prove.

Installation

Install the latest published release:

uv tool install cc-session-control
# or
pipx install cc-session-control

Upgrade later with uv tool upgrade cc-session-control (or pipx upgrade cc-session-control).

Latest master build

To try the newest master before it is released, install from GitHub:

uv tool install --reinstall git+https://github.com/dzshzx/cc-session-control.git

csctl manages local state on the machine where it is installed: the active providers' ~/.claude, ~/.codex, and ~/.kimi-code homes, local tmux, and the project launcher entries recorded in ~/.claude.json. Install it separately on each machine whose sessions you want to manage. For working on the code instead of using it, see CONTRIBUTING.md.

Usage

The TUI is the primary surface — Remote Control management and session cleanup live there (Projects tab and the Sessions cleanup submenu). The headless CLI keeps only the agent-facing commands: resume and agents.

# Open TUI
csctl

# Resume rescue (headless): list sessions of ALL providers across
# directories with ready-to-copy resume commands (native /resume only
# searches the cwd and hides sdk-ts/bridge sessions); non-Claude rows
# are tagged [codex]/[kimi]
csctl resume                 # Page 1, 20 per page
csctl resume mybug           # Keyword: sid/cwd/title, then transcript body
csctl resume --page 2        # Next page
csctl resume --all           # Everything, no paging

# Read-only inventory
csctl agents                 # Background agents: state, tempo, name, cwd

# Options
csctl --theme light            # Force the TUI palette (auto/dark/light)
csctl --version

The companion Claude Code skill (claude-session-doctor) is distributed via the skills CLI — install it with skills add dzshzx/agent-skills --skill=claude-session-doctor (it is no longer bundled with this package).

Configuration

Environment Variable Default Description
CSCTL_PROVIDERS claude,codex,kimi Comma list of allowed agent-CLI providers; a listed provider is active only when its state home also exists
CSCTL_RC_SESSION rc Literal tmux session name for RC servers (target syntax = : * ? [ ] $ @ % is rejected); must differ from the reserved workbench session csctl
CSCTL_CLEANUP_AGE_DAYS 14 Minimum age in days for the age sweep in the Sessions cleanup submenu (must be an integer ≥ 0)
CSCTL_THEME auto TUI palette: auto (detect the terminal background via $COLORFGBG, else dark) / dark / light. Most terminals (including tmux) don't set $COLORFGBG, so auto falls back to dark — set this (or --theme) explicitly for a light terminal

Multiple codex identities

CODEX_HOME says which home one codex process uses, and it is inherited by everything that process spawns — including csctl. Reading it as the machine's inventory made csctl show only the identity it happened to be launched from. So when you run more than one codex identity, declare their homes in ~/.config/csctl/providers.json (XDG-respecting) instead:

{
  "codex_homes": [
    {"label": "cx",  "home": "~/.codex"},
    {"label": "cx2", "home": "~/.codex-eva02"}
  ]
}

That list is then the complete codex inventory and CODEX_HOME no longer takes part, so csctl shows the same machine state from any terminal. Each entry becomes its own provider — separate sessions, trust records, badges, and launcher entry — tagged in the CLI column by its label (ASCII alphanumeric, ≤3 characters). The first entry keeps the provider key codex; later ones become codex:<label>. Every command csctl synthesizes for a declared identity carries its CODEX_HOME explicitly. Without this file there is exactly one codex instance following CODEX_HOME/~/.codex, and a malformed file falls back to that same single instance with a visible reason. Changes take effect on the next csctl start. See ADR-0008.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cc_session_control-0.8.7.tar.gz (291.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cc_session_control-0.8.7-py3-none-any.whl (182.5 kB view details)

Uploaded Python 3

File details

Details for the file cc_session_control-0.8.7.tar.gz.

File metadata

  • Download URL: cc_session_control-0.8.7.tar.gz
  • Upload date:
  • Size: 291.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for cc_session_control-0.8.7.tar.gz
Algorithm Hash digest
SHA256 b3ea2c158999b11548aefd9a335afbc4e6adb52f9cd20c64763b7e66ddb165ea
MD5 33c8b505192130c01759f449b2b30f3d
BLAKE2b-256 ad28ab45d438fc7bf2c9dabe9b142976ef22a82c12417d1c2bd11d1f82a73272

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_session_control-0.8.7.tar.gz:

Publisher: release.yml on dzshzx/cc-session-control

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cc_session_control-0.8.7-py3-none-any.whl.

File metadata

File hashes

Hashes for cc_session_control-0.8.7-py3-none-any.whl
Algorithm Hash digest
SHA256 ef5ae873de2824f9ffaedbcec1510e0ba6eb0be24a081c091cee467923c18337
MD5 b5b7ba0b4c0e0a50191789b35a7bd035
BLAKE2b-256 dd5f46d20b78dc258da2558cd8a5aedcbe69d97e3355b0c0b7793759db8d074d

See more details on using hashes here.

Provenance

The following attestation bundles were made for cc_session_control-0.8.7-py3-none-any.whl:

Publisher: release.yml on dzshzx/cc-session-control

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page