miku-grep は、生成AI agent と automation が repository やディレクトリ内で「読むべきファイル」を見つけるための local-first 検索 CLI です。
通常の grep の代わりに、検索結果、summary、diagnostics を JSON として返します。人間が画面で読む検索結果ではなく、次の処理に渡しやすい structured result を得るための tool です。
厳格な CLI / JSON 仕様は docs/miku-grep-cli-spec.md を参照してください。
セキュリティに関する調査結果と対策は docs/miku-grep-security.md を参照してください。
miku-grep は、生成AI agent や script が local repository を読む前に、候補 file を絞り込むために使います。
主な用途:
- file content から読むべき file を探す
- file path から候補を探す
- directory path から候補を探す
- file path、directory path、content を組み合わせて探す
- result JSON の
summaryとdiagnosticsを見て、検索範囲や skipped file を判断する summaryで候補 file を絞ってから、必要に応じてdetailで snippet を読む
miku-grep は semantic search ではありません。embedding search や意味による ranking は行いません。
AI agent が「探す」「候補を絞る」「次に読む file を選ぶ」流れをより自然に扱えるよう、case-insensitive search、file inventory、agent summary、readfile hints、repo root 補助、glob query、encoding preset、簡易 ranking を備えています。現時点ではユーザー数が少ないため、下方互換性よりも agent が扱いやすい request / result shape を優先して設計する方針です。
stdin で request JSON を渡し、stdout から result JSON を受け取ります。
miku-grep < request.json > result.json最小 request 例:
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"search": {
"targets": ["content"]
}
}root が相対 path の場合、CLI process の current working directory から解決されます。既定では指定された root だけを検索します。
subdirectory から実行して repository 全体を検索したい場合は detectGitRoot: true を指定します。result の effectiveRequest.requestedRoot には指定された root、effectiveRequest.root には実際に使った root が返ります。
--version と --help は stdin JSON なしで実行できます。
miku-grep --version
miku-grep --help--help は、生成AI agent や automation が request JSON を組み立てるために必要な stdin / stdout contract、request field、default、result shape、diagnostics、例を stdout に出力します。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "diagnostics"
},
"search": {
"targets": ["content"]
}
}filepath は root からの相対 file path を検索します。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "security"
},
"search": {
"targets": ["filepath"]
}
}{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "docs"
},
"search": {
"targets": ["directory"]
}
}{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "test"
},
"search": {
"targets": ["filepath", "directory"]
}
}{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "encoding"
},
"search": {
"targets": ["filepath", "content"]
}
}include / exclude は glob pattern です。query.type: "regex" は検索語の解釈だけを切り替えます。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "effectiveRequest"
},
"search": {
"targets": ["content"],
"includeFileNamePatterns": ["*.ts", "*.md"],
"excludeDirNamePatterns": [".git", "node_modules", "dist"]
}
}excludeFileNamePatterns と excludeDirNamePatterns が未指定の場合は default exclude preset が使われます。.git、node_modules、target、build、dist、vendor など、通常の検索で読みたくない directory は既定で除外されます。
.gitignore、.ignore、.git/info/exclude は既定で尊重されます。ignore file を無効にして検索したい場合は ignore.mode: "none" を指定します。
注意: ignore file 対応は Git ignore の subset です。!pattern による negation / unignore は対応していますが、escaped leading # / !、character class、brace expansion など一部の pattern は未対応で、該当 pattern は unsupported_ignore_pattern warning diagnostic として報告されます。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"search": {
"targets": ["content"]
},
"ignore": {
"mode": "none"
}
}output 未指定時は summary です。まず候補 file を絞る用途ではこれが既定です。
hit ごとの行、column、matched text が必要な場合は detail を指定します。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"search": {
"targets": ["content"]
},
"output": {
"mode": "detail",
"maxMatches": 200,
"maxMatchesPerFile": 20,
"maxLineLength": 240
}
}match 前後の行も一緒に読みたい場合は、detail mode で context lines を指定します。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"search": {
"targets": ["content"]
},
"output": {
"mode": "detail",
"contextLinesBefore": 2,
"contextLinesAfter": 2
}
}output.contextLines を使うと、前後に同じ行数を指定できます。context lines は content hit の contextBefore / contextAfter として返り、summary mode には載せません。
encoding auto detect は行いません。UTF-8 以外を読む場合は encoding rule を指定します。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "検索語"
},
"search": {
"targets": ["content"],
"includeFileNamePatterns": ["*.txt"]
},
"encoding": {
"default": "utf-8",
"rules": [
{
"fileNamePattern": "*.txt",
"encoding": "shift_jis"
}
],
"onDecodeError": "skip"
}
}読めなかった file、binary と判定された file、size limit を超えた file などは diagnostics に返されます。
{
"version": 1,
"root": ".",
"query": {
"type": "regex",
"text": "Repository(Map|Index)"
},
"search": {
"targets": ["content"]
}
}検索は default では case-sensitive です。大文字小文字を区別せずに検索したい場合は query.case: "insensitive" を指定します。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "repositorymap",
"case": "insensitive"
},
"search": {
"targets": ["content"]
}
}rg --files 相当の file inventory を JSON で返す入口です。
{
"version": 1,
"root": ".",
"mode": "listFiles"
}期待する情報:
.gitignoreや exclude rule を反映した file path 一覧- extension / directory / file count summary
- skipped path や unsupported ignore pattern の diagnostics
listFiles mode では matches[] は空配列になり、file inventory は files[]、集計は fileSummary に返ります。
大量の match から次に読む candidate を選びやすくする mode です。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"output": {
"mode": "agent"
}
}path、target kind、match count、representative snippets、推奨 read range を返します。
agent mode の matches[] は agentFile / agentDirectory item を返します。agentFile は representativeSnippets と readRanges を含みます。
検索結果から miku-readfile に渡す request を作りやすくする handoff hint です。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"output": {
"includeReadfileRequestHints": true
}
}readfileHints[] は matched file ごとに返ります。directory match だけの結果には readfile hint は付きません。
{
"version": 1,
"root": ".",
"detectGitRoot": true,
"query": {
"type": "literal",
"text": "RepositoryMap"
}
}{
"version": 1,
"root": ".",
"query": {
"type": "glob",
"text": "**/*.md"
},
"search": {
"targets": ["filepath"]
}
}query.type: "glob" は root-relative path に対する検索です。filepath / directory target と listFiles mode の絞り込みで使えます。content target との組み合わせは validation error です。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "検索語"
},
"encoding": {
"preset": "japanese-legacy"
}
}japanese-legacy preset は、よくある日本語 legacy text file pattern に Shift_JIS を適用します。明示 encoding.rules は preset より優先され、result の encodingRule には preset 由来かどうかが返ります。
{
"version": 1,
"root": ".",
"query": {
"type": "literal",
"text": "RepositoryMap"
},
"output": {
"sort": "relevance"
}
}output.sort: "relevance" は semantic ranking ではなく、deterministic heuristic です。summary / agent mode の候補を README / docs / src / test / match count / path match / generated らしさなどで並べ替え、各 item に relevance.score と relevance.reasons を返します。default は再現性を優先して path です。
stdout の result JSON は、成功時も期待可能な失敗時も同じ top-level shape を保ちます。
{
"version": 1,
"ok": true,
"error": null,
"effectiveRequest": {},
"matches": [],
"summary": {
"filesVisited": 0,
"directoriesVisited": 0,
"filesScanned": 0,
"directoriesScanned": 0,
"filesMatched": 0,
"directoriesMatched": 0,
"filesIgnored": 0,
"directoriesIgnored": 0,
"matches": 0,
"diagnostics": 0,
"truncated": false,
"truncatedReason": null
},
"diagnostics": []
}主な field:
ok: request が実行できたかどうかerror:ok: falseのときの代表 erroreffectiveRequest: default 適用後の実際の検索条件matches: 検索結果。output.modeによって item shape が変わりますfiles:mode: "listFiles"の file path 一覧fileSummary:mode: "listFiles"の extension / directory summaryreadfileHints:output.includeReadfileRequestHints: trueのときのmiku-readfilehandoff requestsummary: scanned file 数、hit 数、truncation の有無diagnostics: skipped file、decode error、limit 到達、validation error など
summary mode の matches[] は、matched file / matched directory を item として返します。agent が次に読む file や見るべき directory を選ぶ最初の検索に向いています。
detail mode の matches[] は、content target では 1 content hit = 1 item です。filepath / directory target では 1 matched path = 最大 1 item で、同じ path 文字列内に複数 match がある場合は代表 matchedText を返します。line、column、matched text、snippet を見たい場合に使います。
- stdout は result JSON 専用です。progress log や runtime-level message は stderr に出します。
- request JSON と result JSON はどちらも top-level に
version: 1を持ちます。 - request JSON の未知 field は validation error です。
- result JSON 内の
fileはrootからの相対 path です。絶対 path は返しません。 - path separator は platform に関わらず
/です。 - symlink は MVP では追跡しません。
- content 検索では file size、line length、match count などの resource limit が適用されます。
- regex は Node.js
RegExpを使いますが、JavaScript 固有の flags は request schema では受け取りません。
詳細な default、limit、schema、exit code、diagnostic code、sort order は miku-grep CLI Specification を参照してください。
依存関係を入れます。
npm installテストを実行します。
npm testTypeScript compile、テスト、単一ファイル CLI bundle 生成をまとめて実行します。
npm run build開発用 CLI の stdin / stdout smoke example を実行します。
npm run smokebundle 生成後に、単一ファイル runtime artifact の smoke test を実行します。
npm run smoke:bundle主な生成物:
dist/main.jsbundle/miku-grep.mjsbundle/miku-grep-sources.tgz
dist/main.js は package bin が指す開発・npm package 用 CLI entry です。
bundle/miku-grep.mjs は source tree なしで実行できる単一ファイル runtime artifact です。
bundle/miku-grep-sources.tgz は再ビルド、監査、下流確認用の source archive です。
- miku-grep CLI Specification
- miku-grep Security Notes
- miku-grep Search Targets Specification
- miku-grep Context Lines Specification
- miku-grep Ignore Files Specification
- Miku Software Overview Design
- Miku Software Main Application Design
- Miku Software Agent Skills Design
- Agent Skills 版: miku-grep-skills
- Java 版: miku-grep-java
- Repository map 別プロダクト候補: Repository Map Product Candidate
- Policy-aware search 別プロダクト候補: Policy-Aware Search Requirements Memo
MCP adapter は当面対応しません。まずは CLI、Java 版、Agent Skills 版を通常の利用経路として扱います。