
階層構造の.mdファイルを統合するCLIツールを1時間で爆速開発してnpm公開する
こんにちは、リテールアプリ共創部の戸田駿太です。
今回は、複数のMarkdownファイルを一つにまとめるCLIツール「md-concatter」の開発と公開までの流れをご紹介します。
このツールは生成AIによって1時間で作成しました。
開発したツール
複数の階層構造に配置されたMarkdownファイルを一つのファイルにまとめるCLIツール「md-concatter」を開発しました。
生成AIに複数フォルダにまたがるMarkdownファイルを送信する際に手間だったので作成しました。
ユースケース
- AIに一括で資料を送信: プロジェクトの複数のREADMEや仕様書を一つにまとめてChatGPTやClaudeに送信
- ドキュメントレビュー: 散らばったマークダウンファイルを統合してレビュー用資料を作成
- プロジェクトアーカイブ: 開発完了時に全ドキュメントを一つのファイルに保存
仕様書作成まで
まず要件仕様書の作成から着手します。
AIでコーディングするために一番大事な部分かもしれません。
AIとの壁打ち
最初のアイデアは自分で考え、それを元にどのようなツールに仕上げるか壁打ちをしてまとめていきました。
このツールによって本当に解決したい課題と、既存のツールで実現できないのかを確認することでこのツールの価値を判断します。
また、この時点である程度の技術要件もまとめました。
壁打ち内容
md-concatter ツール開発 会話履歴まとめ
1. 初期アイデア提示
ユーザー: ツールの壁打ち依頼
- 階層構造の.mdファイルを一つにまとめるツール
- 指定フォルダ配下の全mdファイルを参照
- 各mdの間にdivider(---)とファイル名・パス情報
- npxで実行可能
アシスタント: 基本機能と技術的検討点を整理
- ファイル探索方法の選択肢提示
- 出力形式の代替案提案
- CLI設計案
- エラーハンドリング項目
- 追加機能の可能性
2. CLIフレームワーク選定
ユーザー: 相性の良いCLIフレームワークの相談
アシスタント: 3つのフレームワークを比較提示
- Commander.js (最推奨) - 軽量で学習コスト低
- Yargs - 柔軟な設定、強力なバリデーション
- CAC - 非常に軽量(2KB)、モダン設計
推奨理由: Commander.jsのシンプルさと安定性
3. 技術要件の確認
ユーザー: Commander.js採用決定、他の技術要件確認
アシスタント: 必須技術要件を整理
- Node.js Core Modules (fs, path)
- ファイル探索ライブラリ選択肢 (glob推奨)
- package.json設定
- エラーハンドリング要件
- 追加検討事項 (文字エンコーディング、大容量ファイル対応等)
4. 要件の段階的まとめ
ユーザー: 要件のまとめ依頼
アシスタント: 簡潔な技術要件まとめを提示
- 基本仕様、技術スタック、CLI仕様、出力フォーマット
- エラーハンドリング、package.json設定、ファイル構成
ユーザー: 全要件のまとめ依頼
アシスタント: 完全仕様書を作成
- 10項目の詳細仕様 (基本仕様〜将来拡張予定)
- 具体的な制限値、エラー処理、品質要件まで網羅
5. 競合調査
ユーザー: 類似ツールの存在確認
アシスタント: 既存ツール調査結果
- 5つの類似ツール分析 (markdown-include, mdmerge, mdbook等)
- 比較表で差別化ポイント明確化
- 結論: 作成価値あり (シンプルさとnpx対応が差別化要因)
6. ネーミング検討
ユーザー: ツール名の相談
アシスタント: 14個の名前候補を4カテゴリで提示
- シンプル系: md-concat, mdmerge, md-combine
- 階層表現系: md-tree, md-flatten, folder-md
- 機能表現系: md-gather, md-bundle, md-stitch
- ユニーク系: md-weave, markmerge, docweaver
TOP3推奨: md-concat, md-tree, md-weave
7. ネーミングの詳細検討
ユーザー: md-concaterの提案
アシスタント: 詳細分析
- 良い点:明確性、一般的パターン、検索性
- 気になる点:語感、長さ
- 代替案との比較表
判定: 良い選択と評価
8. スペリング修正
ユーザー: concatterが正しいスペリングか確認
アシスタント: 語源的分析
- concatter が正しい (concatenate → concatter)
- 類似例での確認 (formatter, submitter等)
- 最終推奨:md-concatter
9. 壁打ち内容のまとめ
ユーザー: 壁打ち内容のまとめ依頼
アシスタント: プロジェクト概要として整理
- 技術仕様、競合分析、機能要件、開発方針を簡潔にまとめ
10. 会話履歴の記録
ユーザー: 会話の履歴通りのまとめと会話方法の記録依頼
アシスタント: この文書 (会話の流れを時系列で整理)
会話の特徴・方法論
効果的だった進行方法
- 段階的詳細化: 大枠→詳細→完全仕様の順で深掘り
- 選択肢提示: 複数案を比較表で整理
- 具体例重視: コード例、コマンド例を多用
- 競合分析: 既存ソリューションとの差別化を明確化
- 反復確認: 各段階で要件を再整理・確認
意思決定プロセス
- 技術選択 → 要件定義 → 競合調査 → ネーミング → 最終仕様
- 各段階で複数選択肢を提示し、ユーザーの判断を仰ぐ方式
⚠️ 壁打ちで注意したこと
- 必ずツールの必要性を相談すること
- やりたいことが本当に役立つのか
- 他のツールで代用できないか
- メリット・デメリット
- 自分以外も使うことを考慮した仕様にする
- 技術要件の確認
- まず自分が実装したいルールを伝える(npxで実行できるようにしたいなど)
- ここは曖昧でもいい、でも気づいたことや悩むところは全部AIに伝えるようにする
- そうすることでAIがより良い提案をしてくれる
- ここは曖昧でもいい、でも気づいたことや悩むところは全部AIに伝えるようにする
- 必要になるライブラリを確認する
- この際に提案されたライブラリを検索して現在の開発状況を確認する
- AIの場合、古いライブラリを提案することがあるので注意
- 代替となるライブラリも検索する
- ライブラリでミスると後で運用や開発が大変になるので割と慎重に
- この際に提案されたライブラリを検索して現在の開発状況を確認する
- そのほかの要件も確認する
- まず自分が実装したいルールを伝える(npxで実行できるようにしたいなど)
- ツールのネーミング
- プロジェクトのディレクトリやツール名を決める
- ネーミングは非常に大事で、わかりやすい名前にするのが無難(md-concatterはビミョーかも...)
要件仕様書の作成
壁打ちできたら要件仕様書を作成してもらいます。
既に壁打ちで決まっていることをまとめてもらうだけなので、あまり手直しはしていません。
md-concatter ツール 要件仕様書
# md-concatter ツール 要件仕様書
## 1. 基本仕様
### **機能概要**
- 階層構造の`.md`ファイルを一つにまとめるCLIツール
- 指定フォルダ配下の全`.md`ファイルを再帰的に検索・統合
- `npx`で実行可能
### **出力フォーマット**
```markdown
aaa/aaa.md
aaa.mdの内容
---
aaa/bbb.md
bbb.mdの内容
---
2. 技術スタック
依存関係
{
"dependencies": {
"commander": "^11.0.0",
"glob": "^10.0.0"
}
}
Node.js標準モジュール
fs/promises
: ファイル読み書きpath
: パス操作(クロスプラットフォーム対応)
Node.jsバージョン要件
>=14.0.0
3. CLI仕様
基本コマンド
npx md-concatter <directory> [options]
オプション
Options:
-o, --output <file> 出力ファイル名 (default: "merged.md")
-d, --max-depth <number> 最大階層数 (default: 10)
--exclude <patterns...> 除外パターン
-h, --help ヘルプ表示
-V, --version バージョン表示
使用例
# 基本使用
npx md-concatter ./docs
# オプション指定
npx md-concatter ./docs -o output.md -d 5 --exclude "*.tmp.md" "draft/**"
4. プロジェクト構成
ディレクトリ構造
md-merger/
├── bin/
│ └── cli.js # CLIエントリーポイント
├── lib/
│ └── merger.js # メイン処理ロジック
├── package.json
├── README.md
└── .gitignore
5. 機能要件
ファイル処理
.md
ファイルのみを対象- UTF-8エンコーディング前提
- 最大階層制限(デフォルト10階層)
- ファイル順序:アルファベット順
除外機能
- 特定ファイル/フォルダの除外対応
- glob パターン対応
- デフォルト除外:
node_modules/
,.git/
出力制御
- 出力ファイル名指定可能
- 既存ファイル上書き確認
- 標準出力への出力対応
6. エラーハンドリング
必須エラー処理
- 指定ディレクトリの存在チェック
- ファイル読み取り権限確認
- 出力先書き込み権限確認
- 不正なファイル形式の処理
- メモリ不足対応
- 循環参照(シンボリックリンク)対応
7. 性能要件
処理方式
- 小〜中規模ファイル想定(全読み込み方式)
制限事項
- 単一ファイル最大サイズ:10MB
- 総ファイル数制限:1000ファイル
- 総出力サイズ制限:100MB
8. 品質要件
テスト要件
- 単体テスト(Jest)
- 統合テスト
- エラーケーステスト
コード品質
- ESLint対応
- 可読性重視
- 適切なコメント
9. 配布要件
npm公開
- npmパッケージとして公開
npx
での実行対応- セマンティックバージョニング
ドキュメント
- README.md(使用方法、例)
- CHANGELOG.md
- ライセンス(MIT)
開発プロセス
ここからは開発の流れをご紹介します。
実装とドキュメント作成は全てCursorで行いました。
今回は一切コードを修正していません。
ドキュメントもほとんど手直し無しです。
Cursorでの依頼・質問の履歴
ざっと以下のような依頼と質問を繰り返して開発を進めていきました。
実装以外のnpm, Github公開は手動でも良かったのですが、スピードを上げるためにAIにやってもらいました。
少しだけ手直しとブログを作成するための依頼もしています。
- プロジェクト作成依頼: 完全要件仕様書に基づくツール作成
- 開発用スクリプト追加:
package.json
のscriptsセクション拡充 - 実装確認依頼: 実装内容とREADMEの整合性確認
- npm公開方法の質問: npm公開手順の確認
- GitHub経由での公開希望: GitHubリポジトリ経由での公開
- GitHub公開完了報告: リポジトリ公開の完了報告
- GitHubリポジトリURL提供: https://github.com/ShuntaToda/md-concatter
- チャット履歴保存依頼: 開発履歴の記録
- 質問履歴記録依頼: 全質問内容の整理
Cursorでの実装の流れ
Cursorでの実装の流れのまとめ
1. 要件仕様書の提供
要件仕様書に基づいてプロジェクトを開始:
- 基本仕様: 階層構造のマークダウンファイル統合
- 技術スタック: Node.js, commander, glob
- CLI仕様:
npx md-concatter <directory> [options]
- 出力フォーマット: 相対パス + 内容 + 区切り線
2. プロジェクト構造の作成
md-concatter/
├── bin/
│ └── cli.js # CLIエントリーポイント
├── lib/
│ └── merger.js # メイン処理ロジック
├── package.json
├── README.md
├── .gitignore
└── .npmignore
3. 実装したファイル
package.json
{
"name": "md-concatter",
"version": "1.0.0",
"description": "Merge markdown files in directory structure",
"bin": {
"md-concatter": "./bin/cli.js"
},
"engines": {
"node": ">=14.0.0"
},
"dependencies": {
"commander": "^11.0.0",
"glob": "^10.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ShuntaToda/md-concatter.git"
}
}
bin/cli.js
- commanderを使用したCLIインターフェース
- オプション処理:output, max-depth, exclude
- エラーハンドリング
lib/merger.js
- マークダウンファイルの検索・統合ロジック
- glob パターンによるファイル検索
- ファイルサイズ制限(10MB)
- デフォルト除外パターン
- アルファベット順ソート
4. 機能実装
主要機能:
- 再帰的ファイル検索
- ファイル除外パターン(glob対応)
- 最大階層制限
- ファイルサイズ制限
- エラーハンドリング
CLIオプション:
-o, --output <file>
: 出力ファイル名-d, --max-depth <number>
: 最大階層数--exclude <patterns...>
: 除外パターン-h, --help
: ヘルプ-V, --version
: バージョン
5. 開発用スクリプトの追加
"scripts": {
"test": "jest",
"start": "node bin/cli.js",
"dev": "node bin/cli.js test-docs",
"dev:custom": "node bin/cli.js test-docs -o dev-output.md",
"test:local": "node bin/cli.js test-docs && echo 'テスト実行完了: merged.mdを確認してください'",
"clean": "rm -f merged.md dev-output.md custom-output.md excluded-test.md"
}
6. テスト環境の構築
テスト用ディレクトリ構造:
test-docs/
├── README.md
├── aaa/
│ └── aaa.md
├── bbb/
│ └── bbb.md
└── draft.md
テスト実行結果:
- 基本統合機能 ✅
- 出力ファイル名指定 ✅
- 除外パターン ✅
- ヘルプメッセージ ✅
- 正しい出力フォーマット ✅
7. ドキュメント作成
README.md の内容:
- 特徴説明
- インストール方法
- 使用方法とオプション
- 使用例
- 制限事項
- エラーハンドリング
- 開発用スクリプト
8. 実装とREADMEの整合性確認
確認項目:
- package.json の設定 ✅
- CLI機能 ✅
- 出力フォーマット ✅
- 機能実装 ✅
- デフォルト除外パターン ✅
- エラーハンドリング ✅
9. GitHub公開
手順:
git init
でリポジトリ初期化git add .
で全ファイル追加git commit
で初回コミット- GitHubでリポジトリ作成
git remote add origin
でリモート追加git push
でコード公開
GitHubリポジトリ: https://github.com/ShuntaToda/md-concatter
10. npm公開
準備作業:
.npmignore
ファイル作成- package.json にリポジトリ情報追加
- 作者情報の設定
公開実行:
npm publish
公開結果:
- パッケージ名:
md-concatter
- バージョン:
1.0.0
- サイズ: 3.5 kB(圧縮時)
- 公開成功 ✅
細かく説明すると長くなるので、大まかな流れと注意したポイントを解説します。
1. 要件仕様書の提供
壁打ちで作成した要件仕様書をプロンプトにして「これを作成して」と依頼します。
特に考えることは無しです。
2. プロジェクト構造の作成
ここから実装に移ります。
プロジェクト構造は大事ですが既に仕様書に記載してあるので少し確認をしてAcceptします。
3. 実装の確認
次はコーディングに移ります。
今回は0→1開発のためロジックはあまり気にせずに重要な部分のみちゃんと目を通します。
例えば、package.jsonの設定やCLIのオプションなどです。
4. 機能実装
ロジックの実装ではほとんど内容を確認せずに全部Acceptです!
コードすら見てないので、コードの質問はしていません。
アーキテクチャを考えると本当はもっと質問をして修正をした方がいいです。
今回は小さなツールなので、そこまで気にしなくても良いかなと思います。
5. 開発用スクリプトの追加
実装の確認などをAIが行ってくれていたのですが、コマンドがわかりづらいと思いました。
そこで開発用のスクリプトの依頼をすることで自分で最終確認する際に楽になります。
6. テスト環境の構築
AIがテストを行うためにテスト用ディレクトリを作成し始めました。
僕自身は必要無さそうと感じましたが、.gitignoreにテスト用ディレクトリを指定していたのでAIの意見を尊重してAcceptしました。
7. ドキュメント作成
ここまでで実装が全て終わったのでドキュメントを作成してもらいます。
README.mdはこのツールを知る上で一番正確な情報源なのでしっかりと確認します。
8. 実装とREADMEの整合性確認
目でも確認しましたが、実装とREADMEの内容が一致しているかを改めてAIに確認してもらいます。
たぶんOKです。
9. GitHub公開
ここまでの実装をGitHubに公開してもらいます。
手動でもできますが、そのままの流れで任せました。
10. npm公開
npm公開はあまりやったことがなかったので、完全にAIの言いなりで公開しました。
最終的に公開できたので良かったです。
最終成果物
利用可能なコマンド
# グローバルインストール
npm install -g md-concatter
# 直接実行(推奨)
npx md-concatter <directory>
# 基本的な使用例
npx md-concatter ./docs
npx md-concatter ./docs -o documentation.md
npx md-concatter ./docs -d 5
npx md-concatter ./docs --exclude "*.tmp.md" "draft/**"
npx md-concatter ./docs -o output.md -d 5 --exclude "*.tmp.md" "draft/**"
実際の使用例
ドキュメント統合の例
# プロジェクトの全ドキュメントを統合
npx md-concatter ./docs -o project-documentation.md
# ドラフトファイルを除外してドキュメント作成
npx md-concatter ./docs --exclude "draft/**" "*.draft.md" -o final-docs.md
# 特定の深さまでのファイルのみ統合
npx md-concatter ./docs -d 3 -o summary.md
出力例
README.md
# プロジェクト名
プロジェクトの説明...
---
docs/installation.md
## インストール方法
インストール手順...
---
docs/api/overview.md
## API概要
API仕様の説明...
---
プロジェクトリンク
- npmパッケージ: https://www.npmjs.com/package/md-concatter
- GitHubリポジトリ: https://github.com/ShuntaToda/md-concatter
技術仕様
対応環境:
- Node.js >= 14.0.0
依存関係:
- commander: ^11.0.0 (CLIインターフェース)
- glob: ^10.0.0 (ファイル検索)
制限事項:
- 単一ファイル最大サイズ: 10MB
- UTF-8エンコーディング前提
- 最大階層数制限: 10階層(デフォルト)
- 総ファイル数制限: 1000ファイル
- 総出力サイズ制限: 100MB
デフォルト除外パターン:
node_modules/**
.git/**
.gitignore
**/*.tmp.md
パッケージ情報:
- サイズ: 8.72 kB (unpacked)
- ファイル数: 4
- ライセンス: MIT
- 最新バージョン: 1.0.0
開発時間
要件仕様の壁打ちから npm 公開まで、約1時間で完了!
今回は特にスピードを意識した開発でした。
ツールは何個か作ったことがありますが、だんだんとAIに任せる部分とそうでない部分がわかってきたように思えます。
確認ポイントまとめ
🤝 壁打ち段階での確認
- ツールの必要性: 本当に役立つのか、他のツールで代用できないかを必ず相談
- 技術要件: 曖昧でも気づいた要件は全てAIに伝える(npx実行可能など)
- ライブラリ選定: 提案されたライブラリの現在の開発状況を手動確認(古いライブラリ注意)
- ネーミング: わかりやすい名前選定(md-concatterは微妙だった反省点)
💻 実装段階での確認
- プロジェクト構造: 仕様書通りか軽く確認してAccept
- 重要設定ファイル: package.json、CLIオプションなど重要部分のみ目を通す
- ロジック実装: 小さなツールならコード詳細は見ずにAccept可能
- 開発用スクリプト: 自分での最終確認を楽にするため追加依頼
- README: ツールの正確な情報源として内容をしっかり確認
📦 公開段階での確認
- 実装整合性: AIに実装とドキュメントの一致を再確認依頼
- GitHub公開: 手動可能だがスピード重視ならAIに任せる
- npm公開: 経験少ない場合は完全にAIに従う
⚖️ AIに任せる判断基準
- 任せる: ロジック実装、ドキュメント作成、公開作業
- 確認必須: 設定ファイル、外部ライブラリ、プロジェクト要件、ネーミング
今後の拡張可能性
- 目次の自動生成
- 設定ファイル対応(
.md-concatter.json
) - プレビューモード
- ストリーミング処理(大容量対応)
- 多言語対応
おわりに
今回はCursorでの爆速開発の流れを紹介しました。
コツを掴めば便利なツールが短時間で作れるようになります。
また、非技術者でもアプリを作りたい際に参考になると思うので、ぜひ試してみてください。
参考