mini-coder 0.1.0 → 0.1.1
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 +39 -157
- package/dist/mc.js +94 -46
- package/docs/mini-coder.1.md +221 -102
- package/package.json +1 -1
- package/docs/configs.md +0 -118
- package/docs/custom-agents.md +0 -69
- package/docs/custom-commands.md +0 -141
- package/docs/skills.md +0 -83
package/README.md
CHANGED
|
@@ -6,194 +6,76 @@
|
|
|
6
6
|
|
|
7
7
|
> _Small. Fast. Gets out of your way._
|
|
8
8
|
|
|
9
|
-
[📖 Read the Full Manual](
|
|
9
|
+
[📖 Read the Full Manual](docs/mini-coder.1.md)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 🤙 Who Am I?
|
|
16
|
-
|
|
17
|
-
I'm `mc` — your new terminal companion. I live in your shell, speak to large language models, and help you explore, understand, and modify code at the speed of thought.
|
|
18
|
-
|
|
19
|
-
I was built with a simple philosophy: **dev flow first**. No slow startup. No clunky GUI. No vendor lock-in. Just you, your terminal, and an AI that keeps up.
|
|
11
|
+
A terminal coding agent for developers who want a sharp tool, not a bloated IDE plugin. Shell-first, multi-provider, minimal tool surface. Just you, your terminal, and an AI that keeps up.
|
|
20
12
|
|
|
21
13
|

|
|
22
14
|
|
|
23
15
|
---
|
|
24
16
|
|
|
25
|
-
##
|
|
26
|
-
|
|
27
|
-
My toolkit is lean on purpose — every tool earns its spot, no passengers:
|
|
28
|
-
|
|
29
|
-
| Tool | What it does |
|
|
30
|
-
| --------------- | -------------------------------------------------------------------------- |
|
|
31
|
-
| 🐚 `shell` | Run shell commands, inspect the repo, and use `mc-edit` for targeted edits |
|
|
32
|
-
| 🤖 `subagent` | Spawn a focused mini-me for parallel subtasks |
|
|
33
|
-
| 🧰 `listSkills` | List discovered skills without loading full skill bodies |
|
|
34
|
-
| 📘 `readSkill` | Load one `SKILL.md` on demand |
|
|
35
|
-
| 🌐 `webSearch` | Search the web when `EXA_API_KEY` is set |
|
|
36
|
-
| 📄 `webContent` | Fetch full page content from URLs when `EXA_API_KEY` is set |
|
|
37
|
-
|
|
38
|
-
mini-coder is intentionally **shell-first**: inspect with shell, edit with `mc-edit`, verify with shell.
|
|
39
|
-
|
|
40
|
-
Need more firepower? I also connect to **MCP servers** over HTTP or stdio — attached MCP tools show up dynamically whenever the job calls for them.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## ⚡ Key Features
|
|
45
|
-
|
|
46
|
-
- **Multi-provider** — set `OPENCODE_API_KEY` for Zen, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY` or `GEMINI_API_KEY`, or just run Ollama locally (`OLLAMA_BASE_URL` optional). I auto-discover whatever's available.
|
|
47
|
-
- **Built-in web search** — set `EXA_API_KEY` and I expose `webSearch` + `webContent` tools.
|
|
48
|
-
- **Session memory** — conversations are saved in a local SQLite database. Resume where you left off with `-c` or pick a specific session with `-r <id>`.
|
|
49
|
-
- **Shell integration** — prefix with `!` to run shell commands inline. Use `@` to reference files in your prompt (with Tab completion).
|
|
50
|
-
- **Slash commands** — `/model` or `/models` to list/switch models, `/model effort <low|medium|high|xhigh|off>` for reasoning effort, `/reasoning [on|off]` to toggle reasoning display, `/context` to inspect or tune pruning/tool-result caps, `/cache` to configure prompt caching, `/review` for a code review (global custom command, auto-created at `~/.agents/commands/review.md`), `/agent [name]` to set or clear an active primary agent, `/undo` to remove the last conversation turn (it does not revert filesystem changes), `/new` for a clean session, `/mcp list|add|remove` to manage MCP servers, and `/exit` (`/quit`, `/q`) to leave. See all with `/help`.
|
|
51
|
-
|
|
52
|
-
- **Custom commands** — drop a `.md` file in `.agents/commands/` and it becomes a `/command`. Claude-compatible `.claude/commands/` works too. Supports argument placeholders (`$ARGUMENTS`, `$1`…`$9`) and shell interpolation (`` !`cmd` ``). Global commands live in `~/.agents/commands/` and `~/.claude/commands/`. Custom commands take precedence over built-ins. → [docs/custom-commands.md](docs/custom-commands.md)
|
|
53
|
-
- **Custom agents** — drop a `.md` file in `.agents/agents/` or `.claude/agents/` (or `~/.agents/agents/` / `~/.claude/agents/` globally) and activate it with `/agent [name]`. Agent definitions are also exposed to subagent delegation unless `mode: primary`. → [docs/custom-agents.md](docs/custom-agents.md)
|
|
54
|
-
- **Skills** — place a `SKILL.md` in `.agents/skills/<name>/` and inject it into any prompt with `@skill-name`. Claude-compatible `.claude/skills/<name>/SKILL.md` works too. Skills are _never_ auto-loaded — always explicit. → [docs/skills.md](docs/skills.md)
|
|
55
|
-
- **Beautiful, minimal output** — compact tool output, formatted trees for file searches, a live status bar with model, git branch, and token counts.
|
|
56
|
-
- **16 ANSI colors only** — my output inherits _your_ terminal theme. Dark mode, light mode, Solarized, Gruvbox — I fit right in.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## 🧠 Interesting Things About Me
|
|
61
|
-
|
|
62
|
-
- **I eat my own dog food.** I was built _by_ a mini-coder agent. It's agents all the way down. 🐢
|
|
63
|
-
- **I'm tiny but mighty.** The whole runtime is [Bun.js](https://bun.com) — fast startup, native TypeScript, and a built-in SQLite driver.
|
|
64
|
-
- **I respect existing conventions.** Context lives in `AGENTS.md` or `CLAUDE.md`, commands in `.agents/commands/`, agents in `.agents/agents/`, skills in `.agents/skills/` — I follow the ecosystem instead of inventing new standards.
|
|
65
|
-
- **I spin while I think.** ⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ (It's the little things.)
|
|
66
|
-
- **I can clone myself.** The `subagent` tool lets me spin up parallel instances of myself to tackle independent subtasks simultaneously. Divide and conquer! (Up to 10 levels deep.)
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 📁 Config folders
|
|
71
|
-
|
|
72
|
-
I follow the [`.agents` convention](https://github.com/agentsmd/agents) — the shared standard across AI coding tools — and I also understand `.claude` layouts for **commands**, **skills**, and **agents**.
|
|
73
|
-
|
|
74
|
-
| Path | What it does |
|
|
75
|
-
| -------------------------------- | ----------------------------------------------------- |
|
|
76
|
-
| `.agents/commands/*.md` | Custom slash commands (`/name`) |
|
|
77
|
-
| `.claude/commands/*.md` | Claude-compatible custom commands |
|
|
78
|
-
| `.agents/agents/*.md` | Custom agents |
|
|
79
|
-
| `.claude/agents/*.md` | Alternate `.claude` path for custom agents |
|
|
80
|
-
| `.agents/skills/<name>/SKILL.md` | Reusable skill instructions (`@name`) |
|
|
81
|
-
| `.claude/skills/<name>/SKILL.md` | Claude-compatible skills |
|
|
82
|
-
| `.agents/AGENTS.md` | Preferred local project context |
|
|
83
|
-
| `CLAUDE.md` | Local fallback context if `.agents/AGENTS.md` is absent |
|
|
84
|
-
| `AGENTS.md` | Local fallback context if `.agents/AGENTS.md` and `CLAUDE.md` are absent |
|
|
85
|
-
| `~/.agents/AGENTS.md` | Preferred global context, prepended before local context |
|
|
86
|
-
| `~/.agents/CLAUDE.md` | Global fallback context if `~/.agents/AGENTS.md` is absent |
|
|
87
|
-
|
|
88
|
-
Global commands, agents, and skills also work from `~/.agents/...` and `~/.claude/...`.
|
|
89
|
-
|
|
90
|
-
For commands, skills, and agents: local overrides global, and `.agents` overrides `.claude` at the same scope. Context files are combined differently: global context is injected first, then local context. → [docs/configs.md](docs/configs.md)
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## 🚀 Getting Started
|
|
17
|
+
## ⚡ Quick Start
|
|
95
18
|
|
|
96
|
-
|
|
19
|
+
I run on [Bun](https://bun.com) — install me via bun or npm, but Bun needs to be on your machine.
|
|
97
20
|
|
|
98
21
|
```bash
|
|
99
|
-
# Install
|
|
100
|
-
bun add -g mini-coder
|
|
101
|
-
# or: npm install -g mini-coder
|
|
102
|
-
|
|
103
|
-
# Set a provider key (pick one — or run Ollama locally)
|
|
104
|
-
export OPENCODE_API_KEY=your-zen-key # recommended
|
|
105
|
-
export ANTHROPIC_API_KEY=your-key # direct Anthropic
|
|
106
|
-
export OPENAI_API_KEY=your-key # direct OpenAI
|
|
107
|
-
export GOOGLE_API_KEY=your-key # direct Gemini
|
|
108
|
-
# or: export GEMINI_API_KEY=your-key
|
|
109
|
-
|
|
110
|
-
# Optional extras
|
|
111
|
-
export OLLAMA_BASE_URL=http://localhost:11434
|
|
112
|
-
export EXA_API_KEY=your-exa-key # enables webSearch/webContent
|
|
113
|
-
|
|
114
|
-
# Launch
|
|
115
|
-
mc
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Or drop me a prompt straight away for one-shot mode (runs once, then exits):
|
|
22
|
+
# Install
|
|
23
|
+
bun add -g mini-coder # or: npm install -g mini-coder
|
|
119
24
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
25
|
+
# Set one API key (pick any)
|
|
26
|
+
export OPENCODE_API_KEY=your-key # recommended
|
|
27
|
+
export ANTHROPIC_API_KEY=your-key # direct Anthropic
|
|
28
|
+
export OPENAI_API_KEY=your-key # direct OpenAI
|
|
29
|
+
export GOOGLE_API_KEY=your-key # direct Gemini (or GEMINI_API_KEY)
|
|
123
30
|
|
|
124
|
-
|
|
31
|
+
# Optional
|
|
32
|
+
export OLLAMA_BASE_URL=http://localhost:11434 # local models
|
|
33
|
+
export EXA_API_KEY=your-key # web search tools
|
|
125
34
|
|
|
126
|
-
|
|
127
|
-
mc
|
|
128
|
-
mc -r <id> # resume a specific session
|
|
129
|
-
mc -l # list recent sessions
|
|
130
|
-
mc -m zen/claude-sonnet-4-6 # pick a model
|
|
131
|
-
mc --cwd ~/src/other-project # set working directory
|
|
132
|
-
mc -h # show help
|
|
35
|
+
# Go
|
|
36
|
+
mc
|
|
133
37
|
```
|
|
134
38
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
## 🗃️ App data
|
|
138
|
-
|
|
139
|
-
Everything I remember lives in `~/.config/mini-coder/` — here's what I'm holding onto:
|
|
39
|
+
One-shot mode: `mc "refactor auth to use async/await"` — runs once, then exits.
|
|
140
40
|
|
|
141
|
-
|
|
142
|
-
- `api.log` — a request/response log for every provider call this run, if you want to peek under the hood
|
|
143
|
-
- `errors.log` — anything that went sideways, caught and written down so you can actually debug it
|
|
41
|
+
Useful flags: `-c` continue last session, `-r <id>` resume, `-l` list sessions, `-m <model>` pick a model, `-h` help.
|
|
144
42
|
|
|
145
43
|
---
|
|
146
44
|
|
|
147
|
-
##
|
|
45
|
+
## 🔑 OAuth Login
|
|
148
46
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
- [docs/custom-commands.md](docs/custom-commands.md)
|
|
152
|
-
- [docs/custom-agents.md](docs/custom-agents.md)
|
|
153
|
-
- [docs/skills.md](docs/skills.md)
|
|
154
|
-
- [docs/configs.md](docs/configs.md)
|
|
155
|
-
|
|
156
|
-
## 🗂️ Project Structure
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
src/
|
|
160
|
-
index.ts # Entry point + CLI arg parsing
|
|
161
|
-
agent/ # Main REPL loop + tool registry
|
|
162
|
-
cli/ # Input, output, slash commands, markdown rendering
|
|
163
|
-
llm-api/ # Provider factory + streaming turn logic
|
|
164
|
-
tools/ # shell, subagent, skill tools
|
|
165
|
-
# + webSearch, webContent
|
|
166
|
-
internal/ # shared internals, including the mc-edit helper implementation
|
|
167
|
-
mcp/ # MCP server connections
|
|
168
|
-
session/ # SQLite-backed session & history management
|
|
169
|
-
```
|
|
47
|
+
Use `/login` inside the REPL to authenticate via browser-based OAuth (currently Anthropic). No need to manage API keys manually.
|
|
170
48
|
|
|
171
49
|
---
|
|
172
50
|
|
|
173
|
-
##
|
|
51
|
+
## 🛠️ Features
|
|
174
52
|
|
|
175
|
-
- **
|
|
176
|
-
- **
|
|
177
|
-
- **
|
|
178
|
-
- **
|
|
179
|
-
- **
|
|
180
|
-
- **
|
|
53
|
+
- **Multi-provider** — auto-discovers Anthropic, OpenAI, Gemini, Ollama, or any OpenAI-compatible endpoint
|
|
54
|
+
- **Session memory** — SQLite-backed. Resume with `-c` or `-r <id>`
|
|
55
|
+
- **Shell integration** — `!` prefix for inline commands, `@` to reference files with tab completion
|
|
56
|
+
- **Subagents** — spawn parallel mini-coder instances for independent subtasks
|
|
57
|
+
- **Web search** — `webSearch` + `webContent` tools when `EXA_API_KEY` is set
|
|
58
|
+
- **MCP support** — connect external tool servers over HTTP or stdio
|
|
59
|
+
- **Custom commands** — drop `.md` files in `.agents/commands/` → instant `/slash` commands
|
|
60
|
+
- **Custom agents** — `.agents/agents/*.md` for specialized personas, usable as primary or via subagent
|
|
61
|
+
- **Skills** — `.agents/skills/<name>/SKILL.md`, inject with `@name`
|
|
62
|
+
- **`mc-edit`** — safe, exact-text file editing (no full-file rewrites)
|
|
63
|
+
- **16 ANSI colors** — inherits your terminal theme. Always looks right.
|
|
181
64
|
|
|
182
65
|
---
|
|
183
66
|
|
|
184
|
-
##
|
|
67
|
+
## 📚 Getting Deeper
|
|
185
68
|
|
|
186
|
-
|
|
69
|
+
The README is the highlight reel. For the full story — slash commands, config folders, context files, app data, and everything else:
|
|
187
70
|
|
|
188
|
-
|
|
71
|
+
**[📖 Read the Full Manual](docs/mini-coder.1.md)**
|
|
189
72
|
|
|
190
73
|
---
|
|
191
74
|
|
|
192
|
-
##
|
|
75
|
+
## 🔮 Tech Stack
|
|
193
76
|
|
|
194
|
-
|
|
195
|
-
> — [vpr99](https://github.com/vpr99)
|
|
77
|
+
[Bun.js](https://bun.com) · [AI SDK](https://ai-sdk.dev) · [yoctocolors](https://github.com/sindresorhus/yoctocolors)
|
|
196
78
|
|
|
197
|
-
|
|
79
|
+
## 📄 License
|
|
198
80
|
|
|
199
|
-
|
|
81
|
+
MIT — [github.com/sacenox/mini-coder](https://github.com/sacenox/mini-coder)
|
package/dist/mc.js
CHANGED
|
@@ -9,7 +9,7 @@ import * as c23 from "yoctocolors";
|
|
|
9
9
|
import * as c12 from "yoctocolors";
|
|
10
10
|
|
|
11
11
|
// src/cli/load-markdown-configs.ts
|
|
12
|
-
import { existsSync as existsSync4, readdirSync as
|
|
12
|
+
import { existsSync as existsSync4, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
|
|
13
13
|
import { homedir as homedir4 } from "os";
|
|
14
14
|
import { basename, join as join5 } from "path";
|
|
15
15
|
|
|
@@ -99,16 +99,58 @@ ${content}
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
// src/cli/error-log.ts
|
|
102
|
-
import {
|
|
102
|
+
import { writeFileSync } from "fs";
|
|
103
|
+
|
|
104
|
+
// src/cli/log-paths.ts
|
|
105
|
+
import { mkdirSync, readdirSync, unlinkSync } from "fs";
|
|
103
106
|
import { homedir } from "os";
|
|
104
107
|
import { join as join2 } from "path";
|
|
108
|
+
var LOGS_DIR = join2(homedir(), ".config", "mini-coder", "logs");
|
|
109
|
+
function getLogsDir() {
|
|
110
|
+
mkdirSync(LOGS_DIR, { recursive: true });
|
|
111
|
+
return LOGS_DIR;
|
|
112
|
+
}
|
|
113
|
+
function pidLogPath(prefix) {
|
|
114
|
+
return join2(getLogsDir(), `${prefix}-${process.pid}.log`);
|
|
115
|
+
}
|
|
116
|
+
function isProcessAlive(pid) {
|
|
117
|
+
try {
|
|
118
|
+
process.kill(pid, 0);
|
|
119
|
+
return true;
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
var LOG_FILE_RE = /^(api|errors)-(\d+)\.log$/;
|
|
125
|
+
function cleanStaleLogs() {
|
|
126
|
+
let entries;
|
|
127
|
+
try {
|
|
128
|
+
entries = readdirSync(LOGS_DIR);
|
|
129
|
+
} catch {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
for (const name of entries) {
|
|
133
|
+
const m = LOG_FILE_RE.exec(name);
|
|
134
|
+
if (!m)
|
|
135
|
+
continue;
|
|
136
|
+
const pidStr = m[2];
|
|
137
|
+
const pid = Number.parseInt(pidStr, 10);
|
|
138
|
+
if (pid === process.pid)
|
|
139
|
+
continue;
|
|
140
|
+
if (!isProcessAlive(pid)) {
|
|
141
|
+
try {
|
|
142
|
+
unlinkSync(join2(LOGS_DIR, name));
|
|
143
|
+
} catch {}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/cli/error-log.ts
|
|
105
149
|
var writer = null;
|
|
106
150
|
function initErrorLog() {
|
|
107
151
|
if (writer)
|
|
108
152
|
return;
|
|
109
|
-
const
|
|
110
|
-
const logPath = join2(dirPath, "errors.log");
|
|
111
|
-
mkdirSync(dirPath, { recursive: true });
|
|
153
|
+
const logPath = pidLogPath("errors");
|
|
112
154
|
writeFileSync(logPath, "");
|
|
113
155
|
writer = Bun.file(logPath).writer();
|
|
114
156
|
process.on("uncaughtException", (err) => {
|
|
@@ -295,7 +337,7 @@ import {
|
|
|
295
337
|
closeSync,
|
|
296
338
|
existsSync as existsSync2,
|
|
297
339
|
openSync,
|
|
298
|
-
readdirSync,
|
|
340
|
+
readdirSync as readdirSync2,
|
|
299
341
|
readFileSync as readFileSync2,
|
|
300
342
|
readSync,
|
|
301
343
|
statSync
|
|
@@ -384,7 +426,7 @@ function listSkillCandidates(skillsDir, source, rootPath) {
|
|
|
384
426
|
return [];
|
|
385
427
|
let entries;
|
|
386
428
|
try {
|
|
387
|
-
entries =
|
|
429
|
+
entries = readdirSync2(skillsDir).sort((a, b) => a.localeCompare(b));
|
|
388
430
|
} catch {
|
|
389
431
|
return [];
|
|
390
432
|
}
|
|
@@ -1761,7 +1803,7 @@ async function renderTurn(events, spinner, opts) {
|
|
|
1761
1803
|
|
|
1762
1804
|
// src/cli/output.ts
|
|
1763
1805
|
var HOME = homedir3();
|
|
1764
|
-
var PACKAGE_VERSION = "0.1.
|
|
1806
|
+
var PACKAGE_VERSION = "0.1.1";
|
|
1765
1807
|
function tildePath(p) {
|
|
1766
1808
|
return p.startsWith(HOME) ? `~${p.slice(HOME.length)}` : p;
|
|
1767
1809
|
}
|
|
@@ -1984,7 +2026,7 @@ function loadMarkdownConfigs(opts) {
|
|
|
1984
2026
|
return configs;
|
|
1985
2027
|
let entries;
|
|
1986
2028
|
try {
|
|
1987
|
-
entries =
|
|
2029
|
+
entries = readdirSync3(dir);
|
|
1988
2030
|
} catch {
|
|
1989
2031
|
return configs;
|
|
1990
2032
|
}
|
|
@@ -2124,7 +2166,7 @@ async function connectMcpServer(config) {
|
|
|
2124
2166
|
|
|
2125
2167
|
// src/session/db/connection.ts
|
|
2126
2168
|
import { Database } from "bun:sqlite";
|
|
2127
|
-
import { existsSync as existsSync5, mkdirSync as mkdirSync2, unlinkSync } from "fs";
|
|
2169
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "fs";
|
|
2128
2170
|
import { homedir as homedir5 } from "os";
|
|
2129
2171
|
import { join as join6 } from "path";
|
|
2130
2172
|
function getConfigDir() {
|
|
@@ -2255,7 +2297,7 @@ function getDb() {
|
|
|
2255
2297
|
} catch {}
|
|
2256
2298
|
for (const path of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
|
|
2257
2299
|
if (existsSync5(path))
|
|
2258
|
-
|
|
2300
|
+
unlinkSync2(path);
|
|
2259
2301
|
}
|
|
2260
2302
|
db = new Database(dbPath, { create: true });
|
|
2261
2303
|
configureDb(db);
|
|
@@ -3538,17 +3580,13 @@ async function getAccessToken(providerId) {
|
|
|
3538
3580
|
}
|
|
3539
3581
|
|
|
3540
3582
|
// src/llm-api/api-log.ts
|
|
3541
|
-
import {
|
|
3542
|
-
import { homedir as homedir6 } from "os";
|
|
3543
|
-
import { join as join9 } from "path";
|
|
3583
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
3544
3584
|
var writer2 = null;
|
|
3545
3585
|
var MAX_ENTRY_BYTES = 8 * 1024;
|
|
3546
3586
|
function initApiLog() {
|
|
3547
3587
|
if (writer2)
|
|
3548
3588
|
return;
|
|
3549
|
-
const
|
|
3550
|
-
const logPath = join9(dirPath, "api.log");
|
|
3551
|
-
mkdirSync3(dirPath, { recursive: true });
|
|
3589
|
+
const logPath = pidLogPath("api");
|
|
3552
3590
|
writeFileSync2(logPath, "");
|
|
3553
3591
|
writer2 = Bun.file(logPath).writer();
|
|
3554
3592
|
}
|
|
@@ -3969,24 +4007,31 @@ async function fetchOpenAIModels() {
|
|
|
3969
4007
|
free: false
|
|
3970
4008
|
}));
|
|
3971
4009
|
}
|
|
3972
|
-
async function
|
|
4010
|
+
async function getAnthropicAuth() {
|
|
3973
4011
|
const envKey = process.env.ANTHROPIC_API_KEY;
|
|
3974
4012
|
if (envKey)
|
|
3975
|
-
return envKey;
|
|
3976
|
-
if (isLoggedIn("anthropic"))
|
|
3977
|
-
|
|
4013
|
+
return { key: envKey, oauth: false };
|
|
4014
|
+
if (isLoggedIn("anthropic")) {
|
|
4015
|
+
const token = await getAccessToken("anthropic");
|
|
4016
|
+
if (token)
|
|
4017
|
+
return { key: token, oauth: true };
|
|
4018
|
+
}
|
|
3978
4019
|
return null;
|
|
3979
4020
|
}
|
|
3980
4021
|
async function fetchAnthropicModels() {
|
|
3981
|
-
const
|
|
3982
|
-
if (!
|
|
4022
|
+
const auth = await getAnthropicAuth();
|
|
4023
|
+
if (!auth)
|
|
3983
4024
|
return null;
|
|
3984
|
-
const
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
}
|
|
3989
|
-
|
|
4025
|
+
const headers = {
|
|
4026
|
+
"anthropic-version": "2023-06-01"
|
|
4027
|
+
};
|
|
4028
|
+
if (auth.oauth) {
|
|
4029
|
+
headers.Authorization = `Bearer ${auth.key}`;
|
|
4030
|
+
headers["anthropic-beta"] = "oauth-2025-04-20";
|
|
4031
|
+
} else {
|
|
4032
|
+
headers["x-api-key"] = auth.key;
|
|
4033
|
+
}
|
|
4034
|
+
const payload = await fetchJson(`${ANTHROPIC_BASE}/v1/models`, { headers }, 6000);
|
|
3990
4035
|
return processModelsList(payload, "data", "id", (item, modelId) => {
|
|
3991
4036
|
const displayName = typeof item.display_name === "string" && item.display_name.trim().length > 0 ? item.display_name : modelId;
|
|
3992
4037
|
return {
|
|
@@ -5523,8 +5568,8 @@ function getMostRecentSession() {
|
|
|
5523
5568
|
|
|
5524
5569
|
// src/agent/system-prompt.ts
|
|
5525
5570
|
import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
|
|
5526
|
-
import { homedir as
|
|
5527
|
-
import { join as
|
|
5571
|
+
import { homedir as homedir6 } from "os";
|
|
5572
|
+
import { join as join9 } from "path";
|
|
5528
5573
|
function tryReadFile(p) {
|
|
5529
5574
|
if (!existsSync6(p))
|
|
5530
5575
|
return null;
|
|
@@ -5535,11 +5580,11 @@ function tryReadFile(p) {
|
|
|
5535
5580
|
}
|
|
5536
5581
|
}
|
|
5537
5582
|
function loadGlobalContextFile(homeDir) {
|
|
5538
|
-
const globalDir =
|
|
5539
|
-
return tryReadFile(
|
|
5583
|
+
const globalDir = join9(homeDir, ".agents");
|
|
5584
|
+
return tryReadFile(join9(globalDir, "AGENTS.md")) ?? tryReadFile(join9(globalDir, "CLAUDE.md"));
|
|
5540
5585
|
}
|
|
5541
5586
|
function loadLocalContextFile(cwd) {
|
|
5542
|
-
return tryReadFile(
|
|
5587
|
+
return tryReadFile(join9(cwd, ".agents", "AGENTS.md")) ?? tryReadFile(join9(cwd, "CLAUDE.md")) ?? tryReadFile(join9(cwd, "AGENTS.md"));
|
|
5543
5588
|
}
|
|
5544
5589
|
var AUTONOMY = `
|
|
5545
5590
|
|
|
@@ -5581,7 +5626,7 @@ var FINAL_MESSAGE = `
|
|
|
5581
5626
|
- If verification could not be run, say so clearly.`;
|
|
5582
5627
|
var SUBAGENT_DELEGATION = `You are running as a subagent. Complete the task you have been given directly using your tools. Do not spawn further subagents unless the subtask is unambiguously separable and self-contained.`;
|
|
5583
5628
|
function buildSystemPrompt(sessionTimeAnchor, cwd, extraSystemPrompt, isSubagent, homeDir) {
|
|
5584
|
-
const globalContext = loadGlobalContextFile(homeDir ??
|
|
5629
|
+
const globalContext = loadGlobalContextFile(homeDir ?? homedir6());
|
|
5585
5630
|
const localContext = loadLocalContextFile(cwd);
|
|
5586
5631
|
const cwdDisplay = tildePath(cwd);
|
|
5587
5632
|
let prompt = `You are mini-coder, a small and fast CLI coding agent.
|
|
@@ -6130,7 +6175,7 @@ import { z as z2 } from "zod";
|
|
|
6130
6175
|
|
|
6131
6176
|
// src/internal/file-edit/command.ts
|
|
6132
6177
|
import { existsSync as existsSync7 } from "fs";
|
|
6133
|
-
import { dirname as dirname2, extname, join as
|
|
6178
|
+
import { dirname as dirname2, extname, join as join10 } from "path";
|
|
6134
6179
|
import { fileURLToPath } from "url";
|
|
6135
6180
|
function quoteShellArg(value) {
|
|
6136
6181
|
return `'${value.replaceAll("'", `'\\''`)}'`;
|
|
@@ -6142,7 +6187,7 @@ function resolveSiblingFileEditScript(scriptPath) {
|
|
|
6142
6187
|
const mainDir = dirname2(scriptPath);
|
|
6143
6188
|
const mainBase = scriptPath.slice(mainDir.length + 1);
|
|
6144
6189
|
if (mainBase === `index${ext}` || mainBase === `mc${ext}`) {
|
|
6145
|
-
return
|
|
6190
|
+
return join10(mainDir, `mc-edit${ext}`);
|
|
6146
6191
|
}
|
|
6147
6192
|
return null;
|
|
6148
6193
|
}
|
|
@@ -6151,7 +6196,7 @@ function resolveModuleLocalFileEditScript(moduleUrl) {
|
|
|
6151
6196
|
const ext = extname(modulePath);
|
|
6152
6197
|
if (!ext)
|
|
6153
6198
|
return null;
|
|
6154
|
-
const helperPath =
|
|
6199
|
+
const helperPath = join10(dirname2(modulePath), "..", "..", `mc-edit${ext}`);
|
|
6155
6200
|
return existsSync7(helperPath) ? helperPath : null;
|
|
6156
6201
|
}
|
|
6157
6202
|
function resolveFileEditCommand(execPath, mainModule, argv1, moduleUrl = import.meta.url) {
|
|
@@ -6617,9 +6662,9 @@ ${c13.bold("Examples:")}`);
|
|
|
6617
6662
|
}
|
|
6618
6663
|
|
|
6619
6664
|
// src/cli/bootstrap.ts
|
|
6620
|
-
import { existsSync as existsSync8, mkdirSync as
|
|
6621
|
-
import { homedir as
|
|
6622
|
-
import { join as
|
|
6665
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
6666
|
+
import { homedir as homedir7 } from "os";
|
|
6667
|
+
import { join as join11 } from "path";
|
|
6623
6668
|
import * as c14 from "yoctocolors";
|
|
6624
6669
|
var REVIEW_COMMAND_CONTENT = `---
|
|
6625
6670
|
description: Review recent changes for correctness, code quality, and performance
|
|
@@ -6639,17 +6684,17 @@ Perform a sensible code review:
|
|
|
6639
6684
|
Output a small summary with only the issues found. If nothing is wrong, say so.
|
|
6640
6685
|
`;
|
|
6641
6686
|
function bootstrapGlobalDefaults() {
|
|
6642
|
-
const commandsDir =
|
|
6643
|
-
const reviewPath =
|
|
6687
|
+
const commandsDir = join11(homedir7(), ".agents", "commands");
|
|
6688
|
+
const reviewPath = join11(commandsDir, "review.md");
|
|
6644
6689
|
if (!existsSync8(reviewPath)) {
|
|
6645
|
-
|
|
6690
|
+
mkdirSync3(commandsDir, { recursive: true });
|
|
6646
6691
|
writeFileSync3(reviewPath, REVIEW_COMMAND_CONTENT, "utf-8");
|
|
6647
6692
|
writeln(`${c14.green("\u2713")} created ${c14.dim("~/.agents/commands/review.md")} ${c14.dim("(edit it to customise your reviews)")}`);
|
|
6648
6693
|
}
|
|
6649
6694
|
}
|
|
6650
6695
|
|
|
6651
6696
|
// src/cli/file-refs.ts
|
|
6652
|
-
import { join as
|
|
6697
|
+
import { join as join12 } from "path";
|
|
6653
6698
|
async function resolveFileRefs(text, cwd) {
|
|
6654
6699
|
const atPattern = /@([\w./\-_]+)/g;
|
|
6655
6700
|
let result = text;
|
|
@@ -6677,7 +6722,7 @@ ${content}
|
|
|
6677
6722
|
result = result.slice(0, match.index) + replacement + result.slice((match.index ?? 0) + match[0].length);
|
|
6678
6723
|
continue;
|
|
6679
6724
|
}
|
|
6680
|
-
const filePath = ref.startsWith("/") ? ref :
|
|
6725
|
+
const filePath = ref.startsWith("/") ? ref : join12(cwd, ref);
|
|
6681
6726
|
if (isImageFilename(ref)) {
|
|
6682
6727
|
const attachment = await loadImageFile(filePath);
|
|
6683
6728
|
if (attachment) {
|
|
@@ -7606,6 +7651,9 @@ function writeJsonLine(write2, payload) {
|
|
|
7606
7651
|
registerTerminalCleanup();
|
|
7607
7652
|
initErrorLog();
|
|
7608
7653
|
initApiLog();
|
|
7654
|
+
if (!process.env.MC_SUBAGENT_DEPTH || process.env.MC_SUBAGENT_DEPTH === "0") {
|
|
7655
|
+
cleanStaleLogs();
|
|
7656
|
+
}
|
|
7609
7657
|
initModelInfoCache();
|
|
7610
7658
|
pruneOldData();
|
|
7611
7659
|
refreshModelInfoInBackground().catch(() => {});
|
package/docs/mini-coder.1.md
CHANGED
|
@@ -1,156 +1,275 @@
|
|
|
1
1
|
# MINI-CODER(1)
|
|
2
2
|
|
|
3
3
|
## NAME
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
**mini-coder** — a small, fast CLI coding agent (executable: `mc`)
|
|
5
6
|
|
|
6
7
|
## SYNOPSIS
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
`mc` \[*options*\] \[*prompt*\]
|
|
8
10
|
|
|
9
11
|
## DESCRIPTION
|
|
10
|
-
|
|
12
|
+
|
|
13
|
+
Developer-focused CLI coding agent. Prioritizes dev flow — no slow startup, no GUI, no vendor lock-in. Uses 16 ANSI colors to inherit terminal theme. Built on Bun.js.
|
|
11
14
|
|
|
12
15
|
## OPTIONS
|
|
13
|
-
**-m, --model <id>**
|
|
14
|
-
: Specify the model to use (e.g., `zen/claude-sonnet-4-6`).
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
:
|
|
17
|
+
`-m`, `--model` *id*
|
|
18
|
+
: Model to use (e.g. `zen/claude-sonnet-4-6`).
|
|
19
|
+
|
|
20
|
+
`-c`, `--continue`
|
|
21
|
+
: Continue most recent session.
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
:
|
|
23
|
+
`-r`, `--resume` *id*
|
|
24
|
+
: Resume a specific session.
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
:
|
|
26
|
+
`-l`, `--list`
|
|
27
|
+
: List recent sessions.
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
:
|
|
29
|
+
`--cwd` *path*
|
|
30
|
+
: Set working directory.
|
|
27
31
|
|
|
28
|
-
|
|
29
|
-
:
|
|
32
|
+
`-h`, `--help`
|
|
33
|
+
: Display help.
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
:
|
|
35
|
+
*prompt*
|
|
36
|
+
: Optional one-shot prompt. Runs once then exits.
|
|
33
37
|
|
|
34
38
|
## INTERACTIVE COMMANDS
|
|
35
|
-
Inside the interactive session, the following slash commands are available:
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
:
|
|
40
|
+
`/model`
|
|
41
|
+
: List all available models.
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
:
|
|
43
|
+
`/model` *id*
|
|
44
|
+
: Switch model.
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
:
|
|
46
|
+
`/model effort` *low|medium|high|xhigh|off*
|
|
47
|
+
: Set reasoning effort.
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
:
|
|
49
|
+
`/reasoning` \[*on|off*\]
|
|
50
|
+
: Toggle reasoning display.
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
:
|
|
52
|
+
`/context prune` *off|balanced|aggressive*
|
|
53
|
+
: Pruning strategy.
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
:
|
|
55
|
+
`/context cap` *off|bytes|kb*
|
|
56
|
+
: Tool result payload cap.
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
:
|
|
58
|
+
`/cache` *on|off*
|
|
59
|
+
: Toggle prompt caching globally.
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
:
|
|
61
|
+
`/cache openai` *in_memory|24h*
|
|
62
|
+
: OpenAI cache retention.
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
:
|
|
64
|
+
`/cache gemini` *off|cachedContents/...*
|
|
65
|
+
: Gemini cached content.
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
:
|
|
67
|
+
`/undo`
|
|
68
|
+
: Remove last turn (does NOT revert filesystem).
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
:
|
|
70
|
+
`/new`
|
|
71
|
+
: Start a fresh session.
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
:
|
|
73
|
+
`/verbose`
|
|
74
|
+
: Toggle output truncation.
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
:
|
|
76
|
+
`/mcp list`
|
|
77
|
+
: List MCP servers.
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
:
|
|
79
|
+
`/mcp add` *name* `http` *url*
|
|
80
|
+
: Add HTTP MCP server.
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
:
|
|
82
|
+
`/mcp add` *name* `stdio` *cmd* \[*args...*\]
|
|
83
|
+
: Add stdio MCP server.
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
:
|
|
85
|
+
`/mcp remove` *name*
|
|
86
|
+
: Remove MCP server.
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
:
|
|
88
|
+
`/agent` \[*name*\]
|
|
89
|
+
: Set or clear active primary agent.
|
|
87
90
|
|
|
91
|
+
`/review`
|
|
92
|
+
: Review changes (custom command, auto-created globally).
|
|
88
93
|
|
|
89
|
-
|
|
90
|
-
:
|
|
94
|
+
`/login`
|
|
95
|
+
: Show OAuth login status.
|
|
91
96
|
|
|
92
|
-
|
|
93
|
-
:
|
|
97
|
+
`/login` *provider*
|
|
98
|
+
: Login via OAuth (opens browser for device flow). Currently supports `anthropic`.
|
|
99
|
+
|
|
100
|
+
`/logout` *provider*
|
|
101
|
+
: Clear saved OAuth tokens.
|
|
102
|
+
|
|
103
|
+
`/help`
|
|
104
|
+
: Command help.
|
|
105
|
+
|
|
106
|
+
`/exit`, `/quit`, `/q`
|
|
107
|
+
: Leave session.
|
|
94
108
|
|
|
95
109
|
## INLINE FEATURES
|
|
96
|
-
**Shell Integration**
|
|
97
|
-
: Prefix user prompts with `!` to run shell commands inline directly into the context.
|
|
98
110
|
|
|
99
|
-
|
|
100
|
-
:
|
|
111
|
+
`!` prefix
|
|
112
|
+
: Runs shell commands inline.
|
|
113
|
+
|
|
114
|
+
`@` prefix
|
|
115
|
+
: References files or skills (with tab completion).
|
|
101
116
|
|
|
102
117
|
## BUILT-IN TOOLS
|
|
103
|
-
The agent has access to the following tools:
|
|
104
|
-
* **shell**: Execute bash commands and capture output. Repo inspection and targeted file edits are typically done here via `mc-edit`.
|
|
105
|
-
* **subagent**: Spawn a focused mini-agent with a prompt.
|
|
106
|
-
* **listSkills**: List discovered skills without loading full skill bodies.
|
|
107
|
-
* **readSkill**: Load one `SKILL.md` on demand.
|
|
108
|
-
* **webSearch**: Search the internet (requires EXA key).
|
|
109
|
-
* **webContent**: Fetch full page content from a URL (requires EXA key).
|
|
110
|
-
* **MCP tools**: Connected external tools attached dynamically from configured MCP servers.
|
|
111
|
-
|
|
112
|
-
## FILE EDIT HELPER
|
|
113
|
-
**mc-edit**
|
|
114
|
-
: Helper command used from shell for one exact-text edit on an existing file. On success it prints a human-readable plain unified diff to stdout followed by a short metadata block (`ok`, `path`, `changed`). If the edit is a no-op, it prints `(no changes)` plus the same metadata. Errors are written to stderr.
|
|
115
118
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
**shell**
|
|
120
|
+
: Execute bash commands; repo inspection and `mc-edit` edits happen here.
|
|
121
|
+
|
|
122
|
+
**subagent**
|
|
123
|
+
: Spawn a focused mini-agent for parallel subtasks.
|
|
124
|
+
|
|
125
|
+
**listSkills**
|
|
126
|
+
: List discovered skills (metadata only).
|
|
127
|
+
|
|
128
|
+
**readSkill**
|
|
129
|
+
: Load one SKILL.md on demand.
|
|
130
|
+
|
|
131
|
+
**webSearch**
|
|
132
|
+
: Search the web (requires `EXA_API_KEY`).
|
|
133
|
+
|
|
134
|
+
**webContent**
|
|
135
|
+
: Fetch page content (requires `EXA_API_KEY`).
|
|
136
|
+
|
|
137
|
+
MCP tools are connected dynamically from configured MCP servers.
|
|
138
|
+
|
|
139
|
+
## FILE EDITING — mc-edit
|
|
140
|
+
|
|
141
|
+
`mc-edit` is the helper for targeted file edits, invoked from **shell**.
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
mc-edit <path> (--old <text> | --old-file <path>) [--new <text> | --new-file <path>] [--cwd <path>]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- Applies one exact-text edit to an existing file.
|
|
148
|
+
- The old text must match exactly once.
|
|
149
|
+
- Omit `--new`/`--new-file` to delete the matched text.
|
|
150
|
+
- Success: prints unified diff + metadata (`ok`, `path`, `changed`).
|
|
151
|
+
- No-op: prints `(no changes)` + metadata.
|
|
152
|
+
- Errors go to stderr.
|
|
153
|
+
|
|
154
|
+
Workflow: inspect with **shell** → edit with **mc-edit** → verify with **shell**.
|
|
155
|
+
|
|
156
|
+
## CUSTOM COMMANDS
|
|
157
|
+
|
|
158
|
+
Drop a `.md` file in `.agents/commands/` (local) or `~/.agents/commands/` (global) and it becomes a `/command`. Filename equals command name (`standup.md` → `/standup`).
|
|
159
|
+
|
|
160
|
+
`.claude/commands/*.md` is also supported.
|
|
161
|
+
|
|
162
|
+
**Frontmatter fields:**
|
|
163
|
+
|
|
164
|
+
`description`
|
|
165
|
+
: Shown in `/help`.
|
|
166
|
+
|
|
167
|
+
`model`
|
|
168
|
+
: Override model (only with `context: fork`).
|
|
169
|
+
|
|
170
|
+
`context`
|
|
171
|
+
: `fork` to run as isolated subagent; default is inline.
|
|
172
|
+
|
|
173
|
+
`subtask`
|
|
174
|
+
: `true` forces subagent (OpenCode-compatible alias).
|
|
175
|
+
|
|
176
|
+
`agent`
|
|
177
|
+
: Run under named agent's system prompt (only with `context: fork`).
|
|
178
|
+
|
|
179
|
+
**Argument substitution:**
|
|
119
180
|
|
|
120
|
-
|
|
121
|
-
|
|
181
|
+
`$ARGUMENTS` expands to the full argument string; `$1`–`$9` expand to positional tokens.
|
|
182
|
+
|
|
183
|
+
**Shell interpolation:**
|
|
184
|
+
|
|
185
|
+
`` !`cmd` `` injects shell output at expansion time (10 s timeout).
|
|
186
|
+
|
|
187
|
+
**Precedence:** custom commands shadow built-ins. Local overrides global.
|
|
188
|
+
|
|
189
|
+
## CUSTOM AGENTS
|
|
190
|
+
|
|
191
|
+
Drop a `.md` file in `.agents/agents/` (local) or `~/.agents/agents/` (global). Filename equals agent name. Activate with `/agent <name>`.
|
|
192
|
+
|
|
193
|
+
`.claude/agents/*.md` is also supported.
|
|
194
|
+
|
|
195
|
+
**Frontmatter fields:**
|
|
196
|
+
|
|
197
|
+
`description`
|
|
198
|
+
: Shown in `/help`.
|
|
199
|
+
|
|
200
|
+
`model`
|
|
201
|
+
: Override active model.
|
|
202
|
+
|
|
203
|
+
`mode`
|
|
204
|
+
: `primary` excludes from subagent tool; `subagent`/`all`/omitted keeps it available.
|
|
205
|
+
|
|
206
|
+
Body is the agent system prompt. Non-primary agents are exposed to the **subagent** tool for delegation.
|
|
207
|
+
|
|
208
|
+
## SKILLS
|
|
209
|
+
|
|
210
|
+
Skills are reusable instruction files at `.agents/skills/<name>/SKILL.md`.
|
|
211
|
+
|
|
212
|
+
`.claude/skills/<name>/SKILL.md` is also supported.
|
|
213
|
+
|
|
214
|
+
**Frontmatter (both required):**
|
|
215
|
+
|
|
216
|
+
`name`
|
|
217
|
+
: Lowercase alphanumeric + hyphens, 1–64 chars.
|
|
218
|
+
|
|
219
|
+
`description`
|
|
220
|
+
: Help text.
|
|
221
|
+
|
|
222
|
+
Skills are never auto-loaded. Load explicitly:
|
|
223
|
+
|
|
224
|
+
- `@skill-name` in prompts (injects body wrapped in `<skill>` XML).
|
|
225
|
+
- **listSkills** / **readSkill** tools at runtime.
|
|
226
|
+
|
|
227
|
+
Local discovery walks up from cwd to the git worktree root.
|
|
228
|
+
|
|
229
|
+
## CONFIGURATION
|
|
230
|
+
|
|
231
|
+
Supports `.agents` and `.claude` layouts for commands, skills, agents, and context.
|
|
232
|
+
|
|
233
|
+
Config roots: `.agents/`, `.claude/` — local (repo) or global (`~/`).
|
|
234
|
+
|
|
235
|
+
**Context files** (one global + one local loaded):
|
|
236
|
+
|
|
237
|
+
- Global: `~/.agents/AGENTS.md` → `~/.agents/CLAUDE.md`
|
|
238
|
+
- Local: `./.agents/AGENTS.md` → `./CLAUDE.md` → `./AGENTS.md`
|
|
239
|
+
|
|
240
|
+
**Precedence:**
|
|
241
|
+
|
|
242
|
+
1. Local overrides global.
|
|
243
|
+
2. Same scope: `.agents` wins over `.claude`.
|
|
244
|
+
3. Skills: nearest ancestor directory wins.
|
|
245
|
+
|
|
246
|
+
## ENVIRONMENT
|
|
122
247
|
|
|
123
|
-
|
|
124
|
-
:
|
|
248
|
+
`OPENCODE_API_KEY`
|
|
249
|
+
: OpenCode Zen (recommended).
|
|
125
250
|
|
|
126
|
-
|
|
127
|
-
:
|
|
251
|
+
`ANTHROPIC_API_KEY`
|
|
252
|
+
: Direct Anthropic.
|
|
128
253
|
|
|
129
|
-
|
|
130
|
-
:
|
|
254
|
+
`OPENAI_API_KEY`
|
|
255
|
+
: Direct OpenAI.
|
|
131
256
|
|
|
132
|
-
|
|
133
|
-
:
|
|
257
|
+
`GOOGLE_API_KEY` / `GEMINI_API_KEY`
|
|
258
|
+
: Direct Gemini.
|
|
134
259
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
: Application data directory. Contains `sessions.db` (SQLite database for session history, MCP server configs, and model metadata), `api.log`, and `errors.log`.
|
|
260
|
+
`OLLAMA_BASE_URL`
|
|
261
|
+
: Ollama local (defaults to `http://localhost:11434`).
|
|
138
262
|
|
|
139
|
-
|
|
140
|
-
:
|
|
141
|
-
* **commands/*.md**: Custom slash commands.
|
|
142
|
-
* **agents/*.md**: Custom behavioral wrappers or subagents.
|
|
143
|
-
* **skills/<name>/SKILL.md**: Isolated context/instruction snippets.
|
|
263
|
+
`EXA_API_KEY`
|
|
264
|
+
: Enables **webSearch** / **webContent**.
|
|
144
265
|
|
|
145
|
-
|
|
146
|
-
: Auto-loaded system context files for project-specific instructions.
|
|
266
|
+
## FILES
|
|
147
267
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
* **Session Memory**: Persists conversation history in a local SQLite database, allowing users to resume past sessions effortlessly.
|
|
151
|
-
* **Subagent Delegation**: Includes a tool to spawn parallel instances of itself to tackle independent subtasks simultaneously (up to 10 levels deep).
|
|
152
|
-
* **Model Context Protocol (MCP)**: Native support for connecting external tools via MCP servers over HTTP or stdio.
|
|
153
|
-
* **Prompt Caching**: Configurable caching behaviors for supported providers (OpenAI, Gemini).
|
|
154
|
-
* **Undo Functionality**: Remove the last conversation turn from the current session history. It does not restore filesystem changes.
|
|
268
|
+
`~/.config/mini-coder/`
|
|
269
|
+
: App data directory (sessions.db, api.log, errors.log).
|
|
155
270
|
|
|
271
|
+
`.agents/` or `.claude/`
|
|
272
|
+
: Config directories for commands, agents, skills.
|
|
156
273
|
|
|
274
|
+
`AGENTS.md` / `CLAUDE.md`
|
|
275
|
+
: Project context files.
|
package/package.json
CHANGED
package/docs/configs.md
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# Config conventions
|
|
2
|
-
|
|
3
|
-
mini-coder supports both its native `.agents` convention and `.claude` layouts for commands, skills, and agents.
|
|
4
|
-
|
|
5
|
-
Only commands, skills, agents, and context files are loaded from these roots. Hook directories are ignored.
|
|
6
|
-
|
|
7
|
-
Discovery is not identical for every config type:
|
|
8
|
-
|
|
9
|
-
- **Commands** and **agents** are loaded from the current working directory and the home directory only.
|
|
10
|
-
- **Skills** are loaded from the home directory plus local directories discovered by walking up from the current working directory to the git worktree root.
|
|
11
|
-
- **Context files** are only loaded from the current working directory and the home directory.
|
|
12
|
-
|
|
13
|
-
## Supported config roots
|
|
14
|
-
|
|
15
|
-
| Root | Purpose |
|
|
16
|
-
|---|---|
|
|
17
|
-
| `.agents/` | mini-coder native config |
|
|
18
|
-
| `.claude/` | Alternate config layout supported by mini-coder |
|
|
19
|
-
|
|
20
|
-
Each root can exist in:
|
|
21
|
-
|
|
22
|
-
- **Local (repo):** `./.agents`, `./.claude`
|
|
23
|
-
- **Global (home):** `~/.agents`, `~/.claude`
|
|
24
|
-
|
|
25
|
-
## Commands
|
|
26
|
-
|
|
27
|
-
Supported locations:
|
|
28
|
-
|
|
29
|
-
- `./.agents/commands/*.md`
|
|
30
|
-
- `~/.agents/commands/*.md`
|
|
31
|
-
- `./.claude/commands/*.md`
|
|
32
|
-
- `~/.claude/commands/*.md`
|
|
33
|
-
|
|
34
|
-
Format:
|
|
35
|
-
|
|
36
|
-
```md
|
|
37
|
-
---
|
|
38
|
-
description: Optional help text
|
|
39
|
-
model: optional/model-override
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
Prompt template body with $ARGUMENTS and $1..$9 support.
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Filename becomes the command name (`review.md` => `/review`).
|
|
46
|
-
|
|
47
|
-
## Skills
|
|
48
|
-
|
|
49
|
-
Supported locations:
|
|
50
|
-
|
|
51
|
-
- local: `./.agents/skills/<skill-name>/SKILL.md` and `./.claude/skills/<skill-name>/SKILL.md`
|
|
52
|
-
- global: `~/.agents/skills/<skill-name>/SKILL.md` and `~/.claude/skills/<skill-name>/SKILL.md`
|
|
53
|
-
|
|
54
|
-
For local skills, mini-coder searches not just the current working directory, but each ancestor directory up to the git worktree root.
|
|
55
|
-
|
|
56
|
-
Format:
|
|
57
|
-
|
|
58
|
-
```md
|
|
59
|
-
---
|
|
60
|
-
name: required-skill-name
|
|
61
|
-
description: Required help text
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
Skill instructions/content.
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
Both `name` and `description` are required. Invalid skills are skipped with a warning.
|
|
68
|
-
|
|
69
|
-
## Agents
|
|
70
|
-
|
|
71
|
-
Supported locations:
|
|
72
|
-
|
|
73
|
-
- `./.agents/agents/*.md`
|
|
74
|
-
- `~/.agents/agents/*.md`
|
|
75
|
-
- `./.claude/agents/*.md`
|
|
76
|
-
- `~/.claude/agents/*.md`
|
|
77
|
-
|
|
78
|
-
Format:
|
|
79
|
-
|
|
80
|
-
```md
|
|
81
|
-
---
|
|
82
|
-
description: Optional help text
|
|
83
|
-
model: optional/model-override
|
|
84
|
-
mode: optional agent mode
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
Agent system prompt.
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Context files
|
|
91
|
-
|
|
92
|
-
mini-coder loads at most one global context file and at most one local context file, then includes both when present.
|
|
93
|
-
|
|
94
|
-
Global lookup order:
|
|
95
|
-
|
|
96
|
-
1. `~/.agents/AGENTS.md`
|
|
97
|
-
2. `~/.agents/CLAUDE.md`
|
|
98
|
-
|
|
99
|
-
Local lookup order:
|
|
100
|
-
|
|
101
|
-
1. `./.agents/AGENTS.md`
|
|
102
|
-
2. `./CLAUDE.md`
|
|
103
|
-
3. `./AGENTS.md`
|
|
104
|
-
|
|
105
|
-
Injection order:
|
|
106
|
-
|
|
107
|
-
1. Global context (if found)
|
|
108
|
-
2. Local context (if found)
|
|
109
|
-
|
|
110
|
-
## Precedence and conflicts
|
|
111
|
-
|
|
112
|
-
Precedence rules for commands, skills, and agents:
|
|
113
|
-
|
|
114
|
-
1. **Local overrides global**
|
|
115
|
-
2. At the **same scope** (both local or both global), if `.agents` and `.claude` define the same name, **`.agents` wins**
|
|
116
|
-
3. For **skills only**, when the same skill name exists in multiple local ancestor directories, the skill nearest to the current working directory wins
|
|
117
|
-
|
|
118
|
-
When same-scope `.agents` / `.claude` conflicts are detected for commands, skills, or agents, mini-coder prints a warning and uses the `.agents` version.
|
package/docs/custom-agents.md
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Custom Agents
|
|
2
|
-
|
|
3
|
-
A custom agent is a reusable system prompt with an optional model override.
|
|
4
|
-
You can activate one with `/agent <name>`, and non-`primary` agents are also exposed to the `subagent` tool.
|
|
5
|
-
|
|
6
|
-
mini-coder is shell-first, so custom agents should assume repo inspection and verification happen through shell, with targeted edits done via `mc-edit` invoked from shell.
|
|
7
|
-
|
|
8
|
-
## Where to put them
|
|
9
|
-
|
|
10
|
-
| Location | Scope |
|
|
11
|
-
|---|---|
|
|
12
|
-
| `.agents/agents/*.md` | Current repo only |
|
|
13
|
-
| `~/.agents/agents/*.md` | All projects (global) |
|
|
14
|
-
| `.claude/agents/*.md` | Current repo only (`.claude` layout) |
|
|
15
|
-
| `~/.claude/agents/*.md` | All projects (global, `.claude` layout) |
|
|
16
|
-
|
|
17
|
-
Local agents override global ones with the same name. At the same scope, `.agents` wins over `.claude`.
|
|
18
|
-
|
|
19
|
-
## Create an agent
|
|
20
|
-
|
|
21
|
-
The filename becomes the agent name.
|
|
22
|
-
|
|
23
|
-
`~/.agents/agents/reviewer.md`:
|
|
24
|
-
|
|
25
|
-
```md
|
|
26
|
-
---
|
|
27
|
-
description: Strict code reviewer focused on bugs and structure
|
|
28
|
-
model: zen/claude-sonnet-4-6
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
You are a senior engineer doing a code review. Be direct and specific.
|
|
32
|
-
Cite file and line number for every finding. Flag bugs first, then
|
|
33
|
-
structure issues, then style — only if they violate project conventions.
|
|
34
|
-
No flattery. End with a one-line verdict.
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Then in the REPL:
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
/agent reviewer
|
|
41
|
-
review the auth module for race conditions
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Frontmatter fields
|
|
45
|
-
|
|
46
|
-
| Field | Required | Description |
|
|
47
|
-
|---|---|---|
|
|
48
|
-
| `description` | No | Shown in `/help`. Defaults to filename. |
|
|
49
|
-
| `model` | No | Override the active model for this agent. |
|
|
50
|
-
| `mode` | No | Controls whether the agent is exposed through the `subagent` tool. `primary` excludes it from that tool and is intended for `/agent`. `subagent`, `all`, and an omitted value all keep it available to the `subagent` tool. Any loaded agent can currently still be selected with `/agent <name>`. |
|
|
51
|
-
|
|
52
|
-
The markdown body (after frontmatter) is the agent's system prompt.
|
|
53
|
-
|
|
54
|
-
## Combining with files
|
|
55
|
-
|
|
56
|
-
File references are resolved before the prompt is sent:
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
/agent reviewer
|
|
60
|
-
@src/auth/session.ts check this file for issues
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Listing agents
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
/help
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Agents are listed in magenta, tagged `(local)` or `(global)`.
|
package/docs/custom-commands.md
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# Custom Commands
|
|
2
|
-
|
|
3
|
-
Custom commands let you define reusable prompts that run as `/command` in the mini-coder REPL.
|
|
4
|
-
|
|
5
|
-
mini-coder is shell-first: when a command needs repo inspection or verification, tell it to use shell. When it needs a targeted file edit, tell it to invoke `mc-edit` from shell rather than relying on old local file-edit tools.
|
|
6
|
-
|
|
7
|
-
## Where to put them
|
|
8
|
-
|
|
9
|
-
| Location | Scope |
|
|
10
|
-
|---|---|
|
|
11
|
-
| `.agents/commands/*.md` | Current repo only |
|
|
12
|
-
| `~/.agents/commands/*.md` | All projects (global) |
|
|
13
|
-
| `.claude/commands/*.md` | Current repo only (Claude-compatible) |
|
|
14
|
-
| `~/.claude/commands/*.md` | All projects (global, Claude-compatible) |
|
|
15
|
-
|
|
16
|
-
Local commands override global ones with the same name. At the same scope, `.agents` wins over `.claude`.
|
|
17
|
-
|
|
18
|
-
## Create a command
|
|
19
|
-
|
|
20
|
-
Create a markdown file. The filename becomes the command name.
|
|
21
|
-
|
|
22
|
-
`.agents/commands/standup.md`:
|
|
23
|
-
|
|
24
|
-
```md
|
|
25
|
-
---
|
|
26
|
-
description: Summarise what changed since yesterday
|
|
27
|
-
model: zen/claude-haiku-4-5
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
Run `!`git log --oneline --since=yesterday`` and summarise the changes
|
|
31
|
-
as a short standup update. Group by theme, skip merge commits.
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Then in the REPL:
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
/standup
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Frontmatter fields
|
|
41
|
-
|
|
42
|
-
| Field | Required | Description |
|
|
43
|
-
|---|---|---|
|
|
44
|
-
| `description` | No | Shown in `/help`. Defaults to the command name. |
|
|
45
|
-
| `model` | No | Override the active model for this command (only applies when `context: fork`). |
|
|
46
|
-
| `context` | No | Set to `fork` to run the command as an isolated subagent; default runs inline. |
|
|
47
|
-
| `subtask` | No | Set to `true` to force subagent execution (OpenCode-compatible alias for `context: fork`). |
|
|
48
|
-
| `agent` | No | Run the command under a named agent's system prompt (only applies when `context: fork`). |
|
|
49
|
-
|
|
50
|
-
## Arguments
|
|
51
|
-
|
|
52
|
-
Use `$ARGUMENTS` for the full argument string, or `$1`, `$2`, … `$9` for individual tokens.
|
|
53
|
-
|
|
54
|
-
`.agents/commands/search.md`:
|
|
55
|
-
|
|
56
|
-
```md
|
|
57
|
-
---
|
|
58
|
-
description: Search the codebase for a topic
|
|
59
|
-
model: zen/claude-haiku-4-5
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
Search the codebase for: $ARGUMENTS
|
|
63
|
-
|
|
64
|
-
Use shell and skill-loading tools as needed to explore thoroughly. Report all
|
|
65
|
-
relevant files, key code snippets with line numbers, and a short summary.
|
|
66
|
-
Be exhaustive but concise. No edits.
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
/search session management
|
|
71
|
-
/search error handling in providers
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Positional tokens:
|
|
75
|
-
|
|
76
|
-
```md
|
|
77
|
-
---
|
|
78
|
-
description: Create a new component
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
Create a React component named $1 in the $2 directory.
|
|
82
|
-
Use TypeScript, include prop types and a default export.
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
/component Button src/ui
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Shell interpolation
|
|
90
|
-
|
|
91
|
-
Use `` !`cmd` `` to inject shell output into the prompt at expansion time.
|
|
92
|
-
Commands time out after 10 seconds.
|
|
93
|
-
|
|
94
|
-
```md
|
|
95
|
-
---
|
|
96
|
-
description: Review failing tests
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
The following tests are currently failing:
|
|
100
|
-
|
|
101
|
-
!`bun test 2>&1 | grep "fail\|✗" | head -20`
|
|
102
|
-
|
|
103
|
-
Investigate the failures and suggest fixes. Read the relevant source
|
|
104
|
-
files before drawing conclusions.
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
/fix-tests
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Model override
|
|
112
|
-
|
|
113
|
-
Specify a model in frontmatter to use a faster or cheaper model for
|
|
114
|
-
lightweight tasks regardless of what the session is currently set to.
|
|
115
|
-
|
|
116
|
-
```md
|
|
117
|
-
---
|
|
118
|
-
description: Quick symbol search
|
|
119
|
-
model: zen/claude-haiku-4-5
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
Find all usages of $ARGUMENTS across the codebase using shell.
|
|
123
|
-
List each occurrence with file path and line number. No explanations needed.
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Large models for deep analysis, small models for search and lookup.
|
|
127
|
-
|
|
128
|
-
## Precedence
|
|
129
|
-
|
|
130
|
-
Custom commands shadow built-ins. The global `/review`
|
|
131
|
-
command (auto-created at `~/.agents/commands/review.md` on first run) works
|
|
132
|
-
the same way — a local `.agents/commands/review.md` will override it.
|
|
133
|
-
|
|
134
|
-
## Listing commands
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
/help
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
Custom commands are listed at the bottom under **custom commands**, tagged
|
|
141
|
-
with `(local)` or `(global)`.
|
package/docs/skills.md
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Skills
|
|
2
|
-
|
|
3
|
-
Skills are reusable instruction files discovered automatically from local and global directories.
|
|
4
|
-
|
|
5
|
-
When a skill tells mini-coder how to work with files, prefer shell for inspection/search/verification and `mc-edit` from shell for targeted edits.
|
|
6
|
-
|
|
7
|
-
- The model sees **skill metadata only** by default (name, description, source).
|
|
8
|
-
- Full `SKILL.md` content is loaded **on demand**:
|
|
9
|
-
- when explicitly requested with the runtime skill tools (`listSkills` / `readSkill`), or
|
|
10
|
-
- when you reference `@skill-name` in your prompt.
|
|
11
|
-
|
|
12
|
-
## Discovery locations
|
|
13
|
-
|
|
14
|
-
Skills live in folders containing `SKILL.md`:
|
|
15
|
-
|
|
16
|
-
| Location | Scope |
|
|
17
|
-
|---|---|
|
|
18
|
-
| `.agents/skills/<name>/SKILL.md` | Local |
|
|
19
|
-
| `.claude/skills/<name>/SKILL.md` | Local (Claude-compatible) |
|
|
20
|
-
| `~/.agents/skills/<name>/SKILL.md` | Global |
|
|
21
|
-
| `~/.claude/skills/<name>/SKILL.md` | Global (Claude-compatible) |
|
|
22
|
-
|
|
23
|
-
Local discovery walks up from the current working directory to the git worktree root.
|
|
24
|
-
|
|
25
|
-
## Precedence rules
|
|
26
|
-
|
|
27
|
-
If multiple skills share the same `name`, precedence is deterministic:
|
|
28
|
-
|
|
29
|
-
1. Nearest local directory wins over farther ancestor directories.
|
|
30
|
-
2. Any local skill wins over global.
|
|
31
|
-
3. At the same scope/path level, `.agents` wins over `.claude`.
|
|
32
|
-
|
|
33
|
-
## Frontmatter
|
|
34
|
-
|
|
35
|
-
`SKILL.md` frontmatter supports:
|
|
36
|
-
|
|
37
|
-
- `name` (**required**)
|
|
38
|
-
- `description` (**required**)
|
|
39
|
-
|
|
40
|
-
`name` constraints:
|
|
41
|
-
|
|
42
|
-
- lowercase alphanumeric and hyphen format (`^[a-z0-9]+(?:-[a-z0-9]+)*$`)
|
|
43
|
-
- 1–64 characters
|
|
44
|
-
|
|
45
|
-
Unknown frontmatter fields are allowed.
|
|
46
|
-
|
|
47
|
-
If either `name` or `description` is missing, mini-coder skips the skill and prints a warning.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
## Create a skill
|
|
51
|
-
|
|
52
|
-
`.agents/skills/conventional-commits/SKILL.md`:
|
|
53
|
-
|
|
54
|
-
```md
|
|
55
|
-
---
|
|
56
|
-
name: conventional-commits
|
|
57
|
-
description: Conventional commit message format rules
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
# Conventional Commits
|
|
61
|
-
|
|
62
|
-
Use:
|
|
63
|
-
<type>(<scope>): <short summary>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Use a skill explicitly
|
|
67
|
-
|
|
68
|
-
```text
|
|
69
|
-
@conventional-commits write a commit message for my staged changes
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
`@skill-name` injects the raw skill body wrapped as:
|
|
73
|
-
|
|
74
|
-
```xml
|
|
75
|
-
<skill name="conventional-commits">
|
|
76
|
-
...
|
|
77
|
-
</skill>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## Tab completion and help
|
|
81
|
-
|
|
82
|
-
- Type `@` then `Tab` to complete skill names.
|
|
83
|
-
- Run `/help` to list discovered skills with `(local)` / `(global)` tags.
|