mini-code-cli 0.1.1.2__tar.gz → 0.1.1.4__tar.gz
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.
- mini_code_cli-0.1.1.4/PKG-INFO +440 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/README.md +86 -13
- mini_code_cli-0.1.1.4/mini_code_cli/__init__.py +59 -0
- mini_code_cli-0.1.1.4/mini_code_cli/__main__.py +12 -0
- mini_code_cli-0.1.1.4/mini_code_cli/agent_files.py +90 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/agent_loop.py +546 -76
- mini_code_cli-0.1.1.4/mini_code_cli/compaction.py +245 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/config.py +35 -19
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/permissions.py +15 -9
- mini_code_cli-0.1.1.4/mini_code_cli/planning.py +29 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/prompts.py +144 -6
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/runner.py +21 -7
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/skills.py +4 -1
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/subagents/base.py +64 -8
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/subagents/builtin.py +10 -9
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/tokens.py +66 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/tools.py +92 -30
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/ui.py +156 -16
- mini_code_cli-0.1.1.4/mini_code_cli/utils.py +292 -0
- mini_code_cli-0.1.1.4/mini_code_cli.egg-info/PKG-INFO +440 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli.egg-info/SOURCES.txt +13 -1
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/pyproject.toml +7 -3
- mini_code_cli-0.1.1.4/tests/test_advanced_features.py +459 -0
- mini_code_cli-0.1.1.4/tests/test_cli_features.py +177 -0
- mini_code_cli-0.1.1.4/tests/test_config.py +82 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/tests/test_e2e_agent_loop.py +53 -1
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/tests/test_interactive.py +216 -0
- mini_code_cli-0.1.1.4/tests/test_permissions.py +93 -0
- mini_code_cli-0.1.1.4/tests/test_release_script.py +240 -0
- mini_code_cli-0.1.1.4/tests/test_runner.py +84 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/tests/test_subagents.py +88 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/tests/test_tokens.py +29 -2
- mini_code_cli-0.1.1.4/tests/test_tools.py +151 -0
- mini_code_cli-0.1.1.4/tests/test_utils.py +93 -0
- mini_code_cli-0.1.1.2/PKG-INFO +0 -1028
- mini_code_cli-0.1.1.2/mini_code_cli/__init__.py +0 -40
- mini_code_cli-0.1.1.2/mini_code_cli/utils.py +0 -214
- mini_code_cli-0.1.1.2/mini_code_cli.egg-info/PKG-INFO +0 -1028
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/LICENSE +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/persistence.py +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/plan.py +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/sandbox.py +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/shell_safety_utils.py +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli/subagents/__init__.py +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli.egg-info/dependency_links.txt +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli.egg-info/entry_points.txt +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli.egg-info/requires.txt +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/mini_code_cli.egg-info/top_level.txt +0 -0
- {mini_code_cli-0.1.1.2 → mini_code_cli-0.1.1.4}/setup.cfg +0 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mini-code-cli
|
|
3
|
+
Version: 0.1.1.4
|
|
4
|
+
Summary: Mini Coding Agent. Allows you to easily experiment with a small coding agent.
|
|
5
|
+
Author-email: Nikolai Rozanov <nikolai.rozanov@gmail.com>
|
|
6
|
+
License-Expression: AGPL-3.0-only
|
|
7
|
+
Project-URL: Homepage, https://github.com/ai-nikolai/mini-code-cli
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: requests<3,>=2.31
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# mini-code-cli
|
|
21
|
+
|
|
22
|
+
### A minimal coding agent CLI
|
|
23
|
+
|
|
24
|
+
> No bloat, no dependencies, no tracking, no telemetry...
|
|
25
|
+
|
|
26
|
+
[](https://github.com/ai-nikolai/mini-code-cli/actions/workflows/ci.yml)
|
|
27
|
+
[](https://pypi.org/project/mini-code-cli/)
|
|
28
|
+
[](https://pypi.org/project/mini-code-cli/)
|
|
29
|
+
[](https://github.com/ai-nikolai/mini-code-cli/stargazers)
|
|
30
|
+
[](LICENSE)
|
|
31
|
+
[](#citation)
|
|
32
|
+
|
|
33
|
+
**Purpose:** a no-bloat, minimal coding CLI to enjoy experimenting and researching!
|
|
34
|
+
|
|
35
|
+
**Install** · [Quick start](#quick-start) · [Modes & safety](#modes--safety) · [Options](#command-line-options) · [Tools](#available-tools) · [Sub-agents](#sub-agents) · [In-session commands](#in-session-commands) · [Development](#development) · [Docs](#documentation) · [Citation](#citation)
|
|
36
|
+
|
|
37
|
+
> [!TIP]
|
|
38
|
+
> **New here?** `pip install mini-code-cli`, point it at a model (a local server on
|
|
39
|
+
> `localhost:30000`, or `MINI_CODE_API_KEY` + `--url`), and run `mini-code`. Everything else
|
|
40
|
+
> is optional.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip3 install mini-code-cli
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- **PyPI:** <https://pypi.org/project/mini-code-cli/>
|
|
49
|
+
- **Python:** `>= 3.10` · **runtime dependency:** `requests` only
|
|
50
|
+
- **From source / contributing:** see [docs/README_DEV.md](docs/README_DEV.md)
|
|
51
|
+
|
|
52
|
+
## Quick start
|
|
53
|
+
|
|
54
|
+
**1 — Local model** (e.g. vLLM or SGLang on port 30000; see [serving a model locally](#serving-a-model-locally)):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
mini-code # talks to http://0.0.0.0:30000/v1
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**2 — Hosted / custom API:**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
export MINI_CODE_API_KEY="sk-YOUR_API_KEY"
|
|
64
|
+
mini-code --url "https://api.deepseek.com" --model "deepseek-v4-flash"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**3 — The shortcuts** (plan mode, sub-agents, shell, auto-mode, no permission prompts):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
mini-code --all # = --plan --enable-subagents --enable-shell --skills --auto-mode --sudo
|
|
71
|
+
mini-code --all-last # ...and continue your last session
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**4 — A first prompt:**
|
|
75
|
+
|
|
76
|
+
```txt
|
|
77
|
+
Write an agent.md file for me that helps an LLM write efficient triton kernels,
|
|
78
|
+
given a reference implementation.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> [!NOTE]
|
|
82
|
+
> **Every flag** is listed once, in [Command-line options](#command-line-options) — or run
|
|
83
|
+
> `mini-code --help`. Modes and their caveats are described in [Modes & safety](#modes--safety).
|
|
84
|
+
|
|
85
|
+
## Command-line options
|
|
86
|
+
|
|
87
|
+
| Option | Default | What it does |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| `--url URL` | `http://0.0.0.0:30000` | API host |
|
|
90
|
+
| `--model MODEL` | — | model name |
|
|
91
|
+
| `--api-key KEY` | `$MINI_CODE_API_KEY` | API key for authentication |
|
|
92
|
+
| `--max-tokens N` | — | reply budget; also the output headroom used when deriving the compaction limit |
|
|
93
|
+
| `--temperature T` | `1.0` | sampling temperature |
|
|
94
|
+
| `--system-prompt TEXT` | built-in | replace the system prompt (an `--agent-md` file is appended *after* it) |
|
|
95
|
+
| `--prompt TEXT` | — | initial user prompt |
|
|
96
|
+
| `-a`, `--auto-mode` | off | keep querying the model and running tools until no tool calls remain |
|
|
97
|
+
| `--agent-md FILE` | — | append an `agent.md` file after the system prompt (e.g. `./skill.md`) |
|
|
98
|
+
| `--ask-permission` | off | ask before **every** tool call, including an ALLOW-tier shell command (`--sudo` disables all prompts) |
|
|
99
|
+
| `--sudo` | off | **dangerous:** never ask. DENY-tier commands are still refused |
|
|
100
|
+
| `--allowed-dir DIR` | `./` | sandbox for **file** tools (does not restrict the shell) |
|
|
101
|
+
| `-s`, `--enable-shell` | off | allow shell execution (classifier always applies) |
|
|
102
|
+
| `-g`, `--enable-subagents` | off | expose sub-agents as tools |
|
|
103
|
+
| `--skills` | off | enable the `.mini` skills directory (`skill.md`s, `SKILLS.md`, runnable scripts). **`run_skill` executes those Python scripts — arbitrary code execution, even without `--enable-shell`**; only enable it for a directory you trust |
|
|
104
|
+
| `-p`, `--plan` | off | plan mode (`CURRENT_GOAL.md` / `CURRENT_PLAN.md`, printed plan, `/plan`, `/skip-plan`) |
|
|
105
|
+
| `--plan-strategy NAME` | `plan-verify-step` | `plan-verify-step`, `plan-verify` or `open-plan` (implies `--plan`) |
|
|
106
|
+
| `--scratchpad` | off | give the agent a free-form `.mini/SCRATCHPAD.md` (plus further scratch files) for thoughts, plans and learnings |
|
|
107
|
+
| `--compaction-strategy NAME` | `summarise` | `summarise`, `predict-files` or `predict-messages` |
|
|
108
|
+
| `--llm-timeout S` | `500` | HTTP timeout for LLM requests |
|
|
109
|
+
| `--tool-timeout S` | `120` | timeout for a single tool call |
|
|
110
|
+
| `--max-context-tokens N` | derived | input-token budget before the history is compacted |
|
|
111
|
+
| `--cache-dir DIR` | `~/.cache/mini/sessions/` | where session histories are stored |
|
|
112
|
+
| `--restore-session PATH` | — | continue a specific previous session |
|
|
113
|
+
| `-l`, `--load-last-session` | off | continue the session recorded in the `.mini` pointer |
|
|
114
|
+
| `--all` | off | `--plan --enable-subagents --enable-shell --skills --auto-mode --sudo` |
|
|
115
|
+
| `--all-last` | off | `--all` + `--load-last-session` |
|
|
116
|
+
| `--verbose` | off | print full detail (default: user/assistant turns, token usage, tool calls only) |
|
|
117
|
+
| `-h`, `--help` | — | show the built-in help |
|
|
118
|
+
|
|
119
|
+
## Available tools
|
|
120
|
+
|
|
121
|
+
The agent can call a small set of tools, all defined in `mini_code_cli/tools.py`. Every
|
|
122
|
+
parameter a model does not need is defaulted, so omitting it keeps the previous behaviour.
|
|
123
|
+
|
|
124
|
+
| Tool | What it does |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| `read_file` | read a file; `offset` (1-based line) and `limit` page through large files |
|
|
127
|
+
| `write_file` | write/overwrite; `append` adds to the end, `create_dirs` creates parents |
|
|
128
|
+
| `edit` | replace an **exact** string (`old_string` → `new_string`); refuses a missing or ambiguous match unless `replace_all` |
|
|
129
|
+
| `grep` | regex search a file or directory; `recursive`, `include`, `ignore_case`, `line_numbers`, `max_results` (noise dirs skipped) |
|
|
130
|
+
| `glob` | list files matching a glob (one per line, `**` supported), optionally against a `root` |
|
|
131
|
+
| `web_search` | best-effort lookup: related queries + a short Wikipedia extract. Never raises |
|
|
132
|
+
| `read_website` | fetch raw text/HTML of a URL (bounded by `--tool-timeout`), `max_chars` caps size |
|
|
133
|
+
| `run_shell_command` | run a shell command (needs `--enable-shell`); `cwd`, `timeout`, and stdout/stderr/exit code are all reported |
|
|
134
|
+
|
|
135
|
+
## Sub-agents
|
|
136
|
+
|
|
137
|
+
`--enable-subagents` lets the main agent **delegate a focused task** to a sub-agent, exposed to
|
|
138
|
+
the model as an extra tool. A sub-agent is a self-contained, narrowed agent: it runs unattended
|
|
139
|
+
in auto-mode, in its own isolated session folder, and hands back a short text result (plus an
|
|
140
|
+
optional `report.md`). It reuses all the existing machinery — tools, the shell-safety
|
|
141
|
+
classifier, the `--allowed-dir` sandbox, compaction and `--plan` — and cannot spawn further
|
|
142
|
+
sub-agents.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
mini-code --enable-subagents # the available sub-agents then show up in /help
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
| Sub-agent | What it is for |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `research` | read-only web research: searches, reads a few sources, returns a sourced summary. Can only use `web_search` / `read_website` — never the filesystem or shell. Optional `sources` hint (e.g. `"wikipedia.org only"`) |
|
|
151
|
+
| `planner` | drafts or refines a step-by-step plan for a goal; always runs in plan mode |
|
|
152
|
+
| `software_engineer` | writes, edits, refactors, fixes and tests code; can run shell commands (tests, builds) to verify |
|
|
153
|
+
| `generic` | general-purpose helper for anything that fits no narrower agent |
|
|
154
|
+
|
|
155
|
+
> [!NOTE]
|
|
156
|
+
> A sub-agent's `tools`, `enable_shell` and `max_steps` are always **intersected with the
|
|
157
|
+
> parent's** permissions, so it can never do anything the main agent could not. The `tools`
|
|
158
|
+
> allowlist is enforced on the nested session itself (both the schemas offered to the model and
|
|
159
|
+
> the dispatch table), not merely described in its prompt. Sub-agents compose with `--plan`:
|
|
160
|
+
> each keeps its own `CURRENT_PLAN.md` / `CURRENT_GOAL.md`.
|
|
161
|
+
|
|
162
|
+
<details>
|
|
163
|
+
<summary><b>Adding your own sub-agent</b></summary>
|
|
164
|
+
|
|
165
|
+
A sub-agent is just a small class — subclass `SubAgent` and register it:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
# my_subagents.py
|
|
169
|
+
from mini_code_cli.subagents import SubAgent, register
|
|
170
|
+
|
|
171
|
+
class SummarizeSubAgent(SubAgent):
|
|
172
|
+
name = "summarize"
|
|
173
|
+
description = "Summarize a piece of text the main agent provides."
|
|
174
|
+
tools = ["read_file", "write_file"] # restrict the nested agent's tools
|
|
175
|
+
enable_shell = False
|
|
176
|
+
max_steps = 5
|
|
177
|
+
|
|
178
|
+
register(SummarizeSubAgent())
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Make sure the module is imported (e.g. `import my_subagents`) and it is discovered and exposed
|
|
182
|
+
to the model automatically when `--enable-subagents` is set. See
|
|
183
|
+
`mini_code_cli/subagents/builtin.py` for every knob and
|
|
184
|
+
[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) (sections 2–3) for the design.
|
|
185
|
+
|
|
186
|
+
</details>
|
|
187
|
+
|
|
188
|
+
## In-session commands
|
|
189
|
+
|
|
190
|
+
| Command | What it does |
|
|
191
|
+
| --- | --- |
|
|
192
|
+
| `/history` | list the conversation (turn number, what happened, where) |
|
|
193
|
+
| `/history <n>` | show the full messages recorded for turn `n` |
|
|
194
|
+
| `/history last` | ...for the most recent turn |
|
|
195
|
+
| `/reset [<n>]` | rewind to the end of turn `n` (`last` works too); drops everything after it |
|
|
196
|
+
| `/clear` | clear the screen (keeps the conversation history) |
|
|
197
|
+
| `/plan` | show the current goal + plan (plan mode only) |
|
|
198
|
+
| `/context` | show how the context window is used: tokens and percentages by category (system prompt, user/assistant messages, tool calls/outputs, reasoning, overhead) |
|
|
199
|
+
| `/skip-plan <prompt>` | send `<prompt>` once without generating or reviewing a plan |
|
|
200
|
+
| `/help` | show this help |
|
|
201
|
+
| `/quit`, `/exit` | save the session and exit |
|
|
202
|
+
|
|
203
|
+
**Multi-line input:** press `Shift+Enter` (or `Ctrl-J`) to insert a newline; plain
|
|
204
|
+
`Enter` sends the turn. This works in the session prompt and the startup tip
|
|
205
|
+
reminds you. Terminals that report `Shift+Enter` as a CSI-u/modifyOtherKeys
|
|
206
|
+
sequence are recognised; elsewhere `Ctrl-J` inserts the newline.
|
|
207
|
+
|
|
208
|
+
> [!NOTE]
|
|
209
|
+
> `/history` and `/reset` are driven by `summary_history.json`, a flat recorder that maps every
|
|
210
|
+
> turn to the `history_{n}.json` segment and message index it lives in — so no full history is
|
|
211
|
+
> read just to list the conversation.
|
|
212
|
+
>
|
|
213
|
+
> * **`<n>` is validated**: `last`, or a positive 1-based turn number. `0`, negatives and
|
|
214
|
+
> non-numbers are rejected with `No such turn` instead of silently showing a different turn.
|
|
215
|
+
> * **A bare `/reset` never destroys anything**: it reports `Already at turn N` when the
|
|
216
|
+
> transcript already ends at the last recorded turn, and *warns instead of truncating* if
|
|
217
|
+
> there are messages that were never recorded. Only `/reset <n>` / `/reset last` rewind.
|
|
218
|
+
> * **A rewind really sticks**: the target `history_{n}.json` is truncated in place (no backup)
|
|
219
|
+
> and every higher `history_{m}.json` / `usage_{m}.json` segment is deleted, so a restart
|
|
220
|
+
> cannot resurrect the dropped turns. All history files are written atomically.
|
|
221
|
+
> * **Token usage is never rolled back**: a rewind does not un-spend tokens, and the session
|
|
222
|
+
> total is preserved. See
|
|
223
|
+
> [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md#rewinding-reset-and-what-it-does-to-the-files)
|
|
224
|
+
> for the files involved.
|
|
225
|
+
|
|
226
|
+
## Development
|
|
227
|
+
|
|
228
|
+
Linting, the test suite, CI and the release process are documented in
|
|
229
|
+
[**docs/README_DEV.md**](docs/README_DEV.md).
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
python3 scripts/lint.py # lint (standard library only)
|
|
233
|
+
python3 -m unittest discover -s tests -p "test_*.py" # run the test suite
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Releases are cut by tagging `main`: pushing a `v*` tag triggers
|
|
237
|
+
[`.github/workflows/release.yml`](.github/workflows/release.yml), which builds the sdist + wheel,
|
|
238
|
+
verifies them with `twine check`, and attaches them to a new GitHub release.
|
|
239
|
+
|
|
240
|
+
## Documentation
|
|
241
|
+
|
|
242
|
+
Everything beyond this README lives in [`docs/`](docs/):
|
|
243
|
+
|
|
244
|
+
| Document | What it covers |
|
|
245
|
+
| --- | --- |
|
|
246
|
+
| [**docs/README_DEV.md**](docs/README_DEV.md) | developer guide — local setup, repository layout, linting, the test suite, CI and the release / PyPI upload process |
|
|
247
|
+
| [**docs/ARCHITECTURE.md**](docs/ARCHITECTURE.md) | design — module layout, on-disk conversation state (`history_{n}.json`, `summary_history.json`, usage files), the sub-agent framework and how to extend it |
|
|
248
|
+
|
|
249
|
+
This README stays the user-facing entry point (install, CLI flags, tools, sub-agents,
|
|
250
|
+
in-session commands, modes & safety); the two documents above go deeper on the developer
|
|
251
|
+
and design side.
|
|
252
|
+
|
|
253
|
+
## Modes & safety
|
|
254
|
+
|
|
255
|
+
### Shell execution — `-s` / `--enable-shell`
|
|
256
|
+
|
|
257
|
+
Everything the agent runs from the shell first passes a **safety classifier** that sorts the
|
|
258
|
+
command into one of three tiers:
|
|
259
|
+
|
|
260
|
+
| Tier | Examples | What happens |
|
|
261
|
+
| --- | --- | --- |
|
|
262
|
+
| **DENY** | `rm -rf /`, `dd of=/dev/...`, `mkfs.*`, fork bombs | refused outright, never run |
|
|
263
|
+
| **ASK** | `rm file`, `sudo ...`, `chmod`, `curl ... \| sh` | requires your confirmation |
|
|
264
|
+
| **ALLOW** | `ls`, `cat`, `git status` | runs without prompting |
|
|
265
|
+
|
|
266
|
+
`--sudo` removes the confirmation prompts (ASK tier and `--ask-permission`); DENY commands are
|
|
267
|
+
still refused. With no flags, an ASK-tier command prompts and an ALLOW-tier one runs unaided.
|
|
268
|
+
|
|
269
|
+
> [!WARNING]
|
|
270
|
+
> The classifier is **always enforced** — even in auto-mode and with `--sudo` — so the agent
|
|
271
|
+
> cannot run destructive commands unattended. It is a heuristic, not a sandbox: use it with care.
|
|
272
|
+
> `--allowed-dir` sandboxes **file tools**, not the shell.
|
|
273
|
+
|
|
274
|
+
### Plan mode — `-p` / `--plan`
|
|
275
|
+
|
|
276
|
+
The loop keeps two human-readable tracking files in the session directory: `CURRENT_GOAL.md`
|
|
277
|
+
(your latest instruction) and `CURRENT_PLAN.md` (a step-by-step plan for that goal, marked
|
|
278
|
+
finished when it is done). They are authored by the *loop*, not the agent, live outside
|
|
279
|
+
`--allowed-dir`, and can be inspected any time with `/plan`. The generated plan is
|
|
280
|
+
also printed as a box right after planning, so you can see it without asking.
|
|
281
|
+
Use `/skip-plan <prompt>` to send one prompt without planning it (plan mode stays
|
|
282
|
+
on for later turns).
|
|
283
|
+
|
|
284
|
+
`--plan-strategy` selects how planning is wired:
|
|
285
|
+
|
|
286
|
+
| Strategy | What happens |
|
|
287
|
+
| --- | --- |
|
|
288
|
+
| `plan-verify-step` (default) | Current behaviour: author a plan, review it once the work settles, then run one extra step and keep whatever that step says. |
|
|
289
|
+
| `plan-verify` | Same plan + review, but the post-review step is kept only when it calls a tool. A no-tool answer is shown to you and ends the turn without being appended to the transcript. |
|
|
290
|
+
| `open-plan` | The agent owns a plan document at `.mini/PLAN.md` inside `--allowed-dir`, reads and updates it with the normal file tools, and the loop neither authors nor reviews a plan. |
|
|
291
|
+
|
|
292
|
+
> [!NOTE]
|
|
293
|
+
> Plan mode also changes **history compaction**: after the transcript is compacted to a summary,
|
|
294
|
+
> `CURRENT_PLAN.md` and `CURRENT_GOAL.md` are re-injected, so the agent keeps working against the
|
|
295
|
+
> same goal. With `open-plan`, the agent's `.mini/PLAN.md` is re-injected instead. When the work
|
|
296
|
+
> looks done the plan is reviewed and any outstanding task is re-queued before the agent returns
|
|
297
|
+
> to you (except with `open-plan`).
|
|
298
|
+
|
|
299
|
+
### Scratchpad — `--scratchpad`
|
|
300
|
+
|
|
301
|
+
With `--scratchpad`, the loop creates `.mini/SCRATCHPAD.md` inside `--allowed-dir` and tells the
|
|
302
|
+
agent that it may read and write that file freely, and may create additional scratch files in the
|
|
303
|
+
same directory (for example `SCRATCH-NOTES.md`, `SCRATCH-IDEAS.md`). The scratchpad is ordinary
|
|
304
|
+
state inside the sandbox, so the normal `read_file` / `write_file` / `edit` tools work; no special
|
|
305
|
+
tool is registered. It is meant for the agent's own thoughts, plans, learnings and open questions,
|
|
306
|
+
and survives a history compaction because it lives on disk.
|
|
307
|
+
|
|
308
|
+
### Sessions — resume, or start fresh
|
|
309
|
+
|
|
310
|
+
Every session is saved under `--cache-dir` (default `~/.cache/mini/sessions/`).
|
|
311
|
+
|
|
312
|
+
> [!TIP]
|
|
313
|
+
> If a previous session exists but you did **not** ask to resume one (neither
|
|
314
|
+
> `--load-last-session` nor `--restore-session`), the prompt offers **Resume / Start new / Exit**
|
|
315
|
+
> before the conversation begins. Ctrl-C or EOF there is a graceful exit. This is the *asking*
|
|
316
|
+
> variant; `--load-last-session` is the *silent* one.
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
| Flag | Behaviour |
|
|
320
|
+
| --- | --- |
|
|
321
|
+
| `--restore-session PATH` | continue that exact session (a session directory or a bare session id under `--cache-dir`) |
|
|
322
|
+
| `-l`, `--load-last-session` | continue the session recorded in the `.mini/last_session.json` pointer, without asking |
|
|
323
|
+
|
|
324
|
+
`--load-last-session` continues that session **in place** (same id, same folder, same
|
|
325
|
+
messages), so the conversation you were in is the one you get back; an explicit
|
|
326
|
+
`--restore-session` wins if both are given. The "most recent" session comes from a single
|
|
327
|
+
source — the tiny `.mini/last_session.json` pointer written when a session starts or is
|
|
328
|
+
restored inside `--allowed-dir` (deliberately no timestamp fallback: with no pointer, a fresh
|
|
329
|
+
session starts). That pointer lives in the same `.mini` directory as `--skills`, but as its
|
|
330
|
+
own dedicated file, so the two never clash.
|
|
331
|
+
|
|
332
|
+
A session folder is restorable only if it has what this version writes: a valid
|
|
333
|
+
`summary_history.json` recorder, plus the `history_{n}.json` segment its last record names
|
|
334
|
+
(usage files are optional). Anything else — a folder from an older release, a hand-assembled
|
|
335
|
+
transcript, a recorder that does not validate, a missing segment — is **refused with a note
|
|
336
|
+
saying why**, and a fresh session is started instead. Nothing is repaired, guessed at, or
|
|
337
|
+
written into the refused folder.
|
|
338
|
+
|
|
339
|
+
### Context compaction — `--max-context-tokens`
|
|
340
|
+
|
|
341
|
+
Compaction is decided by **tokens only**, never by message count: a few large tool outputs can
|
|
342
|
+
fill a window that hundreds of short turns would not. The next request is projected from the
|
|
343
|
+
server-reported `prompt_tokens`, plus an estimate of what was appended since, plus the output
|
|
344
|
+
reserve (`--max-tokens`). Unset (default) it is derived from the model's context window minus the
|
|
345
|
+
output reserve and a safety margin. Lower it to compact sooner, raise it to compact later — there
|
|
346
|
+
is no message-count cap to configure.
|
|
347
|
+
|
|
348
|
+
Compaction replaces the older turns with a summary, but it always carries the **turn in flight**
|
|
349
|
+
across the rollover: the message you just typed (or, mid-turn, the tool call the model is
|
|
350
|
+
waiting on) is kept verbatim after the summary. So a compaction that fires just as you send an
|
|
351
|
+
instruction cannot swallow it — the model still answers what you asked, and the turn stays in
|
|
352
|
+
the session file, in `/history` and in a later restore.
|
|
353
|
+
|
|
354
|
+
`--compaction-strategy` chooses what else survives besides the summary:
|
|
355
|
+
|
|
356
|
+
| Strategy | Messages after compaction |
|
|
357
|
+
| --- | --- |
|
|
358
|
+
| `summarise` (default) | `system`, `summary`, `plan`, `current turn` |
|
|
359
|
+
| `predict-files` | `system`, `summary`, predicted read-only tool calls + results, `plan`, `current turn` |
|
|
360
|
+
| `predict-messages` | `system`, `summary`, original messages the model names by index, `plan`, `current turn` |
|
|
361
|
+
|
|
362
|
+
`predict-files` asks the model which files it needs to re-read and executes only the read-only
|
|
363
|
+
tools (`read_file`, `grep`, `glob`) it predicts; `predict-messages` asks for a JSON array of
|
|
364
|
+
0-based message indexes to keep verbatim. Both predictions are one extra tool-free (or
|
|
365
|
+
read-only-tool) LLM call, are billed normally, and are capped so they cannot refill the context
|
|
366
|
+
they just freed. A failed prediction degrades to the plain summary.
|
|
367
|
+
|
|
368
|
+
Because a rollover leaves no trace in the transcript (the old turns really are gone), the
|
|
369
|
+
console says in plain terms what happened — all of it without `--verbose`:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
[!] Compacting the conversation: 42 messages -> a summary (51000 tokens in, 8192 reserved for the reply > 52000 budget). The current turn (1 message) is kept verbatim.
|
|
373
|
+
[!] Summary preview: The user asked for a token-based compaction trigger, then fixed ...
|
|
374
|
+
[!] Compacted history_0.json (42 messages) into a summary; history_1.json now starts with 3 messages (summary + 1 kept message).
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
So you can see *what* was folded away (a preview of the summary itself), *how much* (the
|
|
378
|
+
message count of the segment that was closed), *where it went* (`history_0.json` closed,
|
|
379
|
+
`history_1.json` started) and that nothing you just typed was lost. If the summariser answers
|
|
380
|
+
with an empty summary twice, or the call fails, compaction is abandoned and the note says so
|
|
381
|
+
explicitly — "nothing was lost, but the next request may still be too large" — with the
|
|
382
|
+
transcript and the segment left untouched.
|
|
383
|
+
|
|
384
|
+
### Exiting — the good-bye box
|
|
385
|
+
|
|
386
|
+
Quitting (`/quit`, `exit`, or EOF on stdin) saves the session and then prints a short yellow
|
|
387
|
+
box: the version, a sign-off, and what the session left behind — session id, folder, the
|
|
388
|
+
history segments on disk, how many turns were recorded, and the token / call totals.
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
╔══════════ MiniCodeCLI v0.1.1.2 - goodbye ═════════════════════╗
|
|
392
|
+
║ Goodbye, and thanks for using MiniCodeCLI! ║
|
|
393
|
+
║ ║
|
|
394
|
+
║ session id : 1792666273983619-36ca3c2e ║
|
|
395
|
+
║ saved under : ~/.cache/mini/sessions/1792…-36ca3c2e/ ║
|
|
396
|
+
║ history : history_0.json (segment 0), 5 messages ║
|
|
397
|
+
║ conversation : 2 recorded turns ║
|
|
398
|
+
║ tokens : 20 in / 10 out (30 total) ║
|
|
399
|
+
║ calls : 2 LLM, 0 tool ║
|
|
400
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
It is printed exactly once, and only on a normal exit: a Ctrl-C or an internal error already
|
|
404
|
+
says what went wrong in red, so it does not get a cheerful summary box on top. With `--verbose`
|
|
405
|
+
the old per-field `Token usage (this session)` block is printed above it as well.
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
## Serving a model locally
|
|
409
|
+
|
|
410
|
+
Tested with vLLM v0.30 (tool calling enabled):
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
vllm serve ornith-ai/Ornith-1.5-397B-FP8 \
|
|
414
|
+
--tensor-parallel-size 4 \
|
|
415
|
+
--host 0.0.0.0 \
|
|
416
|
+
--port 30000 \
|
|
417
|
+
--enable-auto-tool-choice \
|
|
418
|
+
--tool-call-parser qwen3_xml \
|
|
419
|
+
--reasoning-parser qwen3 \
|
|
420
|
+
--trust-remote-code
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Citation
|
|
424
|
+
|
|
425
|
+
If you use `mini-code-cli` in your research or writing, please cite it:
|
|
426
|
+
|
|
427
|
+
```bibtex
|
|
428
|
+
@misc{mini-code-cli,
|
|
429
|
+
author = {Rozanov, Nikolai},
|
|
430
|
+
title = {mini-code-cli: A minimal, dependency-light coding agent},
|
|
431
|
+
year = {2026},
|
|
432
|
+
version = {0.1.1.4},
|
|
433
|
+
howpublished = {\url{https://github.com/ai-nikolai/mini-code-cli}},
|
|
434
|
+
note = {A no-bloat, dependency-light agent CLI for experimenting.}
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## License
|
|
439
|
+
|
|
440
|
+
[AGPL-3.0](LICENSE) — (C) Nikolai Rozanov, 2026 – present.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](LICENSE)
|
|
12
12
|
[](#citation)
|
|
13
13
|
|
|
14
|
-
**Purpose:** a no-bloat, minimal coding CLI to enjoy experimenting and researching
|
|
14
|
+
**Purpose:** a no-bloat, minimal coding CLI to enjoy experimenting and researching!
|
|
15
15
|
|
|
16
16
|
**Install** · [Quick start](#quick-start) · [Modes & safety](#modes--safety) · [Options](#command-line-options) · [Tools](#available-tools) · [Sub-agents](#sub-agents) · [In-session commands](#in-session-commands) · [Development](#development) · [Docs](#documentation) · [Citation](#citation)
|
|
17
17
|
|
|
@@ -48,7 +48,7 @@ mini-code --url "https://api.deepseek.com" --model "deepseek-v4-flash"
|
|
|
48
48
|
**3 — The shortcuts** (plan mode, sub-agents, shell, auto-mode, no permission prompts):
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
mini-code --all # = --plan --enable-subagents --enable-shell --auto-mode --sudo
|
|
51
|
+
mini-code --all # = --plan --enable-subagents --enable-shell --skills --auto-mode --sudo
|
|
52
52
|
mini-code --all-last # ...and continue your last session
|
|
53
53
|
```
|
|
54
54
|
|
|
@@ -76,20 +76,23 @@ given a reference implementation.
|
|
|
76
76
|
| `--prompt TEXT` | — | initial user prompt |
|
|
77
77
|
| `-a`, `--auto-mode` | off | keep querying the model and running tools until no tool calls remain |
|
|
78
78
|
| `--agent-md FILE` | — | append an `agent.md` file after the system prompt (e.g. `./skill.md`) |
|
|
79
|
-
| `--ask-permission` | off | ask before every tool call
|
|
79
|
+
| `--ask-permission` | off | ask before **every** tool call, including an ALLOW-tier shell command (`--sudo` disables all prompts) |
|
|
80
80
|
| `--sudo` | off | **dangerous:** never ask. DENY-tier commands are still refused |
|
|
81
81
|
| `--allowed-dir DIR` | `./` | sandbox for **file** tools (does not restrict the shell) |
|
|
82
82
|
| `-s`, `--enable-shell` | off | allow shell execution (classifier always applies) |
|
|
83
83
|
| `-g`, `--enable-subagents` | off | expose sub-agents as tools |
|
|
84
|
-
| `--skills` | off | enable the `.mini` skills directory (`skill.md`s, `SKILLS.md`, runnable scripts) |
|
|
85
|
-
| `-p`, `--plan` | off | plan mode (`CURRENT_GOAL.md` / `CURRENT_PLAN.md`, `/plan`) |
|
|
84
|
+
| `--skills` | off | enable the `.mini` skills directory (`skill.md`s, `SKILLS.md`, runnable scripts). **`run_skill` executes those Python scripts — arbitrary code execution, even without `--enable-shell`**; only enable it for a directory you trust |
|
|
85
|
+
| `-p`, `--plan` | off | plan mode (`CURRENT_GOAL.md` / `CURRENT_PLAN.md`, printed plan, `/plan`, `/skip-plan`) |
|
|
86
|
+
| `--plan-strategy NAME` | `plan-verify-step` | `plan-verify-step`, `plan-verify` or `open-plan` (implies `--plan`) |
|
|
87
|
+
| `--scratchpad` | off | give the agent a free-form `.mini/SCRATCHPAD.md` (plus further scratch files) for thoughts, plans and learnings |
|
|
88
|
+
| `--compaction-strategy NAME` | `summarise` | `summarise`, `predict-files` or `predict-messages` |
|
|
86
89
|
| `--llm-timeout S` | `500` | HTTP timeout for LLM requests |
|
|
87
90
|
| `--tool-timeout S` | `120` | timeout for a single tool call |
|
|
88
91
|
| `--max-context-tokens N` | derived | input-token budget before the history is compacted |
|
|
89
92
|
| `--cache-dir DIR` | `~/.cache/mini/sessions/` | where session histories are stored |
|
|
90
93
|
| `--restore-session PATH` | — | continue a specific previous session |
|
|
91
94
|
| `-l`, `--load-last-session` | off | continue the session recorded in the `.mini` pointer |
|
|
92
|
-
| `--all` | off | `--plan --enable-subagents --enable-shell --auto-mode --sudo` |
|
|
95
|
+
| `--all` | off | `--plan --enable-subagents --enable-shell --skills --auto-mode --sudo` |
|
|
93
96
|
| `--all-last` | off | `--all` + `--load-last-session` |
|
|
94
97
|
| `--verbose` | off | print full detail (default: user/assistant turns, token usage, tool calls only) |
|
|
95
98
|
| `-h`, `--help` | — | show the built-in help |
|
|
@@ -132,8 +135,10 @@ mini-code --enable-subagents # the available sub-agents then show up in /h
|
|
|
132
135
|
|
|
133
136
|
> [!NOTE]
|
|
134
137
|
> A sub-agent's `tools`, `enable_shell` and `max_steps` are always **intersected with the
|
|
135
|
-
> parent's** permissions, so it can never do anything the main agent could not.
|
|
136
|
-
>
|
|
138
|
+
> parent's** permissions, so it can never do anything the main agent could not. The `tools`
|
|
139
|
+
> allowlist is enforced on the nested session itself (both the schemas offered to the model and
|
|
140
|
+
> the dispatch table), not merely described in its prompt. Sub-agents compose with `--plan`:
|
|
141
|
+
> each keeps its own `CURRENT_PLAN.md` / `CURRENT_GOAL.md`.
|
|
137
142
|
|
|
138
143
|
<details>
|
|
139
144
|
<summary><b>Adding your own sub-agent</b></summary>
|
|
@@ -171,9 +176,16 @@ to the model automatically when `--enable-subagents` is set. See
|
|
|
171
176
|
| `/reset [<n>]` | rewind to the end of turn `n` (`last` works too); drops everything after it |
|
|
172
177
|
| `/clear` | clear the screen (keeps the conversation history) |
|
|
173
178
|
| `/plan` | show the current goal + plan (plan mode only) |
|
|
179
|
+
| `/context` | show how the context window is used: tokens and percentages by category (system prompt, user/assistant messages, tool calls/outputs, reasoning, overhead) |
|
|
180
|
+
| `/skip-plan <prompt>` | send `<prompt>` once without generating or reviewing a plan |
|
|
174
181
|
| `/help` | show this help |
|
|
175
182
|
| `/quit`, `/exit` | save the session and exit |
|
|
176
183
|
|
|
184
|
+
**Multi-line input:** press `Shift+Enter` (or `Ctrl-J`) to insert a newline; plain
|
|
185
|
+
`Enter` sends the turn. This works in the session prompt and the startup tip
|
|
186
|
+
reminds you. Terminals that report `Shift+Enter` as a CSI-u/modifyOtherKeys
|
|
187
|
+
sequence are recognised; elsewhere `Ctrl-J` inserts the newline.
|
|
188
|
+
|
|
177
189
|
> [!NOTE]
|
|
178
190
|
> `/history` and `/reset` are driven by `summary_history.json`, a flat recorder that maps every
|
|
179
191
|
> turn to the `history_{n}.json` segment and message index it lives in — so no full history is
|
|
@@ -232,6 +244,9 @@ command into one of three tiers:
|
|
|
232
244
|
| **ASK** | `rm file`, `sudo ...`, `chmod`, `curl ... \| sh` | requires your confirmation |
|
|
233
245
|
| **ALLOW** | `ls`, `cat`, `git status` | runs without prompting |
|
|
234
246
|
|
|
247
|
+
`--sudo` removes the confirmation prompts (ASK tier and `--ask-permission`); DENY commands are
|
|
248
|
+
still refused. With no flags, an ASK-tier command prompts and an ALLOW-tier one runs unaided.
|
|
249
|
+
|
|
235
250
|
> [!WARNING]
|
|
236
251
|
> The classifier is **always enforced** — even in auto-mode and with `--sudo` — so the agent
|
|
237
252
|
> cannot run destructive commands unattended. It is a heuristic, not a sandbox: use it with care.
|
|
@@ -242,13 +257,34 @@ command into one of three tiers:
|
|
|
242
257
|
The loop keeps two human-readable tracking files in the session directory: `CURRENT_GOAL.md`
|
|
243
258
|
(your latest instruction) and `CURRENT_PLAN.md` (a step-by-step plan for that goal, marked
|
|
244
259
|
finished when it is done). They are authored by the *loop*, not the agent, live outside
|
|
245
|
-
`--allowed-dir`, and can be inspected any time with `/plan`.
|
|
260
|
+
`--allowed-dir`, and can be inspected any time with `/plan`. The generated plan is
|
|
261
|
+
also printed as a box right after planning, so you can see it without asking.
|
|
262
|
+
Use `/skip-plan <prompt>` to send one prompt without planning it (plan mode stays
|
|
263
|
+
on for later turns).
|
|
264
|
+
|
|
265
|
+
`--plan-strategy` selects how planning is wired:
|
|
266
|
+
|
|
267
|
+
| Strategy | What happens |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| `plan-verify-step` (default) | Current behaviour: author a plan, review it once the work settles, then run one extra step and keep whatever that step says. |
|
|
270
|
+
| `plan-verify` | Same plan + review, but the post-review step is kept only when it calls a tool. A no-tool answer is shown to you and ends the turn without being appended to the transcript. |
|
|
271
|
+
| `open-plan` | The agent owns a plan document at `.mini/PLAN.md` inside `--allowed-dir`, reads and updates it with the normal file tools, and the loop neither authors nor reviews a plan. |
|
|
246
272
|
|
|
247
273
|
> [!NOTE]
|
|
248
274
|
> Plan mode also changes **history compaction**: after the transcript is compacted to a summary,
|
|
249
275
|
> `CURRENT_PLAN.md` and `CURRENT_GOAL.md` are re-injected, so the agent keeps working against the
|
|
250
|
-
> same goal.
|
|
251
|
-
> before the agent returns
|
|
276
|
+
> same goal. With `open-plan`, the agent's `.mini/PLAN.md` is re-injected instead. When the work
|
|
277
|
+
> looks done the plan is reviewed and any outstanding task is re-queued before the agent returns
|
|
278
|
+
> to you (except with `open-plan`).
|
|
279
|
+
|
|
280
|
+
### Scratchpad — `--scratchpad`
|
|
281
|
+
|
|
282
|
+
With `--scratchpad`, the loop creates `.mini/SCRATCHPAD.md` inside `--allowed-dir` and tells the
|
|
283
|
+
agent that it may read and write that file freely, and may create additional scratch files in the
|
|
284
|
+
same directory (for example `SCRATCH-NOTES.md`, `SCRATCH-IDEAS.md`). The scratchpad is ordinary
|
|
285
|
+
state inside the sandbox, so the normal `read_file` / `write_file` / `edit` tools work; no special
|
|
286
|
+
tool is registered. It is meant for the agent's own thoughts, plans, learnings and open questions,
|
|
287
|
+
and survives a history compaction because it lives on disk.
|
|
252
288
|
|
|
253
289
|
### Sessions — resume, or start fresh
|
|
254
290
|
|
|
@@ -296,6 +332,20 @@ waiting on) is kept verbatim after the summary. So a compaction that fires just
|
|
|
296
332
|
instruction cannot swallow it — the model still answers what you asked, and the turn stays in
|
|
297
333
|
the session file, in `/history` and in a later restore.
|
|
298
334
|
|
|
335
|
+
`--compaction-strategy` chooses what else survives besides the summary:
|
|
336
|
+
|
|
337
|
+
| Strategy | Messages after compaction |
|
|
338
|
+
| --- | --- |
|
|
339
|
+
| `summarise` (default) | `system`, `summary`, `plan`, `current turn` |
|
|
340
|
+
| `predict-files` | `system`, `summary`, predicted read-only tool calls + results, `plan`, `current turn` |
|
|
341
|
+
| `predict-messages` | `system`, `summary`, original messages the model names by index, `plan`, `current turn` |
|
|
342
|
+
|
|
343
|
+
`predict-files` asks the model which files it needs to re-read and executes only the read-only
|
|
344
|
+
tools (`read_file`, `grep`, `glob`) it predicts; `predict-messages` asks for a JSON array of
|
|
345
|
+
0-based message indexes to keep verbatim. Both predictions are one extra tool-free (or
|
|
346
|
+
read-only-tool) LLM call, are billed normally, and are capped so they cannot refill the context
|
|
347
|
+
they just freed. A failed prediction degrades to the plain summary.
|
|
348
|
+
|
|
299
349
|
Because a rollover leaves no trace in the transcript (the old turns really are gone), the
|
|
300
350
|
console says in plain terms what happened — all of it without `--verbose`:
|
|
301
351
|
|
|
@@ -312,6 +362,29 @@ with an empty summary twice, or the call fails, compaction is abandoned and the
|
|
|
312
362
|
explicitly — "nothing was lost, but the next request may still be too large" — with the
|
|
313
363
|
transcript and the segment left untouched.
|
|
314
364
|
|
|
365
|
+
### Exiting — the good-bye box
|
|
366
|
+
|
|
367
|
+
Quitting (`/quit`, `exit`, or EOF on stdin) saves the session and then prints a short yellow
|
|
368
|
+
box: the version, a sign-off, and what the session left behind — session id, folder, the
|
|
369
|
+
history segments on disk, how many turns were recorded, and the token / call totals.
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
╔══════════ MiniCodeCLI v0.1.1.2 - goodbye ═════════════════════╗
|
|
373
|
+
║ Goodbye, and thanks for using MiniCodeCLI! ║
|
|
374
|
+
║ ║
|
|
375
|
+
║ session id : 1792666273983619-36ca3c2e ║
|
|
376
|
+
║ saved under : ~/.cache/mini/sessions/1792…-36ca3c2e/ ║
|
|
377
|
+
║ history : history_0.json (segment 0), 5 messages ║
|
|
378
|
+
║ conversation : 2 recorded turns ║
|
|
379
|
+
║ tokens : 20 in / 10 out (30 total) ║
|
|
380
|
+
║ calls : 2 LLM, 0 tool ║
|
|
381
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
It is printed exactly once, and only on a normal exit: a Ctrl-C or an internal error already
|
|
385
|
+
says what went wrong in red, so it does not get a cheerful summary box on top. With `--verbose`
|
|
386
|
+
the old per-field `Token usage (this session)` block is printed above it as well.
|
|
387
|
+
|
|
315
388
|
|
|
316
389
|
## Serving a model locally
|
|
317
390
|
|
|
@@ -337,9 +410,9 @@ If you use `mini-code-cli` in your research or writing, please cite it:
|
|
|
337
410
|
author = {Rozanov, Nikolai},
|
|
338
411
|
title = {mini-code-cli: A minimal, dependency-light coding agent},
|
|
339
412
|
year = {2026},
|
|
340
|
-
version = {0.1.1.
|
|
413
|
+
version = {0.1.1.4},
|
|
341
414
|
howpublished = {\url{https://github.com/ai-nikolai/mini-code-cli}},
|
|
342
|
-
note = {A no-bloat, dependency-
|
|
415
|
+
note = {A no-bloat, dependency-light agent CLI for experimenting.}
|
|
343
416
|
}
|
|
344
417
|
```
|
|
345
418
|
|