mini-coder 0.7.3 → 0.8.0
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/AGENTS.md +114 -0
- package/README.md +53 -66
- package/bin/mini-coder.ts +2 -0
- package/demo.gif +0 -0
- package/package.json +17 -20
- package/src/agent.ts +177 -255
- package/src/cli.ts +101 -0
- package/src/config.ts +150 -0
- package/src/prompt.ts +54 -207
- package/src/session.ts +124 -69
- package/src/tools/bash.ts +89 -0
- package/src/tools/common.ts +32 -0
- package/src/tools/edit.ts +41 -0
- package/src/tools/index.ts +47 -0
- package/src/tools/read.ts +64 -0
- package/src/tui/commands.ts +63 -0
- package/src/tui/editor.ts +291 -0
- package/src/tui/highlight.ts +189 -0
- package/src/tui/stream.ts +142 -0
- package/src/tui/styles.ts +42 -0
- package/src/tui/term.ts +436 -0
- package/src/tui/theme.ts +121 -0
- package/src/tui/tui.ts +595 -0
- package/src/tui/usage.ts +67 -0
- package/tsconfig.json +8 -8
- package/bin/mc.ts +0 -11
- package/bun.lock +0 -346
- package/nono-mini-coder.json +0 -42
- package/src/args.ts +0 -300
- package/src/error-handling.test.ts +0 -163
- package/src/git.ts +0 -23
- package/src/headless.ts +0 -66
- package/src/index.ts +0 -43
- package/src/oauth.ts +0 -157
- package/src/shared.ts +0 -119
- package/src/themes.ts +0 -234
- package/src/tool-bash.ts +0 -77
- package/src/tool-edit.ts +0 -121
- package/src/tool-read.ts +0 -100
- package/src/tui-components.ts +0 -127
- package/src/tui-conversation.ts +0 -218
- package/src/tui-editor.ts +0 -29
- package/src/tui-overlay.ts +0 -618
- package/src/tui.ts +0 -314
- package/src/types.ts +0 -194
- package/src/update.ts +0 -171
package/AGENTS.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# mini-coder
|
|
2
|
+
|
|
3
|
+
A fast, transparent, config-first terminal coding agent for one user at a time.
|
|
4
|
+
|
|
5
|
+
This file holds intent, direction, and guardrails — not a description of the
|
|
6
|
+
code. The source is the source of truth for behavior. If a fact can be learned
|
|
7
|
+
by reading the code, it does not belong here; keep this file short.
|
|
8
|
+
|
|
9
|
+
## Intent
|
|
10
|
+
|
|
11
|
+
- A small, auditable core with no hidden machinery.
|
|
12
|
+
- A minimal system prompt with no injected meta-guidance.
|
|
13
|
+
- Provider work delegated entirely to `pi-ai`.
|
|
14
|
+
- Durable, user-owned, readable session logs.
|
|
15
|
+
- An append-only TUI with a bounded live region and no full-screen buffer.
|
|
16
|
+
- Local models (Ollama / llama.cpp / vLLM) and hosted models treated as equals.
|
|
17
|
+
|
|
18
|
+
Prior art is reference, not template: `x.x.x-archive` (previous implementation),
|
|
19
|
+
`../awl/` (append-only live-region TUI), `../bough/` (layer boundaries), and
|
|
20
|
+
`../agent-ide/` (session durability, streaming). Extract ideas, do not port code.
|
|
21
|
+
|
|
22
|
+
## Direction
|
|
23
|
+
|
|
24
|
+
Deferred, not rejected. Do not build unless explicitly promoted:
|
|
25
|
+
|
|
26
|
+
- context compaction / summarization / masking;
|
|
27
|
+
- reading or resuming sessions (the JSONL log is write-only today);
|
|
28
|
+
- prompt templates; custom agents / subagents / delegation;
|
|
29
|
+
- an extension or plugin system; a settings TUI; overlay editors;
|
|
30
|
+
- custom OAuth or auth flows (use `pi-ai`'s provider auth);
|
|
31
|
+
- MCP, image generation, multi-agent orchestration;
|
|
32
|
+
- sandboxing, approval prompts, permission policies;
|
|
33
|
+
- tests and CI (standing rule: no tests unless asked);
|
|
34
|
+
- macOS/Windows support and cross-platform abstractions. Target Linux first.
|
|
35
|
+
|
|
36
|
+
## Guardrails
|
|
37
|
+
|
|
38
|
+
Hard constraints. Do not cross these without explicit direction:
|
|
39
|
+
|
|
40
|
+
- **Node.js directly.** No Bun, no Deno, no `Bun.*`, no Bun package scripts.
|
|
41
|
+
- **No TUI library or framework.** Render with direct `process.stdout` ANSI
|
|
42
|
+
writes and plain strings.
|
|
43
|
+
- **`pi-ai` owns the provider layer.** All model requests, adapters, wire
|
|
44
|
+
formats, streaming, auth, and usage go through `@earendil-works/pi-ai`. Never
|
|
45
|
+
re-implement a provider protocol, and keep provider-specific continuation data
|
|
46
|
+
intact.
|
|
47
|
+
- **Write original code.** Other coding agents are behavioral references only.
|
|
48
|
+
- **No sandbox or permission layer.** Tools run with the user's permissions;
|
|
49
|
+
isolation is an environment concern (`nono`), not the agent's.
|
|
50
|
+
- **No loop limits.** No max turns, tool calls, token budgets, or agent-imposed
|
|
51
|
+
timeouts. The user's ability to interrupt is the limit.
|
|
52
|
+
- **Config-first.** Every user-facing behavior that can vary comes from config
|
|
53
|
+
with a sane default. Global config only — no project-local config, no
|
|
54
|
+
config-override flags — and never duplicate `pi-ai`'s catalog or env vars.
|
|
55
|
+
- **Minimal context.** The model sees the configured system prompt plus
|
|
56
|
+
explicitly opted-in resource files — never reminders, hidden blocks, or
|
|
57
|
+
harness meta-text.
|
|
58
|
+
- **Never invent a parallel model.** Consume `pi-ai`'s `Message` and stream
|
|
59
|
+
types directly.
|
|
60
|
+
- **The agent never imports the TUI.** Headless and TUI are two projections of
|
|
61
|
+
the same agent events; the TUI owns no agent or provider semantics.
|
|
62
|
+
|
|
63
|
+
## Invariants
|
|
64
|
+
|
|
65
|
+
- Sessions are append-only JSONL, one `pi-ai` message per line, fsynced on
|
|
66
|
+
write. Never rewrite or delete committed lines. A persistence failure stops
|
|
67
|
+
the turn.
|
|
68
|
+
- The loop has no compaction, no retries, and no meta-messages between steps.
|
|
69
|
+
Provider errors surface as-is, never masked or summarized.
|
|
70
|
+
- `edit`, `read`, and `bash` only. Tool arguments are untrusted and validated
|
|
71
|
+
once at the boundary. `read` returns image blocks only for models that declare
|
|
72
|
+
image input.
|
|
73
|
+
- Interruption: ESC politely pauses at the next step boundary; Ctrl+C cancels the
|
|
74
|
+
turn (abort the request, kill the tool's process group, persist the aborted
|
|
75
|
+
message); Ctrl+D exits on an empty draft. Completed side effects are never
|
|
76
|
+
undone.
|
|
77
|
+
- Diagnostics are local only. No telemetry, no hidden stalls.
|
|
78
|
+
|
|
79
|
+
## Driving the TUI with kitty
|
|
80
|
+
|
|
81
|
+
There is no `tmux` here; drive the TUI through kitty's remote control on a
|
|
82
|
+
private socket, one window per session:
|
|
83
|
+
|
|
84
|
+
kitty --detach --listen-on unix:/tmp/mc-<name>.sock \
|
|
85
|
+
-o allow_remote_control=yes -o remember_window_size=no \
|
|
86
|
+
-o initial_window_width=100c -o initial_window_height=30c \
|
|
87
|
+
--title mc-<name> env PS1='\n$ ' bash --norc --noprofile -i
|
|
88
|
+
|
|
89
|
+
Run every `kitty @ --to unix:/tmp/mc-<name>.sock` call through that socket; the
|
|
90
|
+
window id comes from `ls`, don't assume it. Run the app (`node src/cli.ts`) with
|
|
91
|
+
a scratch cwd so its tool calls write nowhere that matters.
|
|
92
|
+
|
|
93
|
+
- `send-text` types literal text and never submits — Enter is its own key,
|
|
94
|
+
`send-key enter`, and it does nothing while a turn is active.
|
|
95
|
+
- `send-key` for named keys: `enter escape ctrl+c ctrl+d shift+enter tab`.
|
|
96
|
+
- `get-text -m id:N --extent=all --ansi` returns the pane with the app's
|
|
97
|
+
truecolor SGR — assert colors from those escapes, not from pixels;
|
|
98
|
+
`--extent=screen` is the live screen alone.
|
|
99
|
+
- `screenshot -m id:N out.png` for the visual check; `identify` it and look at
|
|
100
|
+
it before trusting it.
|
|
101
|
+
|
|
102
|
+
## Working agreement
|
|
103
|
+
|
|
104
|
+
- Trace the real data flow before designing; apply guards at the narrowest
|
|
105
|
+
boundary.
|
|
106
|
+
- Keep the diff small. Do not opportunistically refactor or harden adjacent code.
|
|
107
|
+
- Prefer plain functions and objects; keep exports minimal; define helpers near
|
|
108
|
+
their use.
|
|
109
|
+
- Validate untrusted input once at the boundary with Typebox, then keep internal
|
|
110
|
+
code plain-typed.
|
|
111
|
+
- Ask before adding a dependency.
|
|
112
|
+
- Do not add tests unless explicitly asked; verify manually.
|
|
113
|
+
- Before finishing, review the diff against the direction and guardrails, remove
|
|
114
|
+
anything that added scope, and report any requirement you could not satisfy.
|
package/README.md
CHANGED
|
@@ -1,91 +1,78 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="
|
|
2
|
+
<img src="demo.gif" alt="mini-coder demo" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# mini-coder
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<a href="https://www.npmjs.com/package/mini-coder">npm</a>
|
|
11
|
-
·
|
|
12
|
-
<a href="https://sacenox.github.io/mini-coder/">docs</a>
|
|
13
|
-
·
|
|
14
|
-
<a href="spec.md">spec</a>
|
|
15
|
-
</p>
|
|
16
|
-
|
|
17
|
-
<p align="center">
|
|
18
|
-
<picture>
|
|
19
|
-
<img src="assets/preview.gif" alt="mini-coder terminal session preview" width="960" style="border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.35);" />
|
|
20
|
-
</picture>
|
|
21
|
-
</p>
|
|
22
|
-
|
|
23
|
-
mini-coder (`mc`) is a terminal coding agent, hand crafted for transparency and good engineering performance.
|
|
7
|
+
A fast, transparent, config-first terminal coding agent. One provider request at a time, no
|
|
8
|
+
hidden machinery: `edit`, `read`, and `bash`, an append-only JSONL session log, and a config
|
|
9
|
+
file that decides everything.
|
|
24
10
|
|
|
25
11
|
## Install
|
|
26
12
|
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
$ mc
|
|
13
|
+
```sh
|
|
14
|
+
npm i -g mini-coder
|
|
30
15
|
```
|
|
31
16
|
|
|
32
|
-
##
|
|
17
|
+
## Configuration
|
|
33
18
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- **Agent-first** — every decision serves the goal of reading code, making changes, and verifying them via the shell.
|
|
37
|
-
- **Performance** — startup and turn latency matter more than features.
|
|
38
|
-
- **Streaming end-to-end** — assistant text, reasoning, tool calls, and tool output show up as they happen.
|
|
39
|
-
- **Isolation friendly**— works inside [nono](https://nono.sh/). Suggested profile in `nono-mini-coder.json`
|
|
19
|
+
Global config lives at `~/.config/mini-coder/config.json` (`$XDG_CONFIG_HOME/mini-coder/config.json`
|
|
20
|
+
if set). There is no project-local config and no override flags.
|
|
40
21
|
|
|
41
|
-
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"provider": "anthropic",
|
|
25
|
+
"model": "claude-sonnet-4-5"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
42
28
|
|
|
43
|
-
|
|
29
|
+
Only `provider` and `model` are required. Defaults for the rest:
|
|
44
30
|
|
|
45
|
-
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"sessionsDir": "./sessions",
|
|
34
|
+
"systemPrompt": "",
|
|
35
|
+
"discoverAgentFiles": true,
|
|
36
|
+
"skillsDirs": [],
|
|
37
|
+
"tools": ["edit", "read", "bash"],
|
|
38
|
+
"thinkingEffort": "medium",
|
|
39
|
+
"customProviders": []
|
|
40
|
+
}
|
|
41
|
+
```
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
- `provider` / `model` — any model from the `pi-ai` catalog. Invalid pairs fail with a
|
|
44
|
+
list of available models for that provider.
|
|
45
|
+
- `sessionsDir` — where append-only session JSONL files are written. (no relative paths for now, absolute paths only).
|
|
46
|
+
- `systemPrompt` — the base of the system prompt. Skills and agent files, if
|
|
47
|
+
enabled, are appended after it.
|
|
48
|
+
- `discoverAgentFiles` — when true, appends `AGENTS.md` / `CLAUDE.md` found in `~/.agents`
|
|
49
|
+
and the working directory to the system prompt.
|
|
50
|
+
- `skillsDirs` — directories of skills to advertise (`<dir>/<skill>/SKILL.md` with
|
|
51
|
+
`name:` and `description:` frontmatter). Paths, not contents, go to the model.
|
|
52
|
+
- `tools` — which of `edit`, `read`, `bash` the agent gets. Tool arguments are untrusted
|
|
53
|
+
and validated at this boundary regardless.
|
|
54
|
+
- `thinkingEffort` — `minimal`, `low`, `medium`, `high`, `xhigh`, or `max` for models
|
|
55
|
+
that support reasoning.
|
|
56
|
+
|
|
57
|
+
### Local and custom models
|
|
58
|
+
|
|
59
|
+
Hosted and local models are equals. Add unlisted or self-hosted models through
|
|
60
|
+
`customProviders` — the four wire APIs come from `pi-ai`, and auth resolves from your
|
|
61
|
+
environment via `envKeys` (no local model needs it):
|
|
48
62
|
|
|
49
63
|
```json
|
|
50
64
|
{
|
|
51
|
-
"provider": "ollama",
|
|
52
|
-
"model": "llama3.1:8b",
|
|
53
|
-
"effort": "medium",
|
|
54
65
|
"customProviders": [
|
|
55
66
|
{
|
|
56
|
-
"id": "
|
|
57
|
-
"name": "
|
|
58
|
-
"api": "openai-completions",
|
|
59
|
-
"provider": "ollama",
|
|
67
|
+
"id": "ollama",
|
|
68
|
+
"name": "Ollama",
|
|
60
69
|
"baseUrl": "http://localhost:11434/v1",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"cost": {
|
|
64
|
-
"input": 0,
|
|
65
|
-
"output": 0,
|
|
66
|
-
"cacheRead": 0,
|
|
67
|
-
"cacheWrite": 0
|
|
68
|
-
},
|
|
69
|
-
"contextWindow": 128000,
|
|
70
|
-
"maxTokens": 32000
|
|
70
|
+
"api": "openai-completions",
|
|
71
|
+
"models": ["qwen3-coder:30b", "gpt-oss:20b"]
|
|
71
72
|
}
|
|
72
73
|
]
|
|
73
74
|
}
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
## Also makes LLMs smarter
|
|
79
|
-
|
|
80
|
-
LLMs famously tell you to walk 50 meters to the car wash — forgetting the car needs to be there too. Not on our watch.
|
|
81
|
-
|
|
82
|
-
<table align="center">
|
|
83
|
-
<tr>
|
|
84
|
-
<td><img src="assets/mc-claude-smart.png" alt="Claude correctly answering the car wash question" width="400" /></td>
|
|
85
|
-
<td><img src="assets/mc-gpt-smart.png" alt="GPT correctly answering the car wash question" width="400" /></td>
|
|
86
|
-
</tr>
|
|
87
|
-
</table>
|
|
88
|
-
|
|
89
|
-
## License
|
|
90
|
-
|
|
91
|
-
MIT
|
|
77
|
+
`api` is `openai-completions`, `openai-responses`, `anthropic-messages`, or
|
|
78
|
+
`google-generative-ai`. Then point `provider` and `model` at it.
|
package/demo.gif
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-coder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "A fast, transparent, config-first terminal coding agent",
|
|
4
5
|
"type": "module",
|
|
5
|
-
"
|
|
6
|
+
"license": "MIT",
|
|
6
7
|
"bin": {
|
|
7
|
-
"
|
|
8
|
+
"mini-coder": "bin/mini-coder.ts"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"lint": "bun run biome check .",
|
|
13
|
-
"typecheck": "bun run tsc -p tsconfig.json --noEmit",
|
|
14
|
-
"format": "bun run prettier --write *.md && bun run biome format --write . && bun run biome check --write ."
|
|
15
|
-
},
|
|
16
|
-
"devDependencies": {
|
|
17
|
-
"@biomejs/biome": "^2.5.0",
|
|
18
|
-
"@types/bun": "^1.3.14",
|
|
19
|
-
"prettier": "^3.8.4",
|
|
20
|
-
"typescript": "^6.0.3"
|
|
11
|
+
"start": "node src/cli.ts",
|
|
12
|
+
"typecheck": "tsc --noEmit"
|
|
21
13
|
},
|
|
22
14
|
"dependencies": {
|
|
23
|
-
"@
|
|
24
|
-
"@
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
15
|
+
"@earendil-works/pi-ai": "0.87.0",
|
|
16
|
+
"@tree-sitter-grammars/tree-sitter-markdown": "0.3.2",
|
|
17
|
+
"diff": "^8.0.2",
|
|
18
|
+
"tree-sitter": "0.25.1",
|
|
19
|
+
"tree-sitter-javascript": "0.25.0",
|
|
20
|
+
"tree-sitter-typescript": "0.23.2",
|
|
21
|
+
"typebox": "1.3.27"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^22.19.19",
|
|
25
|
+
"typescript": "^5.9.3"
|
|
29
26
|
}
|
|
30
27
|
}
|