ブラウザ経由をやめて2台のPCのClaude Codeをつないだ日と、TTSナレーションのテンポ設計

開発mdx-playground

夕方、手元のリポジトリがリモートより遅れている気がして、プルさせた。 遅れているどころか分岐していた。 手元に2件、リモートに3件、それぞれ固有のコミットがある。 単純な早送りでは追いつけないので、マージで取り込ませた。 衝突は1件も出なかった。

入ってきたのは記事2本と、もう1台で書かれたTTSまわりのセットアップメモだった。 devサーバーは動いたままだったので、新着の2本をブラウザで開かせた。 見出しも目次も図解も崩れていない。

TTSのテンポ設計をどこに置いたか

思い出せなかったのは、中身ではなく置き場のほうだった。 TTSで音声を作るとき、文と文の間をBPMのグリッドに合わせるという考え方をスキルに反映させたのは覚えている。 どのリポジトリに入れたかが出てこない。

探させたら、~/.claude をまるごと預けているリポジトリに tts-narration という名前で入っていた。 手元とリモートで進み具合の差は出ておらず、4日前の更新がそのまま入っている。

このスキルがやっているのは、話速を「なんとなく」で決めるのをやめることだ。 話速をBPMに換算して決め、読点は短く句点は長く、別々のグリッドに置く。 そうすると次の文が拍か小節の頭から始まる。 人が読むと話速はその日の調子で揺れるが、TTSは数値で固定できるので、シリーズ全編でテンポが揃う。

そのあと、やはりプッシュできていない気がすると言ってもう一度確かめさせた。 今度は音声まわりの別リポジトリも出てきたので、そちらも照合させた。 少なくともこの機体に押し忘れは残っていない。 そこまで確かめたところで手を止めた。

ブラウザ越しに話しかける必要があるのか

プルで入ってきた記事の1本は、複数の端末から進捗を1か所に集めるセミナー向けの構成だった。 それを開いて読んでいるうちに引っかかった。 この構成が成り立つなら、普段やっている「Windows側から隣のMacのClaude Codeに話しかける」も、もっと素直にできるのではないか。

今の経路はこうなっている。 ブラウザでclaude.aiを開き、Chrome DevTools越しに操作して、向こうのセッションへ文字を流し込む。 Macから送るぶんには通るのに、逆向きだけがやたら難しかった。

突き合わせさせたら、成立するという答えが返ってきた。 しかも自宅の2台のあいだなら、記事の構成より1段簡単な形で足りるという。 実装には入らせず、所見だけ出させた。

ここで方針が太りかけた。 出てきた案には、セッションの区切りを捕まえて自動で送るフックの機構が入っていた。 それは元の記事が「進捗を勝手に集める」ためのもので、こちらが欲しいのは送りたいときに1通送ることだけだ。 要らないと言ったら、前の整理が過剰でしたと引っ込めて、最小構成に書き直してきた。 部品を1つ足すたびに、あとで剥がす手間も1つ増える。

計画書を書いてMac側へ渡すまで

memoに計画書を書かせ、Codexに3回レビューさせた。 3回目で通った。

その計画をMacへ渡す段で、ブラウザのほうが止まった。 claude.aiがログアウトしていて、しかもログインしていたアカウントが違っていた。 ここで送り方を変えた。 ブラウザ経由をやめ、GitHubへプッシュして向こうでフェッチさせる形にした。 アカウントを揃えるより、リポジトリを1周させるほうが早い。

先の工程はMac側に実装させ、残りをこちらで進めさせた。 認証用の値は画面に出さないまま置かせて、疎通を確認し、実際に1通流した。 Windowsから隣へ届くところまでは通った。

送れたのに、返ってこない

詰まったのは返信だった。 向こうでは受け取れているのに、そこから打ったメッセージがこちらへ戻ってこない。

理由は機体の違いではなかった。 受けているのはターミナルから素に起動された新しいセッションで、claude.ai側の送信口を持っていない。 スキルには「ローカルのターミナルから素で起動したセッションは送信口を持たない」と前から書いてある。 それが今度はMac側で起きていた。 送れるかどうかを決めているのは、どちらの機体かではなく、そのセッションがどう起動されたかだ。

腑に落ちなかったのはここだった。 Macからはもともと送れていたのに、今回だけ向きが逆になっている。 ただ、逆転はしていない。 これまで送れていたセッションと、今回受けているセッションが別物だっただけで、法則は一貫していた。

もうひとつ聞いた。 tmuxを開かないと届かないのか、普通のターミナルで動いているClaude Codeには渡せないのか。 返ってきた答えはこうだった。 素のターミナルには、外から文字を届ける取っ手が無い。 tmuxを使っているのは好みの問題ではなく、そこが外から触れる唯一のまともな入口だからだ。

返信の経路をどう作るか

モデルをFable 5に切り替えて、返信の経路を設計させた。 出てきたのは、Windows側にtmuxを持ち込まない非対称の形だった。 キーストロークの注入を両側で再現しなくても、返信はWindows側が取りに行けば済む。

このあたりで、全部面倒になってやめる可能性のほうが高いという感触があった。 だから、巻き戻せる状態にしておくよう言った。 計画書に次の工程と、まるごと撤去する手順を書き足させた。 やめる判断をあとから安く取れるようにしておく。

Codexの4巡目を通してからプッシュし、できたばかりのブリッジを使ってMacへ実装指示を送った。 向こうのプッシュを監視させたら、7分ほどで検出した。 取り込んで往復テストを通し、未了がゼロなのを確かめてから計画書を締めた。

念のため「こんにちは」だけを1通送ってみた。 ブラウザを1枚も開かないまま、隣の機体のセッションに文字が入る。

ついでに数えさせたら、Mac側で動いているClaude Codeは4個あった。 このうちブリッジで届くのは、tmuxの中の1個だけだった。 残る3個(ターミナルから直に起動した2個と、デスクトップアプリ経由の1個)は、動いているのが見えるだけで送れない。

測定の前に足りなくなったメモリ

夜は別件で、2台のデプロイ速度に8.5倍の差が出ている理由の切り分けに入った。 手順はプルで入ってきていて、デプロイまでしなくてもビルドだけで測れると書いてある。

測る前に足元が崩れた。 空きメモリが31.9GBのうち4.7GBしかなく、nodeが38個で4.1GBを抱えている。 一覧させると、大口はChromeの56プロセスで7.6GB、次いで開きっぱなしのClaude Codeセッション10個で4.7GBだった。 起動時刻が朝から夜まで並んでいて、どれも自分が開いたものだった。

止めるものを選んで、子プロセスごと落とさせた。 空きは8.2GBまで戻り、devサーバーとMCPのプロセスは15個から2個になった。 ここでようやくビルドを走らせて、1回目の実測を計画書に書き足させた。

副産物として分かったのは、miseのshimが1回あたり100msほど上乗せしていることだ(shim経由で180ms、直接叩けば76ms)。 ただしプリレンダーはnodeが1プロセスなので、これが8.5倍差の主因という線はほぼ消えた。

終業のコミット

全部ステージングしてコミットさせたら、4グループに分かれた。 学習ゲートが止めたので中身を見ると、ソースコードの変更はゼロだった。 残っていたのはmemoの追記と、別セッションが書いた記事と、evalsのJSONと、ビルドが再生成した索引だけだった。 ここはスキップと判断して、理由を残したうえで通した。

日本語の強調が閉じない既知のパターンにも引っかかったので、最小限だけ直してプッシュした。

学び

  • ブラウザを介さないと届かない、という前提が思い込みだった。手が届く範囲に受け口を1つ置くだけで、経路はずっと短くなる
  • 送れるかどうかを決めるのは機体ではなく、そのセッションがどう起動されたか
  • 要らないと言った自動化の部品は、その場で外す。フック機構を残していたら、撤去の手順もそのぶん増えた
  • やめる見込みが高い作りものほど、先に撤去手順を書いておく
  • 何かを測る前に、自分が開きっぱなしにしたものを数える

明日に回したこと

  • ブリッジの記事に入れる図3枚を作って公開する
  • デプロイ速度の切り分けの続きを測る
#Claude Code #TTS #開発環境#メモリ管理#2台運用