自前のForgejoサーバーを捨て、GitHubとClaude Codeのスマホ運用へ移行する流れを表した図

自前Gitサーバー(Forgejo)でAIエージェント基盤を作って、3日で捨てた話

AIエージェントに開発を任せる仕組みを「どこまで自前で持つか」で悩んでいる人向けの記録です。結論から言うと、私はローカルForgejoでの完全自前運用を一度組み上げ、そして捨てました。捨てて初めて分かった「管理を手放す価値」と、その先で出会ったスマホ運用のパラダイムシフトまでを、時系列で残します。 これは「やってみてうまくいった成功談」ではなく、「作り込んで撤退した正直な記録」です。3日かけて組んだものを3日で捨てたので、その判断に至るまでの過程と、そこで得た教訓を共有します。 きっかけは、以前作った agent runner だった そもそもの出発点は、以前作った GitHub IssueからCodexを動かすagent runner でした。 GitHub Issueをキューにして、VPS上のrunnerがそれを定期的に拾い、Codex CLIを非対話で実行してPRまで作る。ターミナルに張り付かなくても、スマホからIssueを投げれば作業が進む。ここまでは確かに動いていて、私の開発体験は一度大きく変わりました。 ただ、AIエージェントを使い込むほど、人は欲が出てきます。「この仕組み、もっと自分の手元に寄せられないか」と。そこから今回の迷走が始まりました。 GitHubのIssueが使いづらくて、自分で作り始めた そもそもの発端は、もっと素朴な不満でした。GitHubのIssueが、どうにも使いづらかったのです。 動作がなんとなくもっさりするし、リポジトリが増えてくると「これはどのリポジトリのIssueだったか」が分かりにくい。実際、別のリポジトリにIssueを書き間違える、というミスが何度も起きていました。 それで、こう思ったのです。「Issueくらいなら、自分で作ってローカルサーバーに立てておけばいいのでは」と。さっそく、AIエージェントの力を借りて、Issue管理の仕組みをさくっと自作しました。 ところが、作っているうちにスコープがどんどん膨らんでいきます。Issueがあるなら、プルリクエストも要るのではないか。PRがあるなら、差分を確認する仕組みも要るのではないか。AIエージェントがIssueを読み込むところまではいいとして、その後のPRやレビューのやり取りは、いったいどう作ればいいのか。 考えているうちに、はたと気づきました。これは結局、GitHubそのものを作ろうとしているのではないか、と。 であれば、答えは単純です。同じものがOSSにあるなら、それを使えばいい。そこでOSSの Forgejo を採用しました。ForgejoはGiteaから派生した、セルフホスト前提のGitフォージです。GitHubに近いIssue・PR・Webhookの機能が一通りそろっています。 根っこには、外部サービスへの依存を切りたい、全部を手元に置きたい、という気持ちもありました。実行時間の枠や無料プランの制約、コードやIssueを外部に預けることへのうっすらとした抵抗。そして正直に言えば、「この仕組みを一から自分で組んでみたい」という技術的な好奇心も、大きな燃料だったと思います。 そこでローカルにサーバーを立て、Forgejoをインストールしました。ただ、立てて動かすまでにも、地味な手間が少しずつ積み重なります。APIトークンや権限まわりの設定、サーバーとして動かし続けるための構築と運用。意外なことにWebhook連携そのものは素直に動いたのですが、「GitHubなら最初から用意されていたもの」を一つずつ自分で揃え直している感覚は、この時点ですでにありました。 「これでGit基盤も含めて、開発のループが全部自分の管理下に入る」——そう思っていました。 ClaudeとCodexで「3往復の自動レビュー」を組んだ Forgejoを土台に、私は前回のrunnerをさらに進化させた「エージェントランナーv2」を組みました。 流れはこうです。 ForgejoにIssueを書く そのタイミングでWebhookが発火し、処理が起動する Claude CodeがIssueを読み取る そのままClaude Codeが実装まで進める その実装を内部でCodexにレビューさせる このレビューのやり取りを最大3回まで自動で往復させる 完成したらIssue/PRにコメントで結果を返す ポイントは、AI同士が互いをレビューし合う閉ループを自動で回す構造にしたことです。Claudeが実装し、Codexがレビューし、また直す。前回の記事で AIエージェント自身がテストを実行して直す閉ループ の話を書きましたが、それを「実装者AI」と「レビュアーAI」の二者間にまで広げた形になります。 Issue → PR → レビュー往復 → コメントに記録を残しつつ手元に戻る。図にすると一本の気持ちのいいパイプラインで、組んでいる間はかなり楽しかったです。 つまずいたのは「どのサーバーに置くか」だった ところが、組み上げた直後から現実的な問題が頭をもたげてきました。「これ、結局どのサーバーで動かし続けるのか」という問題です。 最初はローカルのマシンに置きました。しかしローカルに置いたままでは、外出先など別のネットワークからは叩けません。そこで VPN でつなぐことを考え、Tailscale を試しました。手元のマシン同士を VPN 網で直接つないでしまえば、外からでも安全にアクセスできます。 ただ、普段使いの Mac のバックグラウンドで VPN クライアントが常駐し続けるのが、どうも好きになれませんでした。ならばと、VPS 側に Tailscale を入れて、運用一式を VPN ネットワークの中に閉じ込めてしまえば安全ではないか——と考えて構成してみました。 しかし実際にやってみると、これがなかなか雑で、手間のかかる構成でした。管理する箇所もトラブルの種も、明らかに増えていきそうです。結局、この VPN 構成は廃止しました。 ...

公開: 2026年6月1日 · Toshihiko Arai
Codex、Claude、iOSアプリ開発の3つが淡く重なり合う抽象的なアイキャッチ画像

【新規記事】AIエージェントに没頭した20日間。Codex、Claude、iOSアプリ開発まで

ここ最近、AIエージェントをかなり集中的に触っていた。 Codex の $100 プランを契約し、20日ほどがっつり使ってみた。 結論から言うと、来月からは $20 プランへ戻す予定である。 理由は単純で、$100 プランの容量を使いこなすほど、自分の指示が追いつかなかったからだ。 Codex が物足りなかったわけではない。 むしろ十分すぎた。 5日のコンテキスト上限を使いこなすほどの指示を、自分が出せなかった。 つまり、自分の処理能力が先に限界へ来た。 CLI型AIエージェントのすごさは「フィードバックループ」にある Codex に限らず、この手の CLI 型AIエージェントを導入してすごいと思ったのは、ローカルプロジェクトを理解してくれることだった。 これまで Web ブラウザ版の ChatGPT を使ってコード修正を相談する場合、修正したいファイルを毎回アップロードしたり、コードを貼り付けたりする必要があった。 しかし CLI 型AIエージェントでは、ローカルのプロジェクトをそのまま見てもらえる。 そのため、プロジェクト全体をまるで把握しているかのように、かなり的を射たコーディングをしてくれる。 ただ、改めて考えると、すごさはそれだけではない。 もっと大きいのは、AIエージェント自身がテストコードを実行できることだと思う。 AIがコードを改修する。 そのコードに対してテストを実行する。 テストが失敗したら、エラー内容を読んで、もう一度コードを直す。 そしてまたテストを実行する。 これは、単なるコード生成ではない。 入力に対して出力を返すだけではなく、その出力結果を観測し、フィードバックして、次の修正に反映する流れである。 制御工学っぽく言えば、開ループではなく、閉ループになった感じがある。 これまでのAIチャットは、どちらかといえば「コードを提案して終わり」だった。 しかし CLI 型AIエージェントでは、生成したコードを自分で実行し、結果を見て、自分で修正する。 このフィードバックループが入ったことで、AIによるコーディングはかなり実用的になった。 人間に例えれば当たり前の話だが、たったこれだけで、精度はぐんと上がった感がある。 (このことは、今後 AI をうまく使いこなすための大きなヒントになるかもしれない) もちろん、すべてが完璧になるわけではない。 テストが通っても、仕様として正しいとは限らない。 こちらの気持ちや意図まで理解するには程遠い場面も多々あり、最後は人間による判断が必要になる。 それでも、テスト結果という強いフィードバック信号をAI自身が扱えるようになったことは、かなり大きな変化だと思う。 Claude も契約してみた 一方で、Claude の $20 プランも契約してみた。 CLI AI エージェントは Claude が先駆者だと思うが、Codex を先に体験してしまったので、Claude を使うことに今更感があり少し足踏みしていた。 しかし、実際に使ってみると Codex との違いを比較できて、かなり面白かった。 ただし、契約時にはクレジットカード決済で少し苦労した。 なかなか決済が通らず、最終的には VISA の楽天カードについてサポートへ連絡し、ストップされていた件を説明して解除してもらうことで、ようやく決済できた。 ...

公開: 2026年5月9日 · Toshihiko Arai
多窓ターミナルの旧世界からGitHub IssueキューとVPS上のagent runnerへ世界線が切り替わるイメージ

GitHub IssueからCodexを動かすagent runnerを作ったら世界線が変わった

この記事で伝えたいこと Codex などの AI コーディングエージェントを使うと、コードを書く時間そのものは短くなる。一方で、実際に使い込むほど「エージェントへ指示を出す」「結果を確認する」「失敗したら再実行する」「別の作業をもう一つ投げる」といった運用に時間を取られるようになった。 気がつくと PC の前に張り付き、ターミナルを 4 窓から 8 窓くらい開き、どの作業がどこまで進んでいるのかを追い続けていた。これはこれで便利ではあるが、開発体験としてはまだ人間がかなり忙しい。 そこで、GitHub Issue をキューとして使い、VPS 上の agent runner が Codex CLI を非対話で動かす仕組みを作った。この記事ではプログラムの細部ではなく、なぜ作ったのか、GitHub Actions と何が違うのか、どんな構成で動かしているのか、そして何が変わったのかを整理する。 「agent runner」 はあくまで自作のプロダクト名であり、前回の記事 さくらのサーバーでCodexをcronで動かしてブログ記事を自動リライトさせる をさらに進化させた形である。 想定読者 この記事は、すでに AI コーディングエージェントを使っている開発者に向けて書いている。 特に次のような人を想定する。 Codex CLI や Claude Code などのエージェントを日常的に使っている ターミナルを複数開いて並行作業している GitHub Issue や PR を開発の入口として使っている CI/CD とは別に、AI エージェントへの作業依頼をうまく管理したい 導入: AI 駆動開発は便利だが、人間が忙しい AI コーディングエージェントを使うと、実装、調査、テスト修正、ドキュメント作成などをかなり任せられる。 ただし、使えば使うほど別の課題が出てくる。 ターミナルをいくつも開いて、複数のエージェント作業を見張る必要がある どの作業に何を指示したか分からなくなりやすい 失敗した作業を再投入するたびに、文脈を思い出して指示し直す必要がある PC の前にいないと、次の指示を出しにくい エージェントは作業を進めてくれる。しかし、作業を投げる入口がターミナルに閉じていると、人間は結局ターミナルの前から離れにくい。 この状態を変えたかった。 なぜ Codex GitHub Action ではないのか 最初に考える選択肢は GitHub Actions だと思う。GitHub のイベントをトリガーにして処理を走らせるなら、Actions は自然な選択肢だ。 ...

公開: 2026年5月5日 · Toshihiko Arai
サーバー上のcloneリポジトリでCodexが安全な作業ブランチを動かしているイメージ

さくらのサーバーでCodexをcronで動かしてブログ記事を自動リライトさせる

ブログ記事の簡単なリライト作業を、手元のMacではなくサーバー側でも動かすようにしてみました。 やりたいことは、サーバーにブログ用リポジトリを clone して、その中で Codex CLI に記事リライト系の作業を任せ、さらにコミット・push・PR作成までを自動化することです。 実際には gh の権限、privateリポジトリのclone、Codexのログイン、sandbox など、細かいところでつまずいたことがいくつかありました。それらを中心に、備忘録として残しておきます。 やりたかったこと まずはサーバーにSSHでログインし、GitHubリポジトリを用意します。 仮に、clone先は以下とします。 /home/appuser/repos/private-blog ここにブログのprivateリポジトリをcloneして、記事リライト用のバッチ処理から Codex CLI を呼び出します。最終的には、このバッチ処理をcronで定期実行する想定です。 当然、git / gh / codex がシェルで使えるように、サーバー側へ各コマンドをインストールしておく必要があります。 本番サーバーでやるのが怖い場合は、もう1台サーバーを用意するのも現実的です。さくらVPSなら比較的安いですし、私も本格運用するなら別サーバーを用意する予定です。 もちろん、ラズパイなどを使って自鯖で処理させるのも十分ありだと思います。 サーバー側でCodexに作業させるので、本番公開ディレクトリとは必ず分けておきます。 /home/appuser/public-site # 公開用 /home/appuser/repos/private-blog # 作業用clone また、私の場合は、リポジトリのmainブランチも直接編集させず、worktreeを使った別ブランチで作業させるようにしています。 全体の関係は、次のようなイメージです。 今のところ、PRのレビューからbuild / deploy作業までは、人間が担当するようにしています。 そのためローカルMacの出番は、最初の初期設定とPR確認が中心です。そこまで整えば、毎回SSHでサーバーに入って手作業する必要はかなり減ります。 なぜGitHub Actionsではなくサーバー上のcloneで回したか ところで、この手の自動化をChatGPTへ相談すると、かなりの確率で GitHub Actions 案が出てきます。 MicrosoftはGitHubを買収済みで、OpenAIにも大きく投資しています。 Microsoft → GitHubを買収済み Microsoft → OpenAIへ大規模投資 だからActionsが推されるのでは、と邪推したくなるくらい毎回出てきます。もちろん半分冗談です。実際には、定期実行やPR作成までGitHub側で完結できるので、CI/CDの定番案として出てくるのだと思います。以前、VPSへのデプロイでは GitHub CI/CD で VPS へ自動デプロイするまで にまとめたように、Actionsの便利さも確認しています。 それでも今回は、サーバー上のcloneで動かす方を選びました。 理由は主に3つです。 1つ目は、すでにサーバー上で日次処理を動かす前提があったことです。記事リライトはサイト運用のローカルな作業に近く、実行ログや失敗時のworktreeをサーバー上に残せる方が追いやすいと考えました。 2つ目は、秘密情報を増やしたくなかったことです。GitHub Actionsに渡すsecretを増やすより、サーバー側のenvファイルに閉じた方が、今回の小さな運用では見通しがよくなります。 3つ目は、OpenAI API key を新しく使わずに進めたかったことです。Codex CLIはChatGPTログインでも使えるため、今回の確認ではAPI keyを新規発行せず、手元で使っているアカウントのログインで試しました。もちろん、公式にはAPI key認証もあり、CIや完全自動化ではAPI keyの方が向く場面もあります。ここでは「今回の運用では使わなかった」という整理です。 ...

公開: 2026年5月2日 · Toshihiko Arai
雨の日の机でAIエージェントがマイクラ風の座標表示Mod改造を手伝っているイラスト

雨の連休にマイクラを再開し、CodexにMiniHUD導入とMod改造を頼んだ話

せっかくの大型連休、ゴールデンウィークだというのに雨が続くらしい。 釣りへ出かける気分にもなれない。というより最近はCodexの衝撃とともに、Codexへの指示とレビューに時間を取られまくって消耗し切っている。 もはや私はAIの奴隷に成り下がっているのではないか。 AIが人間社会を楽にしてくれるなんて嘘っぱちじゃないか。人間作業だったら数週間かかるものを一瞬でAIが生成してくれるからといって、人間側はまったく楽にならないのだ。 なぜなら、AIの生成物のレビューに時間がかかる。イメージと違う成果物が出てきたら、当然、自分ではすぐ直せないほど高度なものなので、指示書を書き直して再度依頼する。そんなことを高速で繰り返すものだから、こちらは休みなく働かされ続ける。 少しでも時間にゆとりが出ようものなら、Codexの /status を見て「課金プランを使い切っていないともったいない」という感情が働き、次の指示を考えなければならない。ターミナルだって4窓をCodexに使い、各窓をさらに左右に分割し、人間側が操作できるCLIをなんとか確保している。 きっと私が間違っているのだろうが、最近はそんな日々を送っていたため、だいぶ病んでいる。 現実逃避すべくマイクラを再開したのは自然な流れだろう。 Note ただ、この状態はその後少しだけましになった。手元のMacに張り付いてCodexの様子を見続けるのではなく、さくらのサーバー上にリポジトリをcloneして、Codexに記事リライトを定期実行させる仕組み を作ったからだ。結局AIに仕事を増やされている気もするが、人間がずっとターミナルを監視し続ける時間は少し減った。 久しぶりに一から始めるマイクラ 久しぶりにMinecraftを一から始めた。雨の連休、釣りに行けない気持ちを抱えたまま、仮想世界の砂浜へ降り立つ。 画面を見ていると、これは小田原サーフだろうか、などと勝手に脳内補正が始まる。現実の海へ行けないなら、ブロックの海辺でよいではないか。 ただ、ゲームを始めてすぐ、マイクラそのものよりも「CodexにModをインストールさせてみよう」という気持ちが勝ってしまった。ここがもう病の深いところである。 以前にも手作業でModを入れたことはあったのだが、仕組みをちゃんと理解していないせいか、とても面倒な印象が残っていた。手動ではやりたくない。こういった作業こそCodexに任せるのが正解だろう。 そこで思い出したのが、座標を常に画面上へ表示したいという話だった。 デフォルトでもF3のデバッグ画面を開けば座標は確認できる。ただ、情報量が多すぎて見づらいし、普段のプレイ中にずっと出しておくには少し邪魔だ。必要なのは、座標だけを小さく常時表示してくれる仕組みである。 MiniHUDを見つける 調べてみると、まさに欲しかったものとして MiniHUD があった。 MiniHUDは、いわば小さなF3画面のように、座標などの情報を選んで表示できるクライアント側Modである。Modrinthの説明でも、MiniHUDは「mini F3」的なHUDや各種オーバーレイを提供するクライアントサイドModとして紹介されている。 また、MiniHUDを使うには共通ライブラリである MaLiLib も必要になる。MaLiLibは、設定画面、ホットキー、GUIまわりなど、masa氏系Modで共通利用される部品をまとめたライブラリという位置づけらしい。 こういう依存関係を自分で追いかけるのが面倒だったので、すぐにMinecraft用のプライベートリポジトリを作り、git clone で取り込み、Fork、IntelliJ IDEA、Codexあたりの初期化を済ませた。 GitHub Issuesには、次のような指示を追加した。 codex --search exec --full-auto で以下タスクを順番に自動で進めてください。 --- MiniHUDをインストールして、座標を表示できるようにしてください。 この実装を始める前に、まずは実行計画を立てて下さい。 それをTODOリストとしてMarkdownファイルに落とし込んでください。 このIssueのURLをCodexへ貼り付けて作業開始。数分でMod導入まで進んだ。 このスピード感は確かにすごい。人間が公式ページを読み、依存関係を確認し、バージョンを合わせ、ダウンロード先を探し、配置先を調べる。その一連の調査と作業を、Codexはかなりの速度で進めてくれる。 ただし、速いからといって楽になるとは限らない。ここから人間は、何が入ったのか、どこへ置かれたのか、バージョンは合っているのか、起動して本当に動くのかを確認し続けることになる。 今度はModの表示を変えたくなる 座標が表示できるようになると、さらに余計なことを思いつく。 MiniHUDの表示で WEST や EAST と出ている部分を、「西」「東」のように日本語化できないだろうか。 ただの表示文字列を変えるだけなら簡単そうに見える。だが、Modは普通のアプリではなく、Minecraft本体のバージョン、Modローダー、依存Mod、マッピング、ビルド設定が密接に絡む。ここを理解しないまま触ると、急に難しくなる。 調べるとMiniHUDはオープンソースだった。そこで速攻でforkして、ソースコードをcloneし、IntelliJ IDEAで開いて、表示文字列らしき箇所を変更してみた。 ところが結果として、この方法はうまくいかなかった。 ソースコードを直してもダメだった理由 今回つまずいたポイントは、ソースコードを直すこと自体ではなく、ビルドしたModが自分のMinecraft環境に合っていなかったことだった。 MinecraftのModは、単に「MiniHUDのソースをビルドすれば動く」というものではない。 Minecraft本体のバージョン Fabric、Forge、LiteLoader、OrnitheなどのModローダー MaLiLibなど依存Modのバージョン そのブランチが想定しているマッピングやビルド設定 これらが揃って初めて、入れ替え可能なJARになる。 ...

公開: 2026年4月30日 · 更新: 2026年5月2日 · Toshihiko Arai
1つの.gitをmain、feature A、feature Bの3つのworktreeが共有している図

git worktreeでAI時代の並列開発を試す。Codexに別ブランチを同時に任せるには

AIコーディングエージェントに複数の作業を同時に任せたい場面があります。 たとえば、片方ではUIを直し、もう片方ではテストを直す。あるいは、A案とB案を別々に試す。こういうとき、同じ作業ディレクトリで同時に編集させると、未コミット変更やブランチ切り替え、同じファイルの編集が絡んでかなり危なっかしくなります。 そこで使えるのが git worktree です。 この記事では、1つのローカルリポジトリから複数の作業ディレクトリを作り、feature/new-feature-a と feature/new-feature-b を別々に進める流れを、実際のコマンドと結果で確認します。 git worktree とは git worktree は、1つのGitリポジトリに複数の作業ディレクトリを紐づける機能です。 普通は1つのリポジトリに1つの作業ディレクトリがあり、その中で git switch や git checkout を使ってブランチを切り替えます。 一方、git worktree を使うと、ブランチごとに作業ディレクトリそのものを分けられます。 /tmp/worktree-demo は main /tmp/worktree-demo-a は feature/new-feature-a /tmp/worktree-demo-b は feature/new-feature-b というように、別々の場所で別々のブランチを同時に開けます。 git checkout との違い git checkout や git switch は、今いる作業ディレクトリの中身を別ブランチへ切り替える操作です。 作業途中の変更があると、切り替え時に止められたり、stashやコミットが必要になったりします。 git worktree は、ブランチを切り替えるのではなく、作業ディレクトリを増やします。なので、main の作業場所を残したまま、A用、B用の作業場所を別に用意できます。 AIエージェントに並列で頼む場合は、この差がかなり大きいです。 検証用リポジトリを作る 今回はブログ本体のリポジトリではなく、/tmp に捨てリポジトリを作って試します。 cd /tmp mkdir worktree-demo cd worktree-demo git init -b main printf '# worktree demo\n' > README.md git add README.md git -c user.name='Demo User' -c user.email='[email protected]' commit -m 'initial commit' ここまでで main ブランチに最初のコミットが1つある状態になります。 ...

公開: 2026年4月28日 · Toshihiko Arai