なぜ ccs が要るのか¶
ccs の中核は tmux new-session -d の 1 行に近い。実装は
設計調査 のとおり「足りない 4 つを埋めるだけ」で、
そう書くと必ず「手順書(skill)で足りたのでは」という疑問が出る。
この文書はその疑問に答える。素の Claude Code セッションで何が起きないかを 実測で示し、それを踏まえて tmux と CLI という選択の理由を書く。
計測日: 2026-08-18 / claude 2.1.233 / macOS。
1. 「新しいセッションを立てて」は素直には通らない¶
Claude Code のセッションに、新しい Claude Code セッションを立てさせたい。 素直に頼むと、次の 3 つのどれかに落ちる。
1.1 ツールから直接 claude を起動する → pty が無くて即死する¶
セッションのツールから起動したプロセスに pty が無い。この状態で対話モードの
claude を起動すると、黙って --print モードに落ちてそのまま終了する。
$ tty
not a tty
$ claude -n ttytest --session-id <uuid>
Error: Input must be provided either through stdin or as a prompt argument when using --print
プロセスは残らない。対話セッションはそもそも存在できない。
1.2 これは「禁止」ではない¶
入れ子で claude を呼ぶこと自体は通る。同じ環境で -p を付ければ動く。
つまり再帰的な起動を止めているポリシーは無い。 足りないのは pty を配る手段だけ。 ここを取り違えると、 「外から SSH で入る」ような別の問題を解きに行くことになる。
1.3 組み込みのツールには新規作成の口が無い¶
| 手段 | なぜ届かないか |
|---|---|
SendMessage |
生きている既存セッション宛にしか送れない。 新しくは作れない |
ListAgents |
一覧するだけ |
Agent ツール |
サブエージェントであって独立したセッションではない。ListAgents にも Remote Control にも現れず、終わればそこで消える |
ツールから直接 claude |
§1.1 のとおり pty が無く即死する |
claude agents --json も読み取り専用。新規作成だけが空白という状態が、
設計調査 §1 の表の「セッションの新規作成: 要る」に対応する。
2. 手で tmux を叩けば立つ。だが毎回同じ形では立たない¶
pty は tmux が配れる。実際、ccs を使わずに手順どおり叩けばセッションは立つ。
mkdir -p "$D"
U=$(uuidgen | tr 'A-Z' 'a-z')
tmux new-session -d -s manual-x -c "$D" sh -c "claude -n manual-x --session-id $U; exec /bin/zsh"
この手順を実際に踏んだところ、3 つで止まった。
2.1 workspace trust ダイアログで固まる¶
新しいディレクトリでは、起動直後に信頼確認が出る。
Quick safety check: Is this a project you created or one you trust?
❯ 1. Yes, I trust this folder
2. No, exit
デタッチ起動なのでペインを覗くまで気づけない。しかもこの間、セッションは
~/.claude/sessions/<pid>.json にすら現れない。外から見ると
「立ったのか、死んだのか、待っているのか」が区別できない。
tmux send-keys で手動承認して初めて起動が完了した。
2.2 cc/ を付け忘れると管理から外れる¶
ccs ls は cc/ 接頭辞の tmux セッションだけを扱う(設計調査 §4.2)。
手で立てた manual-x はこの名前空間の外にあり、一覧に出てこなかった。
出てこないということは、ccs kill も ccs gc も届かないということでもある。
放置されたまま残り、次に気づくのは tmux ls を直接叩いたときになる。
ここが厄介なのは、規約を知っていても外れることだ。
上の手順は規約を知ったうえで打ったのに、cc/ を落とした。
2.3 冪等でない¶
UUID・作業ディレクトリ・セッション名を毎回自分で決めることになる。
同じ名前で 2 回叩けば tmux が duplicate session で落ちる。
tmux new-session が返った時点ではまだ起動途中なので、
登録されるまで待つループも自分で書くことになる。
3. ccs が変えるのは「立つ」ではなく「毎回同じ形で立つ」¶
同じことを ccs で行うと 1 コマンドで、結果が 1 行の JSON で返る。
$ ccs new --tmp
ccs: ccs が発行した作業枠なので信頼済みにしました: /Users/apple/.cc-scratch/2e60932e
{"slug":"tmp-8","sessionId":"2e60932e-…","path":"/Users/apple/.cc-scratch/8",
"tmux":"cc/tmp-8","transcript":"…/2e60932e-….jsonl","created":true,"running":true}
| 手で tmux を叩く | ccs new |
|
|---|---|---|
| コマンド数 | 4(mkdir / uuidgen / tmux / send-keys) |
1 |
| trust ダイアログ | 手で承認が要る。気づかないと固まる | 事前に解決して起動する |
| 置き場所・名前 | 自分で決める。衝突は自己責任 | 空き枠を選び、slug は冪等 |
ccs ls での可視性 |
出ない(管理・後片付けの外) | 出る |
| 起動完了の判定 | 自分で待つ | 登録を待ってから返る(running) |
| 出力 | 無し | JSON |
ccs の価値は「できないことをできるようにする」ことではない。
手で 4 コマンド叩けば立つ。価値は、毎回同じ形で立ち、立った後も管理下に残ることにある。
4. なぜ tmux なのか — pty のためだけではない¶
pty を配るだけなら他にも手はある(script、expect、疑似端末を張る自作プロセス)。
tmux を選ぶ理由は、セッションの寿命をどの GUI からも切り離せることにある。
- 人間が乗り込める。
ccs attach <slug>で、AI が立てたセッションに人間がそのまま入る。 逆に、人間が始めた作業をSendMessageで AI に引き継ぐこともできる。 会話の主体を途中で交代できるのは、実体が端末セッションだからこそできる - 長時間走る。 ターミナルを閉じてもプロセスは残る。
数時間から数日かけて
/loopを回す運用が前提にできる - デスクトップアプリから独立している。 アプリの再起動・更新・ウィンドウを閉じる操作に 巻き込まれない。切断の原因がひとつ減る
3 番目は Remote Control と組み合わせたときに効く。Remote Control は プロセスが生き続けていることを前提にしているので、 セッションの宿主が「閉じられうる GUI」であるかどうかが、そのまま切断の頻度になる。
未検証
「ターミナル常駐のほうが実際に切断が少ない」は、設計上そうなるという説明であって、 デスクトップアプリとの切断頻度を並べて測ったものではない。
その独立には代償がある — アプリからターミナルが見えない¶
同じ独立性が、Claude アプリからのターミナルアクセスを奪う。
ccs で立てたセッションを Claude アプリ(デスクトップ / モバイル)から開いても、
そのセッションが動いている端末の画面は出てこない。
アプリが自分で立てたセッションでは出るのに、ccs のものでは出ない。
レジストリ(~/.claude/sessions/<pid>.json)を全件見ると、entrypoint で綺麗に二分される。
entrypoint |
tmux フィールド |
立てたのは |
|---|---|---|
claude-desktop |
無し | デスクトップアプリ |
claude-vscode |
無し | VS Code 拡張 |
cli |
有り | ccs(および手で叩いた tmux) |
pty を持っている主体が違う。 アプリが立てたセッションは、アプリ自身が pty を作って
claude を起動しているので、その端末に画面を出せる。ccs のセッションで pty を
持っているのは tmux サーバーで、アプリはそこへの handle を持っていない。
未検証
アプリがどの条件で端末の画面を出すかの実装は確認していない。 上はレジストリの形から立てた仮説にすぎない。
これは ccs 固有の欠陥ではない。 手で tmux new-session して立てたセッションも
同じ形(entrypoint: cli + tmux 有り)になり、同じ制約を受ける。
ただし ccs を使うと全セッションがこの状態になるので、実質的には ccs の制約として現れる。
いまの回避策と、その限界¶
| したいこと | 手段 | 限界 |
|---|---|---|
| 端末の画面を見る | ccs attach <slug> |
同じマシンのターミナルからしかできない |
| セッションに指示を出す | SendMessage(ハブ経由) |
会話は通る。シェルの生の出力は返らない |
| 何が起きたか後から読む | ~/.claude/projects/<cwd-slug>/<uuid>.jsonl |
会話の記録であって端末の画面ではない |
外出先でアプリしか持っていない状況では、端末に届く経路が無い。
ccs は「ハブから複数セッションを立てて回す」道具なので、
立てたものをモバイルから触るのは主要な使い方に含まれる。ここは埋める必要がある。
追跡は #19。
5. なぜ skill ではなく CLI なのか¶
§2 の手順は、そのまま手順書として書ける。それでも CLI にしてある理由は 3 つある。
| 手順書(skill) | ccs(CLI) |
|
|---|---|---|
| trust の回避 | 手順としては書けるが、~/.claude.json を書く状態変更。冪等性と壊れた JSON の扱いは書き手任せ |
コードとして冪等。妥当性を確かめてから mv で置き換える |
| 命名規約 | 守られる保証がない。 外れると管理から漏れる(§2.2) | 強制される |
| 出力 | 自然言語。読めるのは AI だけ | JSON。人間・スクリプト・GUI から叩ける |
| テスト | 無い | bats + fake claude スタブ。本物の claude を起動せずに検証する |
とくに 3 行目が、この先を決めている。
手順書は「AI に読ませるもの」で、CLI は「誰でも叩けるもの」。 セッションを AI だけが立てるなら手順書で足りた。 人間も、スクリプトも、GUI も同じ入口から立てるなら、コマンドである必要がある。
まとめ¶
- 素の Claude Code セッションは、新しいセッションを立てられない。禁止ではなく、 pty が無く、組み込みに新規作成の口が無い(§1)
- tmux を手で叩けば立つ。ただし trust で固まり、命名を外すと管理から漏れ、冪等でない(§2)
ccsが売るのは可能性ではなく再現性。同じ形で立ち、立った後も管理下に残る(§3)- tmux は pty のためだけではなく、attach・長時間稼働・GUI からの独立のために選んでいる(§4)
- 手順書ではなく CLI なのは、入口を AI 以外にも開けておくため(§5)
- ただし tmux による独立には代償がある。Claude アプリからは端末の画面が見えない(§4)