@takara-ai/miru-code 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -333
- package/package.json +1 -1
- package/src/cli.ts +2 -2
- package/src/installer/installer.ts +5 -0
- package/src/setup.ts +25 -10
package/README.md
CHANGED
|
@@ -1,409 +1,154 @@
|
|
|
1
1
|
# Miru (見る)
|
|
2
2
|
|
|
3
|
-
Hybrid code search for AI agents — **
|
|
3
|
+
Hybrid code search for AI agents — **Bun**, **TypeScript**, **Takara embeddings**.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Find code by meaning, not grep. Miru returns the best **chunks** (path, lines, snippet) for questions like “where is auth middleware configured?”
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|-----------------|------------|
|
|
9
|
-
| Use Miru in an IDE (Cursor, Claude Code, etc.) | [User flow](#user-flow) → [Credentials](#credentials) → [IDE integration](#ide-integration) |
|
|
10
|
-
| Run search from a terminal or script | [User flow](#user-flow) → [CLI](#cli) |
|
|
11
|
-
| Embed Miru in your own tool | [Library](#library) |
|
|
12
|
-
| Hack on this repo | [Developing Miru](#developing-miru) |
|
|
13
|
-
|
|
14
|
-
The sections below follow that order: **what Miru does**, **how you use it end to end**, then **reference** (CLI flags, env vars, per-IDE MCP JSON).
|
|
15
|
-
|
|
16
|
-
## What is Miru?
|
|
17
|
-
|
|
18
|
-
*Miru* (見る) means “to see” or “to look” in Japanese. Miru helps coding agents **find code by meaning** instead of guessing file paths or running exhaustive greps.
|
|
19
|
-
|
|
20
|
-
When an agent asks “where is auth middleware configured?” or “how do we batch embeddings?”, Miru returns the most relevant **chunks** — file path, line range, and snippet — so the agent can read only what matters.
|
|
21
|
-
|
|
22
|
-
### Why hybrid search?
|
|
23
|
-
|
|
24
|
-
Pure semantic search misses exact symbol matches. Pure keyword search misses paraphrased intent. Miru combines both:
|
|
25
|
-
|
|
26
|
-
1. **Dense (semantic)** — Takara code embeddings (`ds1-potion-code-16m`) over structurally chunked source files.
|
|
27
|
-
2. **Sparse (BM25)** — keyword scoring with an inverted index; parallelized in Bun workers when the index has 256+ chunks.
|
|
28
|
-
3. **RRF fusion** — reciprocal rank fusion merges the two ranked lists.
|
|
29
|
-
4. **Reranking** — code-tuned penalties and boosts (e.g. multi-chunk files, query-term overlap).
|
|
30
|
-
|
|
31
|
-
You can index **code**, **docs**, **config**, or **all** of the above via `--content` (CLI/MCP) or when building an index in the library.
|
|
32
|
-
|
|
33
|
-
### Caching (what “fresh” means)
|
|
34
|
-
|
|
35
|
-
| Layer | Behavior |
|
|
36
|
-
|-------|----------|
|
|
37
|
-
| **First search** | Builds an index (chunk → embed → BM25 + vectors), then writes a disk cache. |
|
|
38
|
-
| **MCP server (local repo, same session)** | Watches the workspace and **incrementally** re-indexes changed files; updates the disk cache. Disable with `MIRU_MCP_WATCH=0`. |
|
|
39
|
-
| **CLI or a new MCP session** | Reuses the disk cache if the embedding model, content types, and indexed files still match. Cache does **not** detect file edits by itself — run `miru clear <path>` after large changes, or rely on MCP live updates. |
|
|
40
|
-
| **Remote `https://` repos** | Cloned per session; no filesystem watch. Use `--ref` for a branch/tag. |
|
|
41
|
-
|
|
42
|
-
Cache locations: `~/Library/Caches/miru` (macOS), `~/.cache/miru` (Linux), `%LOCALAPPDATA%\miru\Cache` (Windows).
|
|
43
|
-
|
|
44
|
-
### How agents use Miru
|
|
45
|
-
|
|
46
|
-
| Mode | Best for | What the agent gets |
|
|
47
|
-
|------|----------|---------------------|
|
|
48
|
-
| **MCP server** | Cursor, Claude Code, VS Code Copilot, Gemini CLI, Kiro, OpenCode | `search` and `find_related` tools; pass `repo` (local path or `https://` git URL) |
|
|
49
|
-
| **CLI sub-agent** | Any agent with shell access | `miru install` (global) or `miru init --agent <id>` (per-repo) |
|
|
50
|
-
|
|
51
|
-
Both modes share the same indexing logic and disk cache layout.
|
|
52
|
-
|
|
53
|
-
## User flow
|
|
54
|
-
|
|
55
|
-
Typical path from zero to useful search:
|
|
56
|
-
|
|
57
|
-
```text
|
|
58
|
-
1. Install Bun + Miru → bun add -g @takara-ai/miru-code (or bunx for one-off)
|
|
59
|
-
2. Credentials → miru setup OR TAKARA_API_KEY in MCP env / .env.local
|
|
60
|
-
3. Integrate → miru install (MCP + instructions + sub-agent)
|
|
61
|
-
4. Search → Agent calls search("…", repo: project root)
|
|
62
|
-
5. Go deeper (optional) → find_related(file, line) on a hit
|
|
63
|
-
6. Refresh cache (if needed) → miru clear . after big refactors when using CLI only
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Agent workflow:** `search` first → read returned chunks → `find_related` on a promising `file_path` + line → open full files only when the chunk is not enough → use grep for exhaustive literal matches.
|
|
67
|
-
|
|
68
|
-
**`repo` rules:** Local workspaces use the **project root** path. Remote repos use an explicit **`https://` or `http://`** URL (not `git@` SSH). Never guess URLs.
|
|
7
|
+
**Requires:** [Bun](https://bun.sh) 1.1+ · [Takara API key](https://takara.ai)
|
|
69
8
|
|
|
70
9
|
## Install
|
|
71
10
|
|
|
72
|
-
Requires [Bun](https://bun.sh) 1.1+ on your PATH.
|
|
73
|
-
|
|
74
11
|
```bash
|
|
75
|
-
# One-off
|
|
76
|
-
bunx @takara-ai/miru-code search "auth middleware" ./src
|
|
77
|
-
|
|
78
|
-
# Global CLI
|
|
79
12
|
bun add -g @takara-ai/miru-code
|
|
80
|
-
miru search "auth middleware" ./src
|
|
81
|
-
|
|
82
|
-
# Library
|
|
83
|
-
bun add @takara-ai/miru-code
|
|
84
13
|
```
|
|
85
14
|
|
|
86
|
-
##
|
|
87
|
-
|
|
88
|
-
Miru needs a **Takara bearer token** for embeddings (`TAKARA_API_KEY`).
|
|
89
|
-
|
|
90
|
-
**CLI / terminal (recommended for local dev):**
|
|
15
|
+
## Set up API key
|
|
91
16
|
|
|
92
17
|
```bash
|
|
93
|
-
miru setup
|
|
94
|
-
miru setup --key TOKEN # non-interactive
|
|
95
|
-
miru setup --clear # remove stored key
|
|
18
|
+
miru setup
|
|
96
19
|
```
|
|
97
20
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
**MCP in an IDE:** Put `TAKARA_API_KEY` in the MCP server `env` block. MCP does not reliably inherit your shell or `.env.local` — set it explicitly.
|
|
101
|
-
|
|
102
|
-
**This repo:** `bun install` then add `TAKARA_API_KEY` to `.env.local` (Bun loads it when you run from the project root).
|
|
103
|
-
|
|
104
|
-
## IDE integration
|
|
105
|
-
|
|
106
|
-
### Recommended: `miru install`
|
|
107
|
-
|
|
108
|
-
Interactive setup (like Semble’s `semble install`). Detects installed agents and configures any combination of:
|
|
109
|
-
|
|
110
|
-
| Integration | What it does |
|
|
111
|
-
|-------------|----------------|
|
|
112
|
-
| **MCP server** | Adds `miru` to your agent’s MCP config (`search`, `find_related`) |
|
|
113
|
-
| **Instructions** | Appends a marked block to `CLAUDE.md`, `GEMINI.md`, `AGENTS.md`, etc. |
|
|
114
|
-
| **Sub-agent** | Installs `miru-code` under your **user** config (global, all projects) |
|
|
21
|
+
Validates your key and saves it locally. Skip this if you prefer — `miru search` or `miru install` will prompt on first run.
|
|
115
22
|
|
|
116
23
|
```bash
|
|
117
|
-
|
|
118
|
-
miru setup
|
|
119
|
-
miru install
|
|
24
|
+
miru setup --key YOUR_TOKEN # non-interactive
|
|
25
|
+
miru setup --clear # remove stored key
|
|
120
26
|
```
|
|
121
27
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
**Supported agents:** Claude Code, Cursor, Gemini CLI, Kiro, OpenCode, GitHub Copilot, Codex, VS Code.
|
|
125
|
-
|
|
126
|
-
### Global paths (after `miru install`)
|
|
127
|
-
|
|
128
|
-
| Agent | MCP config | Sub-agent |
|
|
129
|
-
|-------|------------|-----------|
|
|
130
|
-
| Claude Code | `~/.claude.json` | `~/.claude/agents/miru-code.md` |
|
|
131
|
-
| Cursor | `~/.cursor/mcp.json` | `~/.cursor/agents/miru-code.md` |
|
|
132
|
-
| Gemini CLI | `~/.gemini/settings.json` | `~/.gemini/agents/miru-code.md` |
|
|
133
|
-
| Kiro | `~/.kiro/settings/mcp.json` | `~/.kiro/agents/miru-code.md` |
|
|
134
|
-
| OpenCode | `~/.config/opencode/opencode.json(c)` | `~/.config/opencode/agents/miru-code.md` |
|
|
135
|
-
| GitHub Copilot | `~/.copilot/mcp-config.json` | `~/.copilot/agents/miru-code.agent.md` |
|
|
136
|
-
| Codex | `~/.codex/config.toml` | (MCP only) |
|
|
137
|
-
| VS Code | user profile `mcp.json` | (MCP only) |
|
|
28
|
+
For MCP in an IDE, export `TAKARA_API_KEY` or paste your token into the MCP `env` block after install.
|
|
138
29
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
### Per-project sub-agent (`miru init`)
|
|
142
|
-
|
|
143
|
-
To commit a sub-agent into a repo (team-shared) instead of global user config:
|
|
30
|
+
## Add to your IDE
|
|
144
31
|
|
|
145
32
|
```bash
|
|
146
|
-
miru
|
|
33
|
+
miru install
|
|
147
34
|
```
|
|
148
35
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
### MCP server
|
|
152
|
-
|
|
153
|
-
No subcommand starts stdio MCP:
|
|
36
|
+
Interactive — pick your agent and what to enable (MCP, instructions, sub-agent). Restart the IDE when done.
|
|
154
37
|
|
|
155
38
|
```bash
|
|
156
|
-
|
|
157
|
-
# or: miru
|
|
39
|
+
miru uninstall # remove miru config
|
|
158
40
|
```
|
|
159
41
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
**Tools**
|
|
163
|
-
|
|
164
|
-
| Tool | Purpose |
|
|
165
|
-
|------|---------|
|
|
166
|
-
| `search` | Natural-language or code query; requires `repo`; optional `top_k` (default 5) |
|
|
167
|
-
| `find_related` | Similar chunks to `file_path` + `line` (from a search hit); requires `repo`; optional `top_k` |
|
|
168
|
-
|
|
169
|
-
Indexing runs on the first tool call for each `repo`. Later calls in the same MCP session reuse memory and refresh local files via watch (see [Caching](#caching-what-fresh-means)).
|
|
170
|
-
|
|
171
|
-
Use `bunx` in MCP config (`command`: `bunx`, `args`: `["@takara-ai/miru-code"]`). After `bun add -g`, you may use `"command": "miru"` instead.
|
|
172
|
-
|
|
173
|
-
#### Shared env block
|
|
42
|
+
**Supported:** Cursor · Claude Code · Gemini CLI · Kiro · OpenCode · GitHub Copilot · Codex · VS Code
|
|
174
43
|
|
|
175
|
-
|
|
44
|
+
| IDE | Config written by `miru install` |
|
|
45
|
+
|-----|----------------------------------|
|
|
46
|
+
| Cursor | `~/.cursor/mcp.json` + `~/.cursor/agents/miru-code.md` |
|
|
47
|
+
| Claude Code | `~/.claude.json` + `~/.claude/agents/miru-code.md` |
|
|
48
|
+
| Gemini CLI | `~/.gemini/settings.json` + `~/.gemini/agents/miru-code.md` |
|
|
49
|
+
| Kiro | `~/.kiro/settings/mcp.json` + `~/.kiro/agents/miru-code.md` |
|
|
50
|
+
| OpenCode | `~/.config/opencode/opencode.json(c)` + agents dir |
|
|
51
|
+
| GitHub Copilot | `~/.copilot/mcp-config.json` + `~/.copilot/agents/miru-code.agent.md` |
|
|
52
|
+
| Codex / VS Code | MCP config only |
|
|
176
53
|
|
|
177
|
-
|
|
178
|
-
{
|
|
179
|
-
"TAKARA_API_KEY": "your-takara-bearer-token",
|
|
180
|
-
"MIRU_OPENAI_BASE_URL": "https://infer.dev.takara.ai/v1",
|
|
181
|
-
"MIRU_OPENAI_EMBEDDING_MODEL": "ds1-potion-code-16m",
|
|
182
|
-
"MIRU_EMBEDDING_DIMENSIONS": "256"
|
|
183
|
-
}
|
|
184
|
-
```
|
|
54
|
+
**Team sub-agent in a repo** (optional):
|
|
185
55
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
`~/.cursor/mcp.json` or project `.cursor/mcp.json`:
|
|
189
|
-
|
|
190
|
-
```json
|
|
191
|
-
{
|
|
192
|
-
"mcpServers": {
|
|
193
|
-
"miru": {
|
|
194
|
-
"command": "bunx",
|
|
195
|
-
"args": ["@takara-ai/miru-code"],
|
|
196
|
-
"env": {
|
|
197
|
-
"TAKARA_API_KEY": "your-takara-bearer-token"
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
56
|
+
```bash
|
|
57
|
+
miru init --agent claude --force
|
|
202
58
|
```
|
|
203
59
|
|
|
204
|
-
|
|
60
|
+
## Try it
|
|
205
61
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
```json
|
|
211
|
-
{
|
|
212
|
-
"mcpServers": {
|
|
213
|
-
"miru": {
|
|
214
|
-
"type": "stdio",
|
|
215
|
-
"command": "bunx",
|
|
216
|
-
"args": ["@takara-ai/miru-code"],
|
|
217
|
-
"env": {
|
|
218
|
-
"TAKARA_API_KEY": "${TAKARA_API_KEY}"
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
62
|
+
```bash
|
|
63
|
+
miru search "auth middleware" ./src
|
|
64
|
+
miru find-related src/auth.ts 42 ./src
|
|
223
65
|
```
|
|
224
66
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
Sub-agent: `miru install` (global) or `miru init --agent claude` (project-local).
|
|
228
|
-
|
|
229
|
-
### VS Code / GitHub Copilot
|
|
230
|
-
|
|
231
|
-
`.vscode/mcp.json` or user profile (**MCP: Open User Configuration**). Note `"servers"` not `mcpServers`:
|
|
67
|
+
Terminal output is human-readable; use `--json` for scripts. One-off without installing:
|
|
232
68
|
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
"servers": {
|
|
236
|
-
"miru": {
|
|
237
|
-
"type": "stdio",
|
|
238
|
-
"command": "bunx",
|
|
239
|
-
"args": ["@takara-ai/miru-code"],
|
|
240
|
-
"env": {
|
|
241
|
-
"TAKARA_API_KEY": "your-takara-bearer-token"
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
69
|
+
```bash
|
|
70
|
+
bunx @takara-ai/miru-code search "auth middleware" ./src
|
|
246
71
|
```
|
|
247
72
|
|
|
248
|
-
|
|
73
|
+
---
|
|
249
74
|
|
|
250
|
-
|
|
75
|
+
## MCP tools
|
|
251
76
|
|
|
252
|
-
|
|
77
|
+
When wired via `miru install`, your agent gets:
|
|
253
78
|
|
|
254
|
-
|
|
79
|
+
| Tool | What it does |
|
|
80
|
+
|------|----------------|
|
|
81
|
+
| `search` | Query by meaning; pass `repo` (project root or `https://` git URL) |
|
|
82
|
+
| `find_related` | Similar code at a `file_path` + line from a search hit |
|
|
255
83
|
|
|
256
|
-
|
|
84
|
+
Pass the **project root** as `repo` for local projects.
|
|
257
85
|
|
|
258
|
-
|
|
259
|
-
"env": {
|
|
260
|
-
"TAKARA_API_KEY": "your-takara-bearer-token",
|
|
261
|
-
"PATH": "/usr/local/bin:/usr/bin:/bin"
|
|
262
|
-
}
|
|
263
|
-
```
|
|
86
|
+
## How it works
|
|
264
87
|
|
|
265
|
-
|
|
88
|
+
Hybrid search: Takara embeddings + BM25 + fusion + reranking. Indexes **code**, **docs**, **config**, or **all** via `--content`.
|
|
266
89
|
|
|
267
|
-
|
|
90
|
+
Disk cache: `~/Library/Caches/miru` (macOS), `~/.cache/miru` (Linux). MCP watches local files and updates incrementally; run `miru clear .` after big refactors when using CLI only.
|
|
268
91
|
|
|
269
|
-
|
|
92
|
+
## CLI reference
|
|
270
93
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
Verify with `opencode mcp list`. Sub-agent: `miru install`.
|
|
288
|
-
|
|
289
|
-
## CLI
|
|
94
|
+
| Command | Purpose |
|
|
95
|
+
|---------|---------|
|
|
96
|
+
| `miru setup` | Store API key |
|
|
97
|
+
| `miru install` | Configure IDE (global) |
|
|
98
|
+
| `miru uninstall` | Remove IDE config |
|
|
99
|
+
| `miru search <query> [path]` | Search (`-k N`, `--content`, `--json`) |
|
|
100
|
+
| `miru find-related <file> <line> [path]` | Related chunks |
|
|
101
|
+
| `miru init --agent <id>` | Project-local sub-agent |
|
|
102
|
+
| `miru clear [path]` | Drop index cache |
|
|
103
|
+
| `miru` | Start MCP server |
|
|
290
104
|
|
|
291
|
-
|
|
105
|
+
## Library
|
|
292
106
|
|
|
293
107
|
```bash
|
|
294
|
-
miru
|
|
295
|
-
miru install # interactive MCP + instructions + sub-agent (recommended)
|
|
296
|
-
miru search "where are embeddings created" ./src -k 10 --content code
|
|
297
|
-
miru find-related src/embeddings/openai.ts 120 ./src
|
|
298
|
-
miru uninstall # remove miru config from agents
|
|
299
|
-
miru clear ./src
|
|
300
|
-
miru help search # per-command help
|
|
301
|
-
miru -h # environment variables
|
|
108
|
+
bun add @takara-ai/miru-code
|
|
302
109
|
```
|
|
303
110
|
|
|
304
|
-
From **this repo** (development), prefix with `bun run miru` instead of `miru`.
|
|
305
|
-
|
|
306
|
-
| Command | Summary |
|
|
307
|
-
|---------|---------|
|
|
308
|
-
| `search <query> [path]` | Hybrid search; `path` defaults to cwd; accepts local path or `https://` git URL |
|
|
309
|
-
| `find-related <file> <line> [path]` | Semantic neighbors of the chunk containing that line |
|
|
310
|
-
| `setup` | Store and validate `TAKARA_API_KEY` locally |
|
|
311
|
-
| `install` | Interactive global agent setup (MCP, instructions, sub-agent) |
|
|
312
|
-
| `uninstall` | Remove miru configuration from agents |
|
|
313
|
-
| `init --agent <id>` | Write project-local sub-agent markdown |
|
|
314
|
-
| `clear [path]` | Delete disk cache for that source |
|
|
315
|
-
| *(no command)* | Start MCP server |
|
|
316
|
-
|
|
317
|
-
**Options:** `-k` / `--top-k N` (default 5), `--content code|docs|config|all` (default `code`). Multiple types: `--content code docs`.
|
|
318
|
-
|
|
319
|
-
Output is JSON (`query` + `results` with `chunk`, `score`, `location`).
|
|
320
|
-
|
|
321
|
-
## Library
|
|
322
|
-
|
|
323
111
|
```ts
|
|
324
112
|
import { MiruIndex } from "@takara-ai/miru-code";
|
|
325
113
|
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
// Local path or https:// git URL
|
|
330
|
-
const fromUrl = await MiruIndex.fromSource("https://github.com/org/repo", ["code"], undefined, "main");
|
|
331
|
-
|
|
332
|
-
const results = await index.search({
|
|
333
|
-
query: "BM25 tokenize",
|
|
334
|
-
topK: 10, // default 10 in the library API
|
|
335
|
-
filterPaths: ["src/index/bm25.ts"],
|
|
336
|
-
rerank: true,
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
const related = await index.findRelated(results[0], 5);
|
|
340
|
-
await index.saveToDefaultCache("./src");
|
|
114
|
+
const index = await MiruIndex.fromPath("./src");
|
|
115
|
+
const results = await index.search({ query: "BM25 tokenize", topK: 10 });
|
|
341
116
|
```
|
|
342
117
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
## Environment variables
|
|
346
|
-
|
|
347
|
-
| Variable | Default / notes |
|
|
348
|
-
|----------|-----------------|
|
|
349
|
-
| `TAKARA_API_KEY` | **Required** — Takara bearer token |
|
|
350
|
-
| `MIRU_OPENAI_BASE_URL` | `https://infer.dev.takara.ai/v1` |
|
|
351
|
-
| `MIRU_OPENAI_EMBEDDING_MODEL` | `ds1-potion-code-16m` |
|
|
352
|
-
| `MIRU_EMBEDDING_DIMENSIONS` | `256` for potion (auto when unset) |
|
|
353
|
-
| `MIRU_FLOAT_VECTORS` | unset = **int8** vectors; `1` = float32 |
|
|
354
|
-
| `MIRU_EMBEDDING_BATCH_SIZE` | `32` |
|
|
355
|
-
| `MIRU_CONCURRENCY` | logical CPUs **minus 2** (min 1); file IO, embedding batches, BM25 workers |
|
|
356
|
-
| `MIRU_MCP_WATCH` | on; set `0` or `false` to disable MCP filesystem watch |
|
|
357
|
-
| `MIRU_CREDENTIALS_DIR` | override stored-credentials directory |
|
|
358
|
-
| `MIRU_PIPELINE_EMBED_BATCH` | optional pipeline tuning (see `.env.example`) |
|
|
359
|
-
| `MIRU_PIPELINE_EMBED_INFLIGHT` | optional pipeline tuning |
|
|
118
|
+
## Environment
|
|
360
119
|
|
|
361
|
-
|
|
120
|
+
| Variable | Notes |
|
|
121
|
+
|----------|-------|
|
|
122
|
+
| `TAKARA_API_KEY` | Required |
|
|
123
|
+
| `MIRU_OPENAI_BASE_URL` | Default `https://infer.dev.takara.ai/v1` |
|
|
124
|
+
| `MIRU_MCP_WATCH` | Set `0` to disable MCP file watch |
|
|
125
|
+
| `NO_COLOR` | Disable CLI colors |
|
|
362
126
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
```bash
|
|
366
|
-
bun install
|
|
367
|
-
cp .env.example .env.local # add TAKARA_API_KEY
|
|
368
|
-
bun test
|
|
369
|
-
bun run typecheck
|
|
370
|
-
```
|
|
127
|
+
See `.env.example` for more.
|
|
371
128
|
|
|
372
|
-
|
|
129
|
+
## Manual MCP (skip `miru install`)
|
|
373
130
|
|
|
374
131
|
```json
|
|
375
132
|
{
|
|
376
|
-
"
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
"TAKARA_API_KEY": "your-
|
|
133
|
+
"miru": {
|
|
134
|
+
"command": "miru",
|
|
135
|
+
"args": [],
|
|
136
|
+
"env": { "TAKARA_API_KEY": "your-token" }
|
|
380
137
|
}
|
|
381
138
|
}
|
|
382
139
|
```
|
|
383
140
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
## Publishing
|
|
387
|
-
|
|
388
|
-
Releases use **Bun** for install, test, and `bun pm pack`. Registry upload uses **`npm publish`** on that tarball because [Bun does not yet support npm OIDC trusted publishing](https://github.com/oven-sh/bun/issues/22423).
|
|
389
|
-
|
|
390
|
-
**Local** (logged in to npm):
|
|
391
|
-
|
|
392
|
-
```bash
|
|
393
|
-
bun publish
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
Runs `prepublishOnly` (typecheck + tests). Do not add a `publish` script that calls `npm publish` — that would upload twice.
|
|
141
|
+
Use `bunx` + `@takara-ai/miru-code` if `miru` is not global. Wrapper key varies by IDE (`mcpServers`, `servers`, or `mcp`).
|
|
397
142
|
|
|
398
|
-
|
|
143
|
+
## Developing
|
|
399
144
|
|
|
400
145
|
```bash
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
146
|
+
git clone https://github.com/takara-ai/miru-code.git && cd miru-code
|
|
147
|
+
bun install && cp .env.example .env.local
|
|
148
|
+
bun test && bun run typecheck
|
|
404
149
|
```
|
|
405
150
|
|
|
406
|
-
|
|
151
|
+
Local MCP: `"command": "bun", "args": ["/path/to/miru-code/src/cli.ts"]`
|
|
407
152
|
|
|
408
153
|
## License
|
|
409
154
|
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -133,7 +133,7 @@ async function runSearch(
|
|
|
133
133
|
content: ContentType[],
|
|
134
134
|
jsonFlag: boolean,
|
|
135
135
|
): Promise<void> {
|
|
136
|
-
await ensureCredentials();
|
|
136
|
+
await ensureCredentials({ interactive: true });
|
|
137
137
|
|
|
138
138
|
const index = await withSpinner("Indexing and searching", async () => {
|
|
139
139
|
const built = await MiruIndex.fromSource(path, content);
|
|
@@ -153,7 +153,7 @@ async function runFindRelated(
|
|
|
153
153
|
content: ContentType[],
|
|
154
154
|
jsonFlag: boolean,
|
|
155
155
|
): Promise<void> {
|
|
156
|
-
await ensureCredentials();
|
|
156
|
+
await ensureCredentials({ interactive: true });
|
|
157
157
|
|
|
158
158
|
const { results, label } = await withSpinner("Finding related chunks", async () => {
|
|
159
159
|
const built = await MiruIndex.fromSource(path, content);
|
|
@@ -2,6 +2,7 @@ import { mkdir, unlink, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { loadAgentTemplate } from "../agents.ts";
|
|
4
4
|
import { brandTitle, dim, divider, green, hint, success, writeStdout } from "../cli-ui.ts";
|
|
5
|
+
import { ensureCredentials } from "../setup.ts";
|
|
5
6
|
import {
|
|
6
7
|
AGENT_TARGETS,
|
|
7
8
|
type AgentTarget,
|
|
@@ -183,6 +184,10 @@ export async function runInstaller(mode: InstallMode): Promise<void> {
|
|
|
183
184
|
const install = mode === "install";
|
|
184
185
|
requireInteractiveTerminal(`miru ${mode}`);
|
|
185
186
|
|
|
187
|
+
if (install) {
|
|
188
|
+
await ensureCredentials({ interactive: true });
|
|
189
|
+
}
|
|
190
|
+
|
|
186
191
|
writeStdout("");
|
|
187
192
|
writeStdout(`${brandTitle()}${install ? " installer" : " uninstaller"}`);
|
|
188
193
|
divider();
|
package/src/setup.ts
CHANGED
|
@@ -87,30 +87,45 @@ export async function runClearCredentials(): Promise<void> {
|
|
|
87
87
|
info(`No stored API key at ${path}`);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export
|
|
90
|
+
export function canPromptForCredentials(): boolean {
|
|
91
|
+
return Boolean(process.stdin.isTTY);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function hasCredentials(): boolean {
|
|
91
95
|
try {
|
|
92
96
|
resolveEmbeddingApiKey();
|
|
93
|
-
return;
|
|
97
|
+
return true;
|
|
94
98
|
} catch {
|
|
95
|
-
|
|
99
|
+
return false;
|
|
96
100
|
}
|
|
101
|
+
}
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
async function refreshCredentialsFromStore(): Promise<void> {
|
|
104
|
+
await loadStoredCredentials();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function ensureCredentials(options?: { interactive?: boolean }): Promise<void> {
|
|
108
|
+
if (hasCredentials()) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
await refreshCredentialsFromStore();
|
|
113
|
+
if (hasCredentials()) {
|
|
100
114
|
return;
|
|
101
|
-
} catch {
|
|
102
|
-
// still missing
|
|
103
115
|
}
|
|
104
116
|
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
117
|
+
const wantsPrompt = options?.interactive ?? true;
|
|
118
|
+
if (wantsPrompt && canPromptForCredentials()) {
|
|
119
|
+
writeStderr("");
|
|
120
|
+
info("No Takara API key found.");
|
|
121
|
+
hint("Miru needs one for embeddings — enter it below (same as `miru setup`).");
|
|
107
122
|
await runSetup();
|
|
108
123
|
resolveEmbeddingApiKey();
|
|
109
124
|
return;
|
|
110
125
|
}
|
|
111
126
|
|
|
112
127
|
throw new Error(
|
|
113
|
-
"
|
|
128
|
+
"Takara API key required. Run `miru setup` in a terminal, or set TAKARA_API_KEY " +
|
|
114
129
|
"in your MCP server env (Cursor mcp.json) or .env.local.",
|
|
115
130
|
);
|
|
116
131
|
}
|