駒形電産

OSSがなくなるか、少なくとも大きく衰退するのではないかという危機感を持っています。

AIがOSSを不可視化する

Vibe Coding Kills Open Source

生成AIはOSSを利用者から見えなくしていく。

これまでは利用者自身がOSSを探してREADMEを読み、作者やプロジェクトを知ったうえで利用していた。便利だと思えば感謝を伝えたり貢献したりすることもあった。

しかしVibe CodingによってAIが必要なソフトウェアを選び、組み合わせ、改変するようになると、利用者は元になったOSSの名前すら知らなくてよくなる。

OSS自体は使われ続けても、誰がどんな思想で作ったのか、どれほど役に立ったのかは見えなくなる。結果として作者への感謝や評価、支援、貢献も減っていく。

オーダーメイドソフトがOSSを不要にする

生成AIによって一人ひとりの用途や好みに合ったオーダーメイドのソフトウェアを簡単に作れるようになった。

既存のOSSを探して使い方を覚え、自分に合わない部分を我慢するより、最初から自分専用のものを作るほうが早い。

そうなれば多くの人が同じソフトウェアを共有する必要は薄れ、OSSの存在価値も小さくなる。

ソフトウェアは増えるがOSSは減る。

何が困るの?

僕はOSS文化そのものが大好きなので、なくなると非常に困る。

ただ一般の人から見れば「それって困ることなの?」と思うかもしれない。

しかしこれは単に僕が寂しいというだけではなく、社会全体にとっても良くないことだと思う。

共有地の悲劇

コモンズの悲劇 - Wikipedia

一人ひとりにとってはOSSを探して使うより、AIで自分専用のソフトウェアを作るほうが早くて便利かもしれない。

しかしみんながその選択をすると、改善やバグ修正、設計上の知見が共有されなくなる。社会全体で同じものを何度も作ることになり、品質を共同で検証できる共通基盤も育たない。ソフトウェア技術の蓄積も弱くなる。

一人ひとりにとって合理的な選択でも、その積み重ねによって誰もが利用できる共有資産が失われていく。

これがAI時代のOSSにおける「共有地の悲劇」ではないだろうか。

悲劇を避けるには

共有地の悲劇に対しては、利用者の善意だけに頼るのではなく、資源を守るための仕組みを作るのが一般的だ。

たとえば漁場なら漁業組合や政府が魚を捕ってよい時期や量を決める。利用者同士でルールを作って監視し、ときには違反に罰則を設ける。

漁場から利益を得る人が、その維持にも責任を持つようにする。

どうすればいいのか

OSSでも同じような考え方が必要になるのかもしれない。

AIや企業がOSSから大きな利益を得るなら、その一部がOSSの維持に戻る仕組みを作る。AIがどのOSSを利用したのか分かるようにする。企業や政府、業界団体が基金を作り、共有資産として支える。AIによって生まれた改善を、元のOSSへ戻しやすくする仕組みや標準を用意する。

もちろん漁場とOSSは同じではない。魚は捕れば減るが、ソフトウェアはコピーしても減らない。

減っていくのは作る人の意欲や改善を共有する習慣、コミュニティの活力だ。

それでも共有地を利用する人が、その維持にも参加する仕組みを作るという考え方は参考になる。

AI時代のOSSにも、漁業組合のように共有資産を共同で守る新しい制度や運動が必要になるのかもしれない。

部品や道具をちまちま集めてきて時間かかったけど、自作アケコンがやったとできた。嬉しい〜😭

自作アケコン

散らかり机。

自作アケコン完成直後

かなりギリギリのサイズで中に収めるのに苦労しました。無理やり詰め込んでパンパンです。格闘ゲーム用にはもっと大きいほうが安定するのでシューティングやレトロゲーム用にしようかな。

3Dプリントとか、塗装とか、ラズパイPICOとか色々と苦戦しましたがとっても勉強になりました。

使ったパーツ

基盤

ケーブル類

レバー

三和電子 JLX2-TP-8Y ジョイスティック

ボタン

ケース

レトロアーケードスティック

次は・・・

なんとかできましたが、色々改善したい点があるので次のを作りたい。

  • ピンヘッダが真横に出てる形だけど上面に出てる形の方が収まりがいい
  • マットな仕上げにしたが、ツルツル仕上げもやってみたい
  • 既存の3Dデータを使ったが、自分でデザインしたモデルで作りたい
  • 格闘ゲーム用にもっとデカくて重りとかを入れて安定したのを作りたい

さっさとスト6始めたほうがいいと思います。

Bambu Lab A2L買った!

去年末のAmazonブラックフライデーに定番のA1 miniを買って使ってたんだけど、僕の印刷したい大きめのデータが軒並み印刷できないのと、ブロブ発生からの直そうとして破壊してしまっていてしばらく印刷できてませんでした。

A1 mini blob

A1を買おうと思ってBambu Labのサイトを見に行ったら2日後に次のモデルが出るらしいということを知って新モデルのA2Lを買いました。

Image from Gyazo

デカくてめっちゃカッコいい😭

A1の256mmでも十分だったのにさらにデカい330mm×320mm×325mmは最高です。またブロブ発生を検知する機能がついたらしく、それでA1 miniを破壊した僕にとってはうってつけ。

A1 miniで使ってたAMS liteもそのまま使えるということで快適さに日々感動しております。

蛇足

A1 miniはほとんどのパーツがバラで買えるみたいなので、直すべきか、ジャンクとしてメルカリにでも出すべきか、捨てるべきか…。

Android用のシンプルなテキストエディター、TweekTextを作った。

TweekText

Androidゲーム機で設定ファイルを編集したい

RG RotateみたいなAndroidゲーム機を使っていると、ちょっとした設定ファイルを編集したくなることがある。XMLとかINIとかYAMLとかJSONとか、そういうやつ。

別にプログラムを書きたいわけではない。ただファイルを開いて、ちょっと直して、保存したいだけ。

しかし、Androidでそういう用途にちょうどいい無料・広告なしのプレーンなエディターが見つからなかったので作りました。

TweekText

TweekTextはAndroid 12以上で動く、シンプルなプレーンテキストエディターです。

  • Android標準のファイルピッカーで開く・保存
  • UTF-8
  • 既存ファイルの改行コードを維持
  • 検索・置換
  • XML / INI / YAML / JSON などの設定ファイル向けのシンタックスカラー
  • 無料
  • 広告なし

インストール方法

Google Playではまだ公開していない。

GitHub ReleaseにAPKを置いてあるので、そこから直接ダウンロードしてインストールする方式。

https://github.com/komagata/TweekText/releases/latest

インデントベースのコンパイル言語 Tya を作りました。

Tya — A language without hesitation

Image from Gyazo

Pythonっぽいインデントベースの見た目で、goみたいに1バイナリにコンパイルできる感じの言語です。

# hello.tya
user = { name: "komagata", age: 20 }

greet = user -> "Hello, {user["name"]}!"

if user["age"] >= 20
  print(greet(user))
$ tya build hello.tya -o hello
./hello
Hello, komagata

変わった特徴

ちょっと変わってるところは、動的型付け言語なのにコンパイル言語というところと、ソースコードとASTが情報の欠落なく相互に変換可能(Lossless AST)で、コメントも含めてソースコード表現が一意に決まるところです。(Canonical syntax

要するにgoで言えばgo fmtした結果だけが唯一の正解で、それ以外はSyntax Errorみたいな感じです。

迷わない言語をうたっていて、Syntaxだけじゃなくて、選択肢をなるべく1つだけ用意してそれ以外はできないようにしています。(迷わない言語 = 極端に自由度の少ない言語)

開発のモチベーション

なぜ作ったかというと、僕は以前、coffeescriptの書き味が好きだったんですが、周りでは評判が悪く、「もしかして誰も好きじゃない?」と悲しい思いでいました。僕だけrailsプロジェクトでcoffeescriptを書き続けてたら周囲の迷惑になっちゃうので書かなくなりました。

coffeescriptみたいな書き味でgoみたいに1バイナリにコンパイルできる言語があったらいいなぁと思ってたのでAIの力を借りて作ってみた次第です。

一応、自分でも小さいツールやwebアプリ、小さめのGUIアプリなんかを書くのに使えているので興味がある方がいらっしゃったら使ってみていただけるとありがたいです。感想などをいただけるとさらにありがたいです。

簡単に自撮り動画を撮って、そのままDiscordやSlackに貼るための小さいアプリを作った。

mugvideo

mugvideo

何これ

Web会議ではなく、チャットにちょっとした動画を貼りたい時用のアプリ。

録画ボタンを押すとカメラとマイクでMP4を録画して、停止すると保存した動画ファイルそのものをクリップボードに入れる。あとはDiscordやSlackにペーストすればアップロードできる。

ファイル選択ダイアログを開いて、動画の保存先を探して、添付して……みたいなのが毎回ダリィので、

「撮る → 止める → 貼る」

だけにしたかった。

インストール

OmarchyなどのArch Linux系ならAURから入る。

yay -S mugvideo-git

Arch系以外は下記。 curl -fsSL https://raw.githubusercontent.com/komagata/mugvideo/main/install.sh | sh

モチベーション

リモートワークで、ちょっとした内容なんだけどテキストだけだと説明が難しいとか、感情が伝わりずらい事がよくある。テキストだとな〜んか感じ悪い表現になっちゃうとか。そういう場合に動画は有用だと思うけど、ハドルみたいに同期コミュニケーションは重過ぎたり、大勢に一度に伝えたい場合とかに自撮り動画って便利だなと思ってちょくちょくやってた。それを手軽にするために作りました。

自分用の小さいツールだけど、こういう「毎回ちょっと面倒」みたいなやつを雑に作ってすぐ使えるのはLinuxデスクトップの楽しいところだと思う。

しばらく使ってみて、録画サイズや保存先周りで不便が出たら直していく。

Hyprland上でMarkdownをサッと見るためのアプリ、mark-previewを作った。

mark-preview

OmarchyでMarkdownファイルを見るとき、これまではObsidianで開いてたんだけど、もっとシンプルに確認したかったのでpreview専用でhyperlandにマッチする装飾の少ないやつを作りました。

シンプルにした

Hyprlandの世界観に合うようにメニューバーなしのほぼ全画面ビュー。ステータスバーに開いてるファイルパスがちらっと出るだけ。操作はキーボードショートカット(Ctrl+O / Ctrl+R / Ctrl+W / Ctrl+Q)でやる。スクロールバーもNautilus風にホバーで薄く出る感じにした。

編集は別アプリでやる

mark-preview自体には編集機能がない。Neovimでなどの別アプリで編集する。元ファイイルの変更を監視してリアルタイムにプレビューする。

各OSで自然な見た目になる

wxWidgetsを使ってるのでOS毎のネイティブな見た目になる。Electronとかは重いので使わなかった。

Arch / Omarchyなら簡単インストール

AURに登録したので、

yay -S mark-preview-git

で入る。/usr/bin/mark-previewにバイナリが入って、.desktopファイルも一緒に入るのでwalkerからも起動できるし、.mdファイルを右クリックして「他のアプリで開く」にも出てくる。

omarchy-coding-agent-launcher running multiple coding agents in tmux

Claude Code用に作っていたomarchy向けのプロジェクトランチャーを、特定のコーディングエージェントに依存しない形に作り直しました。

omarchy-coding-agent-launcher

以前の名前は omarchy-claude-launcher でしたが、今はClaude Codeだけではなく、Codex、Gemini CLI、OpenCodeも扱えるので、新しい名前でリリースし直しました。

Claude Code専用ではなくなった

最初に作ったときは、Claude CodeをOpenClawっぽく使いたい、というかなり個人的な動機でした。

Super+I を押すとwalkerのポップアップが出て、プロジェクトを選ぶと、そのプロジェクト用のClaude Codeがtmuxの中で開く。複数プロジェクトを行き来しても、ターミナルが散らからない。そういうものです。

ただ、Claude Codeが週のLimitに達して数日使えなくなって発狂してCodexやGemini CLIでも全く同じように使えるようにしました。

プロジェクトごとにエージェントを選べる

プロジェクトごとにコーディングエージェントを切り替えられるので、1画面に9個立ち上げて、5個がClaude Code、3個がCodex、2個がGeminiみたいな使い方ができます。(というかCodexも頻繁にリミットに行くので仕方なくそうなっている・・・)

グローバルのデフォルトは環境変数で指定できます。

export CODING_AGENT_LAUNCHER_AGENT=codex

さらに、プロジェクトの中に .agents/agent を置くと、そのプロジェクトだけ別のエージェントを使えます。

claude

とか、

gemini

みたいに書くだけです。

ランチャーのメニューにも + Set project agent... を追加したので、ファイルを手で作らなくても、walker上でプロジェクトを選んで claude / codex / gemini / opencode を選べます。

インストール

omarchy / Hyprland向けです。walker, hyprctl, tmux と、使いたいコーディングエージェントのCLIが必要です。

git clone https://github.com/komagata/omarchy-coding-agent-launcher.git
cd omarchy-coding-agent-launcher
./install.sh
hyprctl reload

詳しくはREADMEを見てください。

まとめ

最初は「Claude Codeを複数プロジェクトで使いやすくするための個人用ランチャー」でしたが、今は「どのコーディングエージェントを使うかをプロジェクト単位で切り替えるランチャー」になりました。

Claude Code、Codex、Gemini CLI、OpenCodeを同じ操作感で扱えて、プロジェクトごとに向き不向きを選べるのが良いところです。

最悪でもOpenCodeで無料のローカルLLMを使えるので発狂は防げますが、Qwenとかじゃあまり満足できないのでイライラはするかも。

前回の記事で紹介したomarchy-claude-launcherをアップデートした。

一番大きい変更は、プロジェクトの管理がtmuxの「ウィンドウ(タブ)」から「ペイン(分割画面)」に変わったこと。

Image from Gyazo

全エージェントを同時に見る

前のバージョンは1プロジェクト=1タブで、Alt+1Alt+9で切り替えてた。

これはこれで良かったんだけど、Claude Codeを4つ5つ並行して走らせてると一覧したくなる。タブだと表示されるのは常に1つだけで、他は見えない。

Claude Squadみたいに分割画面で全部見たいなと思って、ペインベースに作り直した。

今は全プロジェクトが1つのtmuxウィンドウ内のペインとして並ぶ。select-layout tiledで自動的にグリッド状に配置されて、4個なら2×2、6個なら2×3になる。Ctrl+Space zで1つにズームして集中、もう一回押して全体に戻る、という使い方。

ペインのボーダーにプロジェクト名が表示されるようにした。tmuxの@projというユーザー独自オプションに名前を入れることで、claude等のTUIアプリがエスケープシーケンスでタイトルを上書きしてくる問題を回避してる。ボーダーはheavyにして見やすく。

その他の変更

他にもちょこちょこ追加した:

  • ghostty対応: 前回はNVIDIA+mesa問題でalacrittyしか使えなかったけど、ghostty 1.3.1で解消。--titleベースのウィンドウ識別に変更
  • 稼働状態インジケーター: walkerの一覧で(ツール実行中)、(入力待ち)が表示される。pstreeでプロセスツリーを見てclaude配下にbashが生えてたら作業中、という判定
  • 名前を打つだけでプロジェクト作成: 一覧にない名前を入力すると自動でディレクトリを作ってclaudeを起動。CLAUDE_LAUNCHER_DEFAULT_NSを設定しておけばchatと打つだけで~/Works/komagata/chat/ができる
  • git worktree管理: walkerから親リポジトリを選んでworktree名を入れるだけ。docker compose連携で.env.localの自動生成やポートの自動割り当てもやる
  • 削除機能: 不要になったプロジェクトやworktreeをwalkerから選んで削除。tmuxのペインkill→ファイル削除まで一発
  • CLAUDE_LAUNCHER_CLAUDE_ARGS: --dangerously-skip-permissionsみたいな引数を環境変数で渡せるようにした

感想

ペインベースにしてから明らかに並行作業の見通しが良くなった。5個のclaudeが同時に動いてるのを眺めながら、止まったやつに指示を出して、また全体を見る、という流れがスムーズ。

tmuxのtiled layoutが地味に賢くて、ペインの増減に合わせて勝手にいい感じに再配置してくれるのがありがたい。

git worktreeで同じサーバーアプリをを複数チェックアウトして並行で動かそうとするとポートが衝突してだるい。

「3000〜3100の範囲で最初に空いてるポートを返す」を1ライナーで書くと下記、

$ comm -23 <(seq 3000 3100) <(ss -tlnH | awk -F: '{print $NF+0}' | sort -un) | head -1
3000

rubyのメソッドとして書くと下記、

require 'socket'

def find_free_port(range = 3000..3100)
  range.find { |p| (TCPServer.new(p).close; true) rescue false }
end

localhostへのbindはちょっぱやで100個見ても数msしかかからないらしいので気軽に探せる。

worktreeに適用する場合は、空いてるポートを環境変数に設定しつつworktreeを作って、アプリ側ではそれを見て起動ポートを決めればいい。