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
