cc-sessions
claude-code-ide.el セッションを「Majordom」(または同一 Emacs サーバーにアクセス可能なその他のセッション)から管理するための、具体的な emacsclient --eval レシピ集。原則(なぜそうするのか)は majordom.md にあり、ここには完成した呼び出しのみを記載します。
重要: 唯一安全な起動コマンドは claude-code-ide-start
claude-code-ide-continue、claude-code-ide-resume、および古い claude-code-ide(いずれも引数なし)は、headless から直接呼び出してはいけません。これらの各関数は、ディレクトリにアクティブなセッションが既に存在する場合、ブロッキングを引き起こす (read-string "Instance name (empty for auto): ") を呼び出し、キーボード操作を行うユーザーが存在しない状態で永久にハングアップします(これは3つの関数すべてで経験的に確認されています)。唯一の例外は、人間が直接行うインタラクティブな M-x です。
claude-code-ide-start(シグネチャ (&optional instance-name continue resume))は、これら3つのケースすべてを1回の呼び出しでカバーし、インスタンス名をインタラクティブに要求することは決してありません。
;; 通常の新しい会話の開始
(let ((default-directory "/home/eugine/job/<プロジェクト>/")
(claude-code-ide-cli-extra-flags "--remote-control <プロジェクト>"))
(claude-code-ide-start "<名前-または-nil>"))
;; claude-code-ide-continue の代わり
(claude-code-ide-start "<名前-または-nil>" t nil)
;; claude-code-ide-resume の代わり(インタラクティブピッカーを claude ターミナル**内部**で開く、
;; Emacs ミニバッファは使用しない — 呼び出し自体は emacsclient をブロックしない)
(claude-code-ide-start "<名前-または-nil>" nil t)
instance-name(第1引数)が nil の場合、自動番号が使用されます(vedmid-2、vedmid-3...)。明示的に指定するのは、ユーザー自身が新しいコピーの目的/名前を指定した場合のみにしてください。不明な場合は、自分で推測せずにユーザーに確認してください。
開始前: 現在の状態を確認する
(mapcar (lambda (b) (list (buffer-name b) (and (get-buffer-process b) (process-status (get-buffer-process b)))))
(seq-filter (lambda (b) (string-match-p "claude-code\\[<プロジェクト>" (buffer-name b))) (buffer-list)))
- アクティブなセッションがない場合 →
(claude-code-ide-start nil t nil)(continueと同様に、プロジェクトの最新の会話を取得します)。 - アクティブなセッションがある場合 → 「再起動のため」に停止してはいけません。同じ
claude-code-ide-startを使用して追加のコピーを起動します(resume=tで特定の古い会話を選択する目的の場合、または新しい会話を開始する場合は引数なし)。
開始後: バッファ内の実際の検索で remote-control を確認する
ハングアップしないことだけでは、--remote-control が機能したことの証明にはなりません(エピソード: フラグを忘れた場合、セッションはきれいに起動するが、リモート制御にならない)。
(with-current-buffer "*claude-code[<プロジェクト>]*"
(save-excursion (goto-char (point-min))
(if (search-forward "remote-control" nil t) "FOUND" "NOT FOUND")))
NOT FOUND の場合でも、必ずしもエラーではありません。バッファの完全な内容(buffer-substring-no-properties (point-min) (point-max))を確認してください。文字列がレンダリング範囲外にあるか、(大規模セッションの場合) eat の可視スクロールバック範囲外にある可能性があります。ターミナル自体は会話全体ではなく、最近の履歴のみを保持します。
セッションの停止: 最初に query-on-exit を無効にし、次に停止する
claude-code-ide-stop 自体は安全であり、セッションが remote-control を持つかどうかに依存しません。しかし、通常の Emacs 確認「Buffer "..." has a running process; kill it?」は非同期で(process-sentinel 内で、claude-code-ide-stop が戻った後に)発生するため、呼び出し自体を let でラップしても回避できません。プロセスのフラグは、別の呼び出しで事前に無効にしておく必要があります。
(let ((proc (get-buffer-process "*claude-code[<プロジェクト>]*")))
(when proc (set-process-query-on-exit-flag proc nil)))
(with-current-buffer "*claude-code[<プロジェクト>]*" (claude-code-ide-stop))
ディレクトリに複数のコピーがある場合(vedmid、vedmid:2、vedmid:masazh...)、default-directory ではなくそのバッファのコンテキストで claude-code-ide-stop を呼び出してください(with-current-buffer)。メッセージでどのコピーが停止されたか確認できます("Stopping Claude Code vedmid:masazh...")。
もし確認がすり抜けてハングアップした場合(ps aux | grep emacsclient にスタックしたプロセスが表示される場合)は、自分で解除しようとしないでください(--eval の再試行も、emacs へのシグナルも禁止)。ユーザーにライブ Emacs で応答するよう依頼してください。この危険性の完全なコンテキストについては emacs.md を参照してください。
インタラクティブピッカーでのナビゲーション(resume リスト、permission 確認)
セッションリスト(resume)とパーミッション確認メニューは、ターミナル内部でレンダリングされます(Emacs ミニバッファ経由ではありません)。これらは、emacsclient --eval による Elisp 呼び出しではなく、生の process-send-string を介した通常の ANSI シーケンスで制御します。
(process-send-string (get-buffer-process "*claude-code[<プロジェクト>]*") "\e[B") ; 下矢印
(process-send-string (get-buffer-process "*claude-code[<プロジェクト>]*") "\e[A") ; 上矢印
(process-send-string (get-buffer-process "*claude-code[<プロジェクト>]*") "\e[6~") ; Page Down
(process-send-string (get-buffer-process "*claude-code[<プロジェクト>]*") "\r") ; Enter(確認)
各キー送信後、バッファ内容(buffer-substring-no-properties)を再読み取りし、カーソル位置(❯)とタイトル (N of M) を確認してから、さらに移動したり確認したりしてください。確認なしに複数ステップを盲目的に移動しないでください。パーミッション確認メニューの直接選択のための数字キー("3")は動作が確認されていません。矢印キー + Enter によるナビゲーションがより信頼性があります。
Permission-mode の切り替え(Shift+Tab)— auto-accept とは別のもの
ターミナルのステータス行(⏸ manual mode on、⏵⏵ accept edits on、⏸ plan mode on、⏵⏵ auto mode on)は、claude バイナリ自体によってのみ制御されます。Emacs はこれについて何も知りません。サイクル(Shift+Tab、4つの状態):manual → accept edits → plan → auto → manual。
(process-send-string (get-buffer-process "*claude-code[<プロジェクト>]*") "\e[Z")
切り替えは時々中間のツール確認プロンプト(Do you want to proceed?)を引き起こすことがあります。目的が auto モードに戻ることである場合は、数字キーではなく矢印キー + Enter で「Yes, and switch to auto mode」を選択してください。
claude-code-ide-toggle-auto-accept — 別の Emacs 関数、同じ状態ではない
上記の permission-mode サイクルと混同しないでください。この関数は、セッション構造体上の Elisp フラグのみを切り替え、MCP ツール openDiff にのみ影響します(ファイル保存前の ediff 表示の提案)。ON → ediff は表示されず、ファイルは即座に保存されます(FILE_SAVED)。OFF → 通常の ediff が表示されます。この呼び出しによってターミナルのステータス行は変更されません。
(with-current-buffer "*claude-code[<プロジェクト>]*" (claude-code-ide-toggle-auto-accept))
バッファ内容をユーザーに「あたかも自分が見ているかのように」表示する
(with-current-buffer "*claude-code[<プロジェクト>]*" (buffer-substring-no-properties (point-min) (point-max)))
大規模セッションの場合は、切り詰めてください((max (point-min) (- (point-max) N)) (point-max))。完全な内容はメガバイト単位になる可能性がありますが、eat の可視スクロールバックは常に制限されています(実際にレンダリングされる部分は無限に増加しません)。