構造を理解した AI ファーストな差分ツール「diffx」を、Claude Code と Rust で作ってリリースしました
―― ケツカンマで消耗するのは、もうやめよう ――
プログラミング中に JSON
、YAML
などの設定ファイルを git diff
で確認するとき、もどかしさを感じたことはありませんか!?
キーの順番が変わっただけなのに、大量の差分と判定されたり。
たかがインデントの変更! ケツカンマ!
従来の diff
ツールはテキストを行単位で比較するため、データの「構造」までは理解してくれません。
小さなストレス。されど、毎日積もる。
「もっと賢く、構造を理解した diff
ツールが欲しい!」
……と思ったときには、すでに行動は終わっていたんだ! 怒り駆動開発!
diffx
とは:構造化データのための差分ツール
diffx
は、JSON
, YAML
, TOML
, XML
, INI
, CSV
といった構造化データに特化した差分ツールであり、Rust 製 CLI です。
1 番の特徴は、データの構造的な意味を理解して差分を表示する点です。
例えば、よくある設定ファイルの変更を見てみましょう。
変更前の config_v1.json
{
"version": "1.0.0",
"server": {
"port": 8080
},
"features": ["auth", "logging"]
}
変更後の config_v2.json
{
"version": "1.0.1",
"server": {
"port": 8081,
"host": "localhost"
},
"features": ["auth", "logging", "cache"]
}
これを git diff
で見ると、差分が出まくりで、変更箇所が分かりにくい! 目が滑る!
一方、diffx
を使うと、差分が次のように出力されます。
$ diffx config_v1.json config_v2.json
~ version: "1.0.0" -> "1.0.1"
~ server.port: 8080 -> 8081
+ server.host: "localhost"
+ features[2]: "cache"
~
は値の変更、+
は追加を表します。
ユニバーサルデザインな色もつくので、色覚特性を持つ方にも直感的!
このように、「どのキーがどう変わったのか?」、「どの配列に何が追加されたのか?」などが、パス形式で直感的に理解できます。
diffx 形式と名づけた! いま!
Tool | Type | Formats | Semantic Aware | Array Tracking | Config Support | Best For |
---|---|---|---|---|---|---|
diffx | Semantic | JSON/YAML/TOML/XML/INI/CSV | ✅ | ✅ | ✅ | Structured data comparison |
diff | Text-based | Any text | ❌ | ❌ | ❌ | General text files |
jq | JSON processor | JSON | Partial | ❌ | ❌ | JSON manipulation |
yq | YAML processor | YAML/JSON | Partial | ❌ | ❌ | YAML manipulation |
daff | Tabular | CSV | ✅ | ❌ | ❌ | CSV/spreadsheet data |
jsondiff | JSON diff | JSON | ✅ | Partial | ❌ | JSON-only comparison |
deep-diff | JavaScript | JSON/Objects | ✅ | ❌ | ❌ | JavaScript applications |
未来に通用する?設計思想
単なる差分ツールで終わらないよう、無限の可能性を込めました。
AI
ファーストな設計
1. diffx
の出力形式は、人間が読みやすいだけでなく、AI
が解釈しやすいように設計しました。
AI
エージェントが diffx
を使えば、「この設定変更の要点をまとめて」といった指示をこなせるようになります。
AI
エージェントが「diffx
を入れてもらえませんか?」って、人間にお願いしてくる未来が目標です。
さらに面白いのが、diffx
の出力を JSON
や YAML
形式にし、それを再び diffx
で比較する「セルフチェイン」というメタ概念です。
これにより、「差分の差分」を取ることができ、設定変更の履歴を追跡したり、構成ファイル群の試作を複数管理したり、応用の可能性が大きく広がるはずです。
いろんなアイデアを思いついてほしいです。
私は lawkit
という Rust
製 CLI も作っているのですが、
その出力も YAML
とかなので、diffx
の出番がさっそく来てくれて、シェルスクリプト内で強力なチェインを構成できています。
lawkit
は、ベンフォードの法則などの自然法則を活用して、会計資料や実験エビデンスなどの改ざんを検出するツールです。
ほか、まだ未リリースですけど
AI
関連の静的ファイル同士を比較(テンソル形状比較とか、重み統計比較とか……)する diffai
という Rust
製 CLI も鋭意開発中です。
その出力も YAML
形式とかなので、さらにチェインのネタが増える予定です。
遊戯王の墓守デッキみたいに、チェインが終わらない!
2. シンプルで統一された差分形式
どんなフォーマット同士を比較しても、出力は統一された diffx 形式です。
シンプルなので、学習コストは低いはずです。
3. プログラミングに役立つ便利なオプション
日々のプログラミングで便利な機能を、思いつく限り実装したので、マニアックな用途にも耐えると思います。
-
--ignore-keys-regex
: タイムスタンプなど、無視したいキーを正規表現で除外できます。 -
diffx ./dir1 ./dir2
: 2 つのディレクトリを再帰的に比較できます。 -
--array-id-key
: 配列内のオブジェクトをid
などで識別し、変更を正確に追跡します。 - 巨大ファイルを比較できる、高速モードも用意しました。
企業でのプロのニーズにも、たまたま通用するかもしれません。
通用しなかったら、GitHub
で要望を書いてください。
より多くの環境で使えるように
できるだけ多くの人に使ってもらいたいので Rust
製(クロスプラットフォーム)です。
cargo
で簡単にインストールできます。
$ cargo install diffx
各 OS 用の実行バイナリも、GitHub Releases
からダウンロードできます。
さらに、Python
や Node.js
のプロジェクトでも使えるように、pip
と npm
のラッパーパッケージも作りました。
これらの言語から、シームレスに diffx
の力(超速い)を召喚できます。
ドキュメントの量でなぐる作戦!
個人開発のツールだけど、最初からドキュメントを充実させました。
インストール方法、全オプションの網羅的な解説、様々なユースケースを想定した豊富な使用例など、思いつく限りを載せたので、小学生でも安心して使えるはず!
開発と翻訳には Claude Code
の Pro
プランを使いました。
日本語すら不完全な私でも作れた!
20 ドル/月だと思いこんで、何度も生成し直した結果、20+220 ドルになって怒られたので、読んでもらえるほど救われます!
最後に
diffx
は、とてもシンプルなツールです。もし、差分確認で同じような悩みを持っていた方がいれば、ぜひ試してください。
私自身は、このツールの便利さと、秘めたポテンシャルに、徐々に気づいてきました。
熟練の開発者の皆様方にとっては、どう感じるのかはわかりませんが、「まさに欲しかったやつ!」ってなるほど隠れニーズがあったら嬉しいです。
開発中はずっと、おなかに猫が乗ってました。
GitHub
でスターを付けていただけると、猫が驚いて逃げるでしょう。(私がガッツポーズをとるという意味です)
バグ報告や機能追加の要望など、フィードバックも歓迎します。
最後まで読んでいただき、ありがとうございました。
Discussion
ペットの三毛猫が驚きました。
たくさんのいいねとスターを、ありがとうございます。
まだバージョンアップはしていませんが、
READMEだけ更新し、ドキュメントを中国語に完全対応させました。
結局、Maxプランにしてしまった……うごごご
記事内で予定として書いてた lawkit というRust製CLIが、いま完成しました。
見てください!(シャクティ)
lawkitの実装にも、diffxが使われています。
diffxをコマンドとして呼ぶのでなく、diffx-core のクレートをインポートする方法です。
オブジェクト同士、配列同士の比較が、すごくシンプルに書けて、開発も動作も高速化しました。
「diffx-core、こいつ使える……」
と、夜神月の魅上への初期の印象のように思いました。
フラグでないことを祈ります。
diffxをバージョンアップして、diffっぽく使えるオプションを追加しました。
diff -q 相当: --quiet での高速変更検出
diff --brief 相当: --brief でのファイル名のみ表示
diff -i 相当: --ignore-case での大文字小文字無視
diff -w 相当: --ignore-whitespace での空白無視
diff -C3 相当: --context でのコンテキスト表示
逆に、オプション同士が直交してるかを見直して、UNIX哲学に準拠してない機能を削除しました。
これからも、かゆいところは直していきます。
土日に30時間くらいプログラミングして、やっと基本機能を全部実装し終わった感じです。
(verboseオプションとか……)
Claude Codeに「リリースして」と書くだけで、リリース作業を成功させるためのテクがわかってきました。
可能な限り、
.sh
で処理を実装して、そこで表現できないような指示はrelease-guide.md にでも人間語で書いておき、CLAUDE.mdからリンクしておけばよかったのですね。
このあたりのノウハウも、いま作ってる残り2つをリリースし終わったら書きたいなー。
増えた機能としては、有名なruffを参考に、pip をmaturinでRustバイナリ同梱版にしたこと。
全OSぶんが別whlとしてpypiにホストされるのだけど、使う人は意識しなくても、自分のOS用のが降ってくる。
ほか、npmには全OSぶんのバイナリを同梱し、使う人のOS用のが自動的に使われる。
どっちもメジャーな仕組みで、初めてだけど、Claude Codeに教えてもらえるので、間に合ってしまう。
いつも色んなツールのバージョンアップを見て、
3ケタ目なんて何が変わるねん、充分完成されてるのに……って不思議だったけど
あー、こういうことだったのね、やるネタ尽きないわ……
って、なんかわかった。