ある日、どら焼きを食べてるAIに「Ruby用のめちゃくちゃ早い型チェッカーつくって〜」と泣きついたらできました。
crema
クレマです。ロゴもAIが作ってくれました。めちゃくちゃローカル環境に依存するAI-agent中心の作り方をしているので、開発repoはprivateに、コードはpublicにする方法を実験的にやってみています。
特徴
README.mdに「cremaの特徴を書いて〜」と言ったら書いてくれました。
AI-agent first
AI-agentによる。AI-agentのための型チェッカーを目指しています。人間にとって使いやすいかという視点は捨てています。 もはやコードを書くのはAI-agentだけです。その世界では、当然型チェッカーを使うのもAI-agentなはずです。
Ultra-fast
100% Rustで実装。とにかくCLIでの利用が早くなるように作りました。かわりにLSP的な用途は捨てています。MCP Serverも今のところ考えていません。後から実装できなくもないけど、優先度としては下げています。 エディターからの利用は捨てているので補完やコードジャンプのような、LSP的な機能を捨てています。この型から使えるメソッド一覧はパッと出せません。 開発のしやすさから、シングルプロセス・シングルスレッドで一旦やってます。これから増えるかもしれない。 速さを語るには機能がなくて何もしてないからで説明できちゃう気もしますが、それでも結構早いと思います。遅くなる機能は落とす気持ちで、パフォーマンス重視です。
ruby/rbs repoで試していて、わたしのPCでは0.3s台キープを基準にしています。が、機能を足すごとに地味に重くなってきて、その度にAIに「早くして〜」と泣きついています。
Inline RBS by default
Inlineの流れが来ると信じて、デフォルトでRubyコード内の型アノテーションコメントを見に行きます。 token的な距離が近い方がAI-agentが読みやすいはずとAI-agentが言っていたので、そうしています。 これまでRBS生成をがんばってきたので、逆張りもやってみたい気持ちもあります。
UNIX-composable
人間が見てわかりやすい情報と、AI-agentが見てわかりやすい情報は違うと信じて、現在JSONLフォーマットしか出力できません。JSONLはjq,head,grepなどと組み合わせて、絞り込みや集計まで幅広く対応できます。明示的に構造化されているので、人間には微妙でもAI-agent的には読みやすいはずです。現に開発中でもJSONLフォーマットの診断を貼り付けるだけで問題箇所を見に行ったり集計したりしているので手応えはあります。
先生
AI-agent
AI-agentはとにかくいろんなことを知っています。「AI-agentの助けがあれば、型とか何もわからないわたしでも型チェッカー作れるのでは?」と思い立って実際作ってくれました。さまざまな型チェッカーの特徴の比較や、基礎となる理論、基本用語など様々なことを教えてくれます。
わたしはRustも全く書いたことがありません。このcremaを書き出してから少しずつRustを学んでいます。ソラで書いたことはありません。
rbs/steep
rbsはRustのparserをcrateとして公開しているので、これをそのまま使っています。parser以降のASTや型環境の実装は、Ruby実装をportしてくれ〜といって実装してます。型チェッカーとしての正しい振る舞いもよくわかっていないので、Steepの挙動をマネしてくれ〜いつも言っています。実装・挙動としての先生がいることで、何をどう実装していけばいいのか手取り足取り教わって実装できました。
機能
基本的にSteepキッズとして実装しているのですが、まだまだ機能が足りずRailsアプリでどうこうは難しいかも。でも定数のtypoぐらいなら見つけれるんじゃないかなと思っています。
rbs collection
サポートできているはずですが、.lock.yamlを生成する機能はないのでrbs collection installで作ってください。
config file
crema.tomlを作れるようになっています。
以下の設定で、定数のtypoチェッカーとして動くと思います。 diagnostic名もSteepのものと同じなので意味の再説明を省いています。
[diagnostic] preset = "all_ignore" "Ruby::UnknownConstant" = "error"
narrowing
ちょっとずつ実装しています。基本的に環境のHashを分岐ごとに複製して、分岐が終わったらjoinする。らしいです。
試し方
git cloneしてcargo install --path .です。
たのしい
オレオレ自作型チェッカーたのしい。

