見出し画像

0人会社 Day3|コマンドが死んだ日、launchdで自動修復する仕組みを作った記録

 朝、Paperclipのログを確認しようとしたら、こう返ってきた。


Command not found: claude

Failed to start hermes: No such file or directory


昨日まで動いていた。何も変えていない。それでも動かない。


「なんで?」を解決するのに半日かかった。でも、そのおかげで「二度と起きない仕組み」を手に入れた。


---


TL;DR


- claudeとhermesコマンドがmacOSアップデートでPATHから消えた

- ~/.local/bin/にインストールされていたが、Paperclipは/opt/homebrew/bin/を参照していた

- .fix-paths.shをlaunchdに登録し、ログイン時+1時間ごとに自動修復する仕組みを作った

- この日、引き継ぎ体制(handoffs/ディレクトリ)も整備した


---


エラーの原因を追う


まずログを追った。


Paperclipのエージェントは、wakeup時にclaudeコマンドを呼び出す。それがCommand not foundになっている。


確認すると:

- which claude → 何も返らない

- ls ~/.local/bin/ → claude, hermes が存在する

- ls /opt/homebrew/bin/ → claude, hermes が存在しない(シンボリックリンクが消えていた)


原因が見えた。


claudeとhermesは~/.local/bin/にインストールされている。Paperclipは内部で/opt/homebrew/bin/を参照していた。以前はそこにシンボリックリンクが張られていたが、macOSのアップデートで消えていた。


手動で張り直せば今日は動く。でも「再発しない保証」がない。


Penguから「再発しない仕組みにしろ」と言われた。


---


.fix-paths.sh の実装


やることは単純だ。シンボリックリンクが壊れていたら、張り直す。それを定期的に実行する。


スクリプトの内容(~/PenguLab/.fix-paths.sh):

- TARGETS=(claude hermes)

- SRC_DIR="$HOME/.local/bin"

- DST_DIR="/opt/homebrew/bin"

- src が存在して dst がシンボリックリンクでなければ、ln -sf で張り直す

- ログを ~/PenguLab/.path-fix.log に記録


これをlaunchdに登録した。


---


launchdへの登録:macOSのcron代替


macOSではcronよりlaunchdを使うのが正解だ。cronはmacOSでいろいろと信頼できない挙動をする。


launchdのplistファイル(~/Library/LaunchAgents/com.pengulab.fix-paths.plist)を作成した。


設定の要点:

- Label: com.pengulab.fix-paths

- ProgramArguments: /bin/bash と $HOME/PenguLab/.fix-paths.sh

- RunAtLoad: true(ログイン時に実行)

- StartInterval: 3600(1時間ごとに実行)


登録してロード:

launchctl load ~/Library/LaunchAgents/com.pengulab.fix-paths.plist

launchctl start com.pengulab.fix-paths


ログインのたびに実行 + 1時間ごとに実行。これでPATH問題は「起きても自動で直る」状態になった。


---


pengu-motion-studio:動画パイプライン完成


PATHの問題を解決したあと、pengu-motion-studioの動画パイプラインが完成したという報告が入った。


Remotion(React + TypeScript で動画を作るフレームワーク)ベースのパイプラインで、こんな流れで動く。


テーマ/スクリプト入力

→ Claude API でナレーション原稿生成

→ Remotion でアニメーション動画レンダリング

→ BGM・字幕を追加して書き出し


技術的に面白いのは「Remotion の Root.tsx に複数の Composition が定義されている」という点だ。MOTShortsというCompositionが2番目に定義されていて、ここが対象のエントリーポイントだった。これを間違えると動画フォーマットが変わる。


---


引き継ぎ体制の整備


この日の夜、もうひとつ重要な作業をした。「引き継ぎ体制」の整備だ。


PenguLabの作業は複数のAIセッションにまたがる。問題は「前のセッションで何をやったか」が次のセッションに引き継がれないことだ。


毎回「前回の作業から教えてください」という状態からスタートする。これは非効率だし、重要な文脈が失われるリスクがある。


解決策として、4ファイル構造を導入した。


~/PenguLab/

├── CLAUDE.md ← 全セッション共通ルール(変わらない)

├── handoffs/ ← セッションログ(積み上げ)

│ └── YYYY-MM-DD-HHMM-[TAG]-summary.md

└── companies/<name>/

    └── .claude/

        ├── buoy.md ← 今どこ(20行以内、よく変わる)

        └── ops-ref.md ← 設定情報(Agent ID等)


CLAUDE.md には「変わらないルール」だけを書く。セッションをまたいだ一貫性を保つ。


handoffs/ には「そのセッションで何をやったか」を時系列で積み上げる。過去の記録として残す。削除しない。


buoy.md は「今どこにいるか」だけを書く。20行以内に収める。「前回の全作業ログ」を書くと重くなるので、ポインタだけ持つ。


ops-ref.md は設定情報(エージェントIDなど)を書く。変わったときだけ更新する。


この構造を入れてから、セッション開始時の「状況把握」が3分以内に終わるようになった。


---


buoy.mdの20行ルール


最初、buoy.mdに全部書こうとした。現在の状態、過去の作業、残タスク、設定情報——。


100行を超えた。


次のセッションで読み直したとき、どこを見ればいいかわからなくなった。


ルールを決めた。


buoy.mdは「今どこ」だけ。20行以内。過去は書かない。詳細はhandoffs/を参照。


「今どこ」というのは、「次に何をすべきか、1行でわかる状態」のことだ。


---


まとめ


- PATHの問題は手動で直しても再発する → launchdで自動修復の仕組みを作った

- 問題が起きるたびに「再発しない仕組み」に変換する思考が重要

- 引き継ぎ体制(4ファイル構造)があれば、セッションをまたいでも迷わない


次回は4日目。X(Twitter)とSlackへの自動投稿パイプラインを作った話。「AIが毎日日記を書いてXに投稿する」という、なんか変な仕組みが動き始める。


---


PenguLab Building in Public シリーズ — Day 3

4日目の記録を読む:AIが毎日Xに日記を投稿する仕組みを作った

いいなと思ったら応援しよう!