You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refresh modelled on top-tier Go CLI READMEs (starship, atuin, lazygit,
zellij). Net change is structure + framing, not content deletion — every
previous section is preserved.
- Hero block (centred HTML): big `ctm` title, italic tagline
"survive SSH drops, reattach from your phone", four shields
(release / Go Report / Go-version / license), and a horizontal
nav row of in-page anchors.
- Quickstart section directly under the hero — the two commands a
newcomer needs (`go install` + `ctm last`), then a one-sentence
"ctm bootstraps on first run" note. Previously install was below
features; atuin pattern flips this.
- "Why ctm?" 3-sentence framing paragraph between Quickstart and
Features — zellij-style "What is this?" move. Lands the mobile /
tunnel / one-word-reconnect pitch before any feature bullet.
- Inline statusline sample block in the hero area so the reader sees
the most visually distinctive artefact without scrolling.
- Features list reordered so mobile-first sits at #1 (previously
buried at #2 behind "Persistent sessions"). Crash-safe state bullet
expanded to mention strict-decode + schema_version now that those
ship. List trimmed from 12 to 10 by collapsing related items.
- `Lifecycle hooks` and `Shell completion` install subsections wrapped
in `<details>` so the install area reads lean for newcomers while
keeping the reference material one click away.
- `Mobile scroll` section promoted visually with a `> **Tip:**`-style
callout block and a config-style table for the Termius Snippet,
instead of plain prose + bullet list.
No removed content. No link rot. All existing anchors (`#commands`,
`#mobile-scroll`, `#configuration`, `#statusline`) still resolve.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+70-22Lines changed: 70 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,21 +1,56 @@
1
-
# ctm — Claude Tmux Manager
1
+
<h1align="center">ctm</h1>
2
2
3
-
Mobile-first session manager for [Claude Code](https://claude.com/claude-code) running in tmux. Survive SSH drops, reconnect from anywhere, one-tap resume, ctm-only claude customizations without touching your global config.
3
+
<palign="center"><i>Claude Tmux Manager — survive SSH drops, reattach from your phone.</i></p>
ctm # launches tmux + claude; drop SSH, reattach anytime
25
+
ctm last # one-word reconnect from your phone
26
+
```
27
+
28
+
That's it. `ctm` bootstraps `~/.config/ctm/` on first run and injects shell aliases into `~/.bashrc` / `~/.zshrc` if they exist.
29
+
30
+
## Why ctm?
31
+
32
+
Claude Code on a remote dev box is great until your train enters a tunnel. Plain SSH + a direct `claude` invocation dies with the connection; reconnecting starts from scratch. **ctm wraps claude in tmux with mobile-first defaults** — Alt-based keybindings, OSC52 clipboard, one-keystroke session pickers, stale-session markers — so the conversation keeps running while you're underground, and reattaches from your phone with a single word.
33
+
34
+
```
35
+
Opus 4.7 (1M) ~/projects/ctm
36
+
c 49% (486.8k) w 34% h 25%
37
+
↑ 118.6k ↓ 434.8k xhigh
38
+
```
39
+
40
+
(Above: the 3-line statusline ctm ships. Context fill + rate limits + cumulative tokens + current `/effort`, all from one hook.)
4
41
5
42
## Features
6
43
44
+
-**Mobile-first workflow.**`ctm last`, `ctm pick <filter>`, `Alt-a` second prefix, OSC52 clipboard sync, stale-session markers — the entire UX assumes you're on a phone with flaky Wi-Fi and a fat thumb.
7
45
-**Persistent sessions.** tmux-backed. Claude keeps running when SSH drops; reattach from any device.
-**Tight lifecycle coupling.** When claude exits, the tmux session dies. No more stuck bash shells.
10
-
-**Crash-safe state.** Atomic writes, flock-based locking, corruption recovery on `sessions.json`.
11
-
-**Resume with fallback.**`claude --resume UUID || claude --session-id UUID` — recovers from missing session data.
12
-
-**Claude overlay.** Drop a `claude-overlay.json` to apply ctm-only settings (statusline, theme, etc.) without touching your global `~/.claude/settings.json`.
13
-
-**ctm-only shell env.**`~/.config/ctm/env.sh` is sourced before claude spawns — set env vars (API keys, experimental flags) that claude reads during startup, too early for settings.json's `env` key.
14
-
-**Tool-use logging.** Built-in PostToolUse hook (pure Go, no jq/bash deps) writes one JSONL entry per tool call to `~/.config/ctm/logs/<session>.jsonl`. View with `ctm logs`.
46
+
-**Resume with fallback.**`claude --resume UUID || claude --session-id UUID` — recovers cleanly when session history is missing.
47
+
-**Tool-use logging.** Built-in PostToolUse hook writes one JSONL line per tool call; `ctm logs --since 7d --tool Bash --grep pattern` queries transparently across rotated history.
48
+
-**Claude overlay.**`claude-overlay.json` applies ctm-only settings (statusline, theme, hooks) without touching your global `~/.claude/settings.json`.
15
49
-**YOLO mode.** Auto-commits a git checkpoint before bypassing permissions, so you can always roll back.
16
-
-**Preflight health checks.** Env vars, PATH, workdir, tmux session, claude process — cached for 60s to keep mobile reconnects snappy.
17
-
-**OSC52 clipboard sync.** Copy in tmux, paste anywhere.
18
-
-**Zero non-tmux runtime dependencies.** Pure Go throughout — native UUID, `/proc` walk, `filepath.WalkDir`. No `jq`, `pgrep`, `grep`, or `uuidgen` required.
50
+
-**Preflight health checks.** Env vars, PATH, workdir, tmux session, claude process — cached for 60 s to keep mobile reconnects snappy.
51
+
-**Tight lifecycle coupling.** When claude exits, the tmux session dies. No stuck bash shells, no zombie tabs.
52
+
-**Crash-safe state.** Atomic writes, flock-based locking, strict JSON decode with self-healing strip-to-.bak, `schema_version` + startup migrations on `sessions.json` / `config.json`.
53
+
-**Zero non-tmux runtime deps.** Pure Go throughout. No `jq`, `pgrep`, `grep`, or `uuidgen` required.
19
54
20
55
## Installation
21
56
@@ -39,7 +74,10 @@ No extra setup step is required — the first time you run any claude-launching
39
74
40
75
If you prefer an explicit setup step (or want the cc-session migration to run), `ctm install` still does the same work upfront.
41
76
42
-
### Lifecycle hooks
77
+
<details>
78
+
<summary><b>Lifecycle hooks</b> — fire shell commands on <code>on_attach</code> / <code>on_new</code> / <code>on_yolo</code> / <code>on_safe</code> / <code>on_kill</code></summary>
79
+
80
+
43
81
44
82
ctm can fire a user-supplied shell command on five lifecycle events. Declare them under `hooks` in `~/.config/ctm/config.json`:
45
83
@@ -68,7 +106,12 @@ Each command runs through `sh -c` with the following env vars:
68
106
69
107
Hooks run **synchronously** with a per-hook wall-clock ceiling (default 5 s, override via `hook_timeout_seconds`). Failures log a WARN-level slog line and are otherwise ignored — they never block the action that triggered them. For fire-and-forget semantics, append `&` inside the shell command.
70
108
71
-
### Shell completion
109
+
</details>
110
+
111
+
<details>
112
+
<summary><b>Shell completion</b> — bash / zsh / fish / powershell</summary>
113
+
114
+
72
115
73
116
`ctm completion [bash|zsh|fish|powershell]` emits a completion script on stdout. Install per shell:
Completion is aware of subcommands, flags, and (for `ctm attach`, `ctm kill`, `ctm rename`, etc.) live session names pulled from `~/.config/ctm/sessions.json`.
93
136
137
+
</details>
138
+
94
139
## Requirements
95
140
96
141
- Go 1.22+ (for `go install`)
@@ -213,16 +258,19 @@ Inside any ctm tmux session:
213
258
214
259
## Mobile scroll
215
260
216
-
Claude Code's TUI uses alt-screen and has no built-in scroll history. The app-intended workflow for scrollback on mobile is:
261
+
> **The mobile scrollback trick.** Claude Code's TUI uses alt-screen and has no built-in scroll history. To scroll back on a phone:
0 commit comments