Claude を使ったコーディング体験が素晴らしかったので、より簡単に Claude と一緒にコーディングするための Node.js コマンドを作りました。
リポジトリの直下で以下を叩くと repomix-output.txt
というファイルが出来上がります。
$ npx repomix
そのまま Claude に次のようなプロンプトと一緒に送ると、
このファイルはリポジトリのファイルを1つにしたものです。コードのリファクタをしたいのでまずコードを確認してください。
全体の内容を理解した上で、リファクタリングなどを進めることができます。
具体的な内容を提案すると、それに従って良い感じのコードを生成してくれます。Claude だと Artifacts 機能で複数のファイルが出力できるため、依存関係にある複数のコードも一緒に生成できます。
特徴
指定したフォルダ配下のファイル郡を1ファイルにまとめてくれるツールです。
.gitignore
対象やバイナリ系のファイルを無視したり、AIに理解させるための文言を入れたりなど細かいことはやっていますが、以下のようなファイルを出力するだけでやっていることは単純です。
================================================================
REPOMIX OUTPUT FILE
================================================================
// AIに理解してもらうための文言
================
File: src/index.js
================
// ファイルの内容
================
File: src/utils.js
================
// ファイルの内容
Claude 3.5 Sonnet だと、こういった雑な構造でもきちんと理解してくれるので、複数ファイルに跨るリファクタなども難なく対応してくれます。
生成AIのサービスごとに処理できるコンテキスト長は限られているので、小規模なプロジェクトに限られますが、個人開発レベルであれば十分使えるかと思います。(仕事のコードでは使わないでください)
設定ファイルでignore対象を調整できたりするので、詳細は GitHub をご覧いただけると幸いです。
経緯
最近個人で Claude Pro を色々と試しており、Projects の機能で複数ファイル読み込ませてコードを改修させたりしていたのですが、60%~95% ぐらいの精度のコードを生成してくれるので、それを参考にコードを書き換えると割と効率が良いと感じています。
ただ、Projects にフォルダやzipごとアップロードするような機能がなく、Cursor を使うことも考えましたがAPIが従量課金だったりと面倒で躊躇していました。
そんなときにこの記事を見て、丸ごと1ファイルでも十分に理解してくれることに気づき、ツールの作成・公開に至ります。
開発について
大したことをしているわけではないですが、なにかのお役に立てれば幸いです
出力ファイルの内容
出力ファイルの先頭に、このファイルをどう取り扱うかの文章が入っています。
最初はファイルパスと内容だけのシンプルな構造だったのですが、うまく理解してくれないことがあったため、先頭に「ファイルの目的」「フォーマット」「取り扱い方法」「その他の補足」を入れることで、より精度良く理解してくれるようになりました。
また、ファイルごとの区切り線に関しては、ChatGPT の Tokenizer を参考に、トークン数が1になる =
の16個と64個区切るようにしています。
ChatGPT-4o や Claude だとまたトークン数が違ってくるとは思いますが、近しいものにあわせておこうという意図でこうしています。
CLIの実装
コマンドラインツールの作成にはcommander
ライブラリを使用しました。
yargsでも良かったのですが、構文がシンプルで、自動でヘルプを作成してくれる機能が気に入っています。
また、自身のバージョンを取得するのに package.json を見ています。Node.js の古いバージョンでも package.json を適切に読み込ませないといけないので、 import などは使わず fs で直接取っています。そして、ES module だと __dirname
が使えず import.meta.dirname
を使えないバージョンがあったりもするので、少しトリッキーな取り方をしたりもしています。
import * as url from 'url';
const dirName = url.fileURLToPath(new URL('.', import.meta.url));
npmパッケージとしての公開
npmへの公開に関しては、楽に新バージョンを公開できるように以下のscriptをpackage.jsonに入れています。
npm version <major|minor|patch>
が地味に便利ですね。
"npm-publish": "npm run lint && npm run test-coverage && npm run build && npm publish",
"npm-release-patch": "npm version patch && npm run npm-publish",
"npm-release-minor": "npm version minor && npm run npm-publish",
"npm-release-prerelease": "npm version prerelease && npm run npm-publish"
ファイルエンコーディング
このツールではバイナリファイルなどは読み込みたくないので、is-binary-path などでバイナリを無視しつつ、 jschardet, iconv-lite でエンコーディングを適切に処理しています。
ファイルのignore
特定ファイルのignoreに関しては ignore が便利でした。
.gitignore ライクなパターンのフィルタを簡単に実装できます。
function createIgnoreFilter(patterns: string[]): (path: string) => boolean {
const ig = ignore.add(patterns);
return (filePath: string) => !ig.ignores(filePath);
}
まとめ
単純に自分が欲しかっただけのシンプルなツールで、待っていればClaudeにもフォルダやzipのアップロード機能が実装されそうですが、今後も増えていくであろう生成AIサービスで汎用的に使えるものにはなっていると思います。
ぜひ試してフィードバックをいただけると嬉しいです!