mini-code-cli 0.1.0.3__tar.gz → 0.1.1.0__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.
Files changed (52) hide show
  1. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/PKG-INFO +214 -136
  2. mini_code_cli-0.1.1.0/README.md +288 -0
  3. mini_code_cli-0.1.1.0/mini_code_cli/__init__.py +40 -0
  4. mini_code_cli-0.1.1.0/mini_code_cli/agent_loop.py +1807 -0
  5. mini_code_cli-0.1.1.0/mini_code_cli/config.py +231 -0
  6. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/persistence.py +187 -121
  7. mini_code_cli-0.1.1.0/mini_code_cli/plan.py +156 -0
  8. mini_code_cli-0.1.1.0/mini_code_cli/prompts.py +273 -0
  9. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/sandbox.py +32 -9
  10. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/skills.py +96 -2
  11. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/subagents/base.py +60 -10
  12. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/subagents/builtin.py +15 -9
  13. mini_code_cli-0.1.1.0/mini_code_cli/tokens.py +118 -0
  14. mini_code_cli-0.1.1.0/mini_code_cli/tools.py +673 -0
  15. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/ui.py +137 -25
  16. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/utils.py +86 -20
  17. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli.egg-info/PKG-INFO +214 -136
  18. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli.egg-info/SOURCES.txt +4 -11
  19. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/pyproject.toml +9 -1
  20. mini_code_cli-0.1.1.0/tests/test_e2e_agent_loop.py +1096 -0
  21. mini_code_cli-0.1.1.0/tests/test_interactive.py +628 -0
  22. mini_code_cli-0.1.1.0/tests/test_subagents.py +368 -0
  23. mini_code_cli-0.1.1.0/tests/test_tokens.py +405 -0
  24. mini_code_cli-0.1.0.3/README.md +0 -216
  25. mini_code_cli-0.1.0.3/mini_code_cli/__init__.py +0 -2
  26. mini_code_cli-0.1.0.3/mini_code_cli/agent_loop.py +0 -1368
  27. mini_code_cli-0.1.0.3/mini_code_cli/config.py +0 -19
  28. mini_code_cli-0.1.0.3/mini_code_cli/plan.py +0 -154
  29. mini_code_cli-0.1.0.3/mini_code_cli/prompts.py +0 -125
  30. mini_code_cli-0.1.0.3/mini_code_cli/tools.py +0 -292
  31. mini_code_cli-0.1.0.3/tests/test_agent_loop.py +0 -250
  32. mini_code_cli-0.1.0.3/tests/test_integration.py +0 -106
  33. mini_code_cli-0.1.0.3/tests/test_last_session_pointer.py +0 -218
  34. mini_code_cli-0.1.0.3/tests/test_plan.py +0 -287
  35. mini_code_cli-0.1.0.3/tests/test_resume_offer.py +0 -178
  36. mini_code_cli-0.1.0.3/tests/test_robustness.py +0 -179
  37. mini_code_cli-0.1.0.3/tests/test_sandboxing.py +0 -91
  38. mini_code_cli-0.1.0.3/tests/test_shell_safety.py +0 -103
  39. mini_code_cli-0.1.0.3/tests/test_skills.py +0 -245
  40. mini_code_cli-0.1.0.3/tests/test_subagents.py +0 -361
  41. mini_code_cli-0.1.0.3/tests/test_tools.py +0 -85
  42. mini_code_cli-0.1.0.3/tests/test_ui.py +0 -144
  43. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/LICENSE +0 -0
  44. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/permissions.py +0 -0
  45. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/runner.py +0 -0
  46. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/shell_safety_utils.py +0 -0
  47. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli/subagents/__init__.py +0 -0
  48. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli.egg-info/dependency_links.txt +0 -0
  49. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli.egg-info/entry_points.txt +0 -0
  50. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli.egg-info/requires.txt +0 -0
  51. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/mini_code_cli.egg-info/top_level.txt +0 -0
  52. {mini_code_cli-0.1.0.3 → mini_code_cli-0.1.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mini-code-cli
3
- Version: 0.1.0.3
3
+ Version: 0.1.1.0
4
4
  Summary: Mini Coding Agent. Allows you to easily experiment with a small coding agent.
5
5
  Author-email: Nikolai Rozanov <nikolai.rozanov@gmail.com>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -666,95 +666,159 @@ License: GNU AFFERO GENERAL PUBLIC LICENSE
666
666
  <https://www.gnu.org/licenses/>.
667
667
 
668
668
  Project-URL: Homepage, https://github.com/ai-nikolai/mini-code-cli
669
+ Classifier: Programming Language :: Python :: 3
670
+ Classifier: Programming Language :: Python :: 3.10
671
+ Classifier: Programming Language :: Python :: 3.11
672
+ Classifier: Programming Language :: Python :: 3.12
673
+ Classifier: Programming Language :: Python :: 3.13
674
+ Classifier: Operating System :: OS Independent
669
675
  Requires-Python: >=3.10
670
676
  Description-Content-Type: text/markdown
671
677
  License-File: LICENSE
672
678
  Requires-Dist: requests<3,>=2.31
673
679
  Dynamic: license-file
674
680
 
675
- # A minimal coding agent cli
681
+ # mini-code-cli
682
+
683
+ ### A minimal coding agent CLI
676
684
 
677
685
  > No bloat, no dependencies, no tracking, no telemetry...
678
686
 
679
- Purpose: A no bloat, minimal coding cli, to enjoy experimenting and researching...
687
+ [![CI](https://img.shields.io/github/actions/workflow/status/ai-nikolai/mini-code-cli/ci.yml?branch=main&label=CI&logo=github&style=flat-square)](https://github.com/ai-nikolai/mini-code-cli/actions/workflows/ci.yml)
688
+ [![PyPI](https://img.shields.io/pypi/v/mini-code-cli?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/mini-code-cli/)
689
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue?style=flat-square&logo=python&logoColor=white)](https://pypi.org/project/mini-code-cli/)
690
+ [![Stars](https://img.shields.io/github/stars/ai-nikolai/mini-code-cli?style=flat-square&logo=github)](https://github.com/ai-nikolai/mini-code-cli/stargazers)
691
+ [![License: AGPL v3](https://img.shields.io/badge/license-AGPL--3.0-blue?style=flat-square)](LICENSE)
692
+ [![Cite](https://img.shields.io/badge/cite-BibTeX-blueviolet?style=flat-square&logo=latex&logoColor=white)](#citation)
693
+
694
+ **Purpose:** a no-bloat, minimal coding CLI to enjoy experimenting and researching.
695
+
696
+ **Install** · [Quick start](#quick-start) · [Modes &amp; safety](#modes--safety) · [Options](#command-line-options) · [Tools](#available-tools) · [Sub-agents](#sub-agents) · [In-session commands](#in-session-commands) · [Development](#development) · [Citation](#citation)
680
697
 
681
- ## Getting started:
698
+ > [!TIP]
699
+ > **New here?** `pip install mini-code-cli`, point it at a model (a local server on
700
+ > `localhost:30000`, or `MINI_CODE_API_KEY` + `--url`), and run `mini-code`. Everything else
701
+ > is optional.
702
+
703
+ ## Install
682
704
 
683
- ### Installation (from pypi)
684
705
  ```bash
685
706
  pip3 install mini-code-cli
686
707
  ```
687
708
 
688
- ### Run agent:
709
+ - **PyPI:** <https://pypi.org/project/mini-code-cli/>
710
+ - **Python:** `>= 3.10` &nbsp;·&nbsp; **runtime dependency:** `requests` only
711
+ - **From source / contributing:** see [README_DEV.md](README_DEV.md)
712
+
713
+ ## Quick start
714
+
715
+ **1 — Local model** (e.g. vLLM or SGLang on port 30000; see [serving a model locally](#serving-a-model-locally)):
689
716
 
690
- 1. Basic usage: (get local LLM running (e.g. via SGLang or Vllm))
691
717
  ```bash
692
- mini-code #run the agent using `localhost:30000/v1` model
718
+ mini-code # talks to http://0.0.0.0:30000/v1
693
719
  ```
694
- 2. Custom API based model:
720
+
721
+ **2 — Hosted / custom API:**
722
+
695
723
  ```bash
696
724
  export MINI_CODE_API_KEY="sk-YOUR_API_KEY"
697
725
  mini-code --url "https://api.deepseek.com" --model "deepseek-v4-flash"
698
726
  ```
699
- 3. Auto-mode and shell enabled: (this will run localhost:30000)
700
- ```bash
701
- mini-code --enable-shell --auto-mode
702
- mini-code -s -a --sudo
703
- mini-code -s -a -p -g -l --sudo #plan, previous session, subagents (#or short-hand the next commands)
704
- mini-code --all
705
- mini-code --all-last
706
- ```
707
727
 
708
- 4. Advanced usage:
709
- Auto-mode, Agent.md, Shell Enabled mode and a specific allowed dir:
728
+ **3 — The shortcuts** (plan mode, sub-agents, shell, auto-mode, no permission prompts):
729
+
710
730
  ```bash
711
- mini-code --enable-shell --auto-mode --agent-md "./skill.md" --allowed-dir "./" --ask-permission --system-prompt "Your awesome new system prompt..."
731
+ mini-code --all # = --plan --enable-subagents --enable-shell --auto-mode --sudo
732
+ mini-code --all-last # ...and continue your last session
712
733
  ```
713
- - auto-mode: the agent will continue querying the LLM and executing tools, until no more tool calls are possible
714
- - agent.md: this will read an agent.md file with the specified name (e.g. ./skill.md)
715
- - shell-enabled: **Be careful**: This will allow the agent to execute shell commands. **Every command is first checked by a shell-safety classifier** that sorts it into three tiers:
716
- - **DENY** — obviously destructive commands (e.g. `rm -rf /`, `dd of=/dev/...`, `mkfs.*`, fork bombs) are **refused outright** and never run.
717
- - **ASK** — risky commands (e.g. `rm file`, `sudo ...`, `chmod`, `curl ... | sh`) require your confirmation before running.
718
- - **ALLOW** — clearly safe commands (e.g. `ls`, `cat`, `git status`) run without prompting.
719
- This protection is **always enforced** for the shell tool, even in auto-mode / without `--ask-permission`, so the agent can never run dangerous commands unattended. (The classifier is a heuristic, not a sandbox — use with care.)
720
- - allowed-dir: this specifies which dirs the agent can read and write from, that does not stop the shell comands! (though dangerous shell commands are still blocked by the classifier above).
721
- - ask-permission: asks user permission before every tool call. For shell commands, commands in the ALLOW tier skip the prompt, DENY is blocked, and ASK always prompts.
722
- - system-prompt: you can override the default prompt by using a string. (Note: Agent.md is always appended after the system prompt.)
723
- - load-last-session: instead of starting a fresh conversation, automatically continue your most recently active session from the default cache dir. It resumes under a brand-new session id, so the original session is never overwritten. An explicit `--restore-session` (a specific path) takes precedence if both are given. The "most recent" session is resolved in two steps: at the end of every interactive session, its path is recorded in a tiny `.mini/last_session.json` pointer inside the `--allowed-dir`, and `--load-last-session` consults that pointer first; only if there is no pointer (e.g. a fresh allowed dir, or the `--skills` feature disabled) does it fall back to the timestamp heuristic (the session whose history was modified most recently). The `.mini` pointer is the same directory the `--skills` feature uses, but it is a single dedicated file, so the two never clash.
724
- - **Interactive session offer:** if a previous session exists in the cache dir but you did **not** explicitly ask to resume one (i.e. neither `--load-last-session` nor `--restore-session` was passed), the prompt asks what you'd like to do before the conversation starts: 1) **Resume** the previous session (splice its history in under a brand-new session id and continue it), 2) **Start a new** session (empty history), or 3) **Exit** (start nothing). Ctrl-C / EOF at the offer is treated as a graceful exit. This is distinct from `--load-last-session`, which silently resumes the most recent session without asking.
725
- - plan: `--plan` enables **plan mode**. The agent now keeps two tracking files in the session directory: `CURRENT_GOAL.md` (the user's latest instruction) and `CURRENT_PLAN.md` (its own step-by-step plan, which it must update as it works and mark finished once the goal is done). The system message gets an extra instruction telling the agent to do this. Plan mode also changes how history compaction works: after the history is compacted to a summary, the current `CURRENT_PLAN.md` and the user's last instruction (`CURRENT_GOAL.md`) are re-injected into the messages so the agent keeps working against the same goal. When the session ends, the active goal is marked finished in `CURRENT_PLAN.md`.
726
734
 
727
- ### Available tools
735
+ **4 — A first prompt:**
728
736
 
729
- The agent can call a small set of tools, all of which live in `mini_code_cli/tools.py`:
730
-
731
- - **`read_file` / `write_file`** — read a file or write/overwrite one.
732
- - **`grep`** — search a file for a pattern.
733
- - **`glob`** — list files matching a glob pattern.
734
- - **`web_search`** — best-effort web lookup: returns popular related queries (DuckDuckGo autocomplete) plus a short extract from the top Wikipedia match. Never raises; always returns a string.
735
- - **`read_website`** — fetch the raw text/HTML of a URL (bounded by `--tool-timeout`).
736
- - **`run_shell_command`** — run a shell command (only when `--enable-shell` is set). Every command is passed through the shell-safety classifier described above.
737
-
738
- ### Sub-agents
739
-
740
- Passing `--enable-subagents` lets the main agent **delegate a focused task to a sub-agent**, which is exposed to the model as an extra tool. A sub-agent is a self-contained, narrowed agent: it runs on its own in auto-mode (unattended), in its own isolated session folder, and hands a short text result (plus an optional `report.md`) back to the main agent. It reuses all the existing machinery -- tools, the shell-safety classifier, the `--allowed-dir` sandbox, history compaction and `--plan` mode -- and cannot recursively spawn further sub-agents.
737
+ ```txt
738
+ Write an agent.md file for me that helps an LLM write efficient triton kernels,
739
+ given a reference implementation.
740
+ ```
741
741
 
742
- Enable it and the available sub-agents appear in the help (`/help`):
742
+ > [!NOTE]
743
+ > **Every flag** is listed once, in [Command-line options](#command-line-options) — or run
744
+ > `mini-code --help`. Modes and their caveats are described in [Modes & safety](#modes--safety).
745
+
746
+ ## Command-line options
747
+
748
+ | Option | Default | What it does |
749
+ | --- | --- | --- |
750
+ | `--url URL` | `http://0.0.0.0:30000` | API host |
751
+ | `--model MODEL` | — | model name |
752
+ | `--api-key KEY` | `$MINI_CODE_API_KEY` | API key for authentication |
753
+ | `--max-tokens N` | — | reply budget; also the output headroom used when deriving the compaction limit |
754
+ | `--temperature T` | `1.0` | sampling temperature |
755
+ | `--system-prompt TEXT` | built-in | replace the system prompt (an `--agent-md` file is appended *after* it) |
756
+ | `--prompt TEXT` | — | initial user prompt |
757
+ | `-a`, `--auto-mode` | off | keep querying the model and running tools until no tool calls remain |
758
+ | `--agent-md FILE` | — | append an `agent.md` file after the system prompt (e.g. `./skill.md`) |
759
+ | `--ask-permission` | off | ask before every tool call (ALLOW-tier shell commands still skip the prompt) |
760
+ | `--sudo` | off | **dangerous:** never ask. DENY-tier commands are still refused |
761
+ | `--allowed-dir DIR` | `./` | sandbox for **file** tools (does not restrict the shell) |
762
+ | `-s`, `--enable-shell` | off | allow shell execution (classifier always applies) |
763
+ | `-g`, `--enable-subagents` | off | expose sub-agents as tools |
764
+ | `--skills` | off | enable the `.mini` skills directory (`skill.md`s, `SKILLS.md`, runnable scripts) |
765
+ | `-p`, `--plan` | off | plan mode (`CURRENT_GOAL.md` / `CURRENT_PLAN.md`, `/plan`) |
766
+ | `--llm-timeout S` | `500` | HTTP timeout for LLM requests |
767
+ | `--tool-timeout S` | `120` | timeout for a single tool call |
768
+ | `--max-context-tokens N` | derived | input-token budget before the history is compacted |
769
+ | `--cache-dir DIR` | `~/.cache/mini/sessions/` | where session histories are stored |
770
+ | `--restore-session PATH` | — | continue a specific previous session |
771
+ | `-l`, `--load-last-session` | off | continue the session recorded in the `.mini` pointer |
772
+ | `--all` | off | `--plan --enable-subagents --enable-shell --auto-mode --sudo` |
773
+ | `--all-last` | off | `--all` + `--load-last-session` |
774
+ | `--verbose` | off | print full detail (default: user/assistant turns, token usage, tool calls only) |
775
+ | `-h`, `--help` | — | show the built-in help |
776
+
777
+ ## Available tools
778
+
779
+ The agent can call a small set of tools, all defined in `mini_code_cli/tools.py`. Every
780
+ parameter a model does not need is defaulted, so omitting it keeps the previous behaviour.
781
+
782
+ | Tool | What it does |
783
+ | --- | --- |
784
+ | `read_file` | read a file; `offset` (1-based line) and `limit` page through large files |
785
+ | `write_file` | write/overwrite; `append` adds to the end, `create_dirs` creates parents |
786
+ | `edit` | replace an **exact** string (`old_string` → `new_string`); refuses a missing or ambiguous match unless `replace_all` |
787
+ | `grep` | regex search a file or directory; `recursive`, `include`, `ignore_case`, `line_numbers`, `max_results` (noise dirs skipped) |
788
+ | `glob` | list files matching a glob (one per line, `**` supported), optionally against a `root` |
789
+ | `web_search` | best-effort lookup: related queries + a short Wikipedia extract. Never raises |
790
+ | `read_website` | fetch raw text/HTML of a URL (bounded by `--tool-timeout`), `max_chars` caps size |
791
+ | `run_shell_command` | run a shell command (needs `--enable-shell`); `cwd`, `timeout`, and stdout/stderr/exit code are all reported |
792
+
793
+ ## Sub-agents
794
+
795
+ `--enable-subagents` lets the main agent **delegate a focused task** to a sub-agent, exposed to
796
+ the model as an extra tool. A sub-agent is a self-contained, narrowed agent: it runs unattended
797
+ in auto-mode, in its own isolated session folder, and hands back a short text result (plus an
798
+ optional `report.md`). It reuses all the existing machinery — tools, the shell-safety
799
+ classifier, the `--allowed-dir` sandbox, compaction and `--plan` — and cannot spawn further
800
+ sub-agents.
743
801
 
744
802
  ```bash
745
- mini-code --enable-subagents
803
+ mini-code --enable-subagents # the available sub-agents then show up in /help
746
804
  ```
747
805
 
748
- Two worked examples ship out of the box:
749
-
750
- - **`research`** -- read-only web research. Given a topic it searches the web, reads a few sources and returns a concise, sourced summary. It can only use `web_search` / `read_website` -- never the filesystem or shell -- so it is safe even without a sandbox. Accepts an optional `sources` hint (e.g. `"wikipedia.org only"`).
751
- - **`planner`** -- drafts/refines a clear step-by-step plan for a goal and returns it. Always runs in plan mode.
806
+ | Sub-agent | What it is for |
807
+ | --- | --- |
808
+ | `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"`) |
809
+ | `planner` | drafts or refines a step-by-step plan for a goal; always runs in plan mode |
810
+ | `software_engineer` | writes, edits, refactors, fixes and tests code; can run shell commands (tests, builds) to verify |
811
+ | `generic` | general-purpose helper for anything that fits no narrower agent |
752
812
 
753
- The `tools`, `enable_shell` and `max_steps` knobs are always intersected with the parent's own permissions, so a sub-agent can never do anything the main agent could not. Sub-agents also compose with `--plan` mode: each sub-agent keeps its own `CURRENT_PLAN.md` / `CURRENT_GOAL.md` in its own session folder.
813
+ > [!NOTE]
814
+ > A sub-agent's `tools`, `enable_shell` and `max_steps` are always **intersected with the
815
+ > parent's** permissions, so it can never do anything the main agent could not. Sub-agents
816
+ > compose with `--plan`: each keeps its own `CURRENT_PLAN.md` / `CURRENT_GOAL.md`.
754
817
 
755
- #### Adding your own sub-agent
818
+ <details>
819
+ <summary><b>Adding your own sub-agent</b></summary>
756
820
 
757
- A sub-agent is just a small class. Subclass `SubAgent` and register it:
821
+ A sub-agent is just a small class — subclass `SubAgent` and register it:
758
822
 
759
823
  ```python
760
824
  # my_subagents.py
@@ -770,97 +834,109 @@ class SummarizeSubAgent(SubAgent):
770
834
  register(SummarizeSubAgent())
771
835
  ```
772
836
 
773
- Then make sure it is imported (e.g. add `import my_subagents`), and it will be discovered and exposed to the model automatically when `--enable-subagents` is set. See `mini_code_cli/subagents/builtin.py` for the full list of knobs and `ARCHITECTURE.md` (sections 2-3) for the design and every available option.
837
+ Make sure the module is imported (e.g. `import my_subagents`) and it is discovered and exposed
838
+ to the model automatically when `--enable-subagents` is set. See
839
+ `mini_code_cli/subagents/builtin.py` for every knob and `ARCHITECTURE.md` (sections 2–3) for the
840
+ design.
774
841
 
775
- 3. Try a prompt:
776
- ```txt
777
- Write an agent.md file for me that helps an LLM write efficient triton kernels, given a reference implementation.
778
- ```
842
+ </details>
779
843
 
780
- 4. Get help:
781
- ```bash
782
- mini-code --help
783
- ```
784
- ```
785
- Agent loop for interacting with a language model
786
-
787
- options:
788
- -h, --help show this help message and exit
789
- --url URL API host, default=http://0.0.0.0:30000
790
- --max-tokens MAX_TOKENS
791
- Maximum tokens for LLM response, default=None
792
- --temperature TEMPERATURE
793
- Temperature for LLM, default=1.0
794
- --model MODEL Model name, default=None
795
- --api-key API_KEY API key for authentication. If not set, it tries to find it in env variable: MINI_CODE_API_KEY.
796
- --cache-dir CACHE_DIR
797
- The cache dir for the session histories. default=~/.cache/mini_code/sessions/
798
- --restore-session RESTORE_SESSION
799
- The location of a previous session to continue. (e.g. ~/.cache/mini_code/sessions/1792028090823027-a9d77653/)
800
- --load-last-session Load the most recent previous session from the cache dir and continue it (under a new session id), instead of starting fresh. --restore-session takes precedence if also given.
801
- --system-prompt SYSTEM_PROMPT
802
- Replace system prompt, with a custom system prompt.
803
- -a, --auto-mode Whether to run the agent in `auto-mode'. Or default: `manual-mode'.
804
- --agent-md AGENT_MD If the agent should use an agent-md file... (it will added after system message.)
805
- --prompt PROMPT An initial prompt from the user...
806
- --ask-permission Ask for permission before any tool call. (Shell ALLOW-tier commands skip the prompt; DENY is blocked.)
807
- --sudo DANGEROUS: never ask for permission. Every non-destructive tool call and shell command runs automatically without confirmation. Destructive (DENY-tier) commands are still refused.
808
- --allowed-dir ALLOWED_DIR
809
- Allowed directory for file operations, default='./'
810
- -s, --enable-shell Allow shell execution. default= False
811
- --enable-subagents Allow the agent to delegate work to sub-agents (exposed as extra tools). default= False
812
- --llm-timeout LLM_TIMEOUT
813
- HTTP timeout in seconds for LLM requests (reasoning models can be slow). default=500
814
- --tool-timeout TOOL_TIMEOUT
815
- Timeout in seconds for a single tool call. default=120
816
- --plan Enable plan mode: the agent keeps a CURRENT_PLAN.md
817
- (its step-by-step plan, marked finished when the goal
818
- is done) and CURRENT_GOAL.md (the user's latest
819
- instruction) in the session directory. Also changes
820
- how history compaction works.
821
- --verbose Print the full, detailed output. Without it (default),
822
- only user/assistant turns, token usage and tool calls
823
- are shown.
824
- ```
825
-
826
- ### In-session commands
844
+ ## In-session commands
827
845
 
828
- ```
829
- /history list the conversation (turn number, what happened, where)
830
- /history <n> show the full messages recorded for turn n
831
- /reset [<n>] rewind to the end of turn n (drops everything after it)
832
- /clear clear the screen (keeps the conversation history)
833
- /help show this help
834
- /quit, /exit save the session and exit
835
- ```
846
+ | Command | What it does |
847
+ | --- | --- |
848
+ | `/history` | list the conversation (turn number, what happened, where) |
849
+ | `/history <n>` | show the full messages recorded for turn `n` |
850
+ | `/reset [<n>]` | rewind to the end of turn `n` (drops everything after it) |
851
+ | `/clear` | clear the screen (keeps the conversation history) |
852
+ | `/plan` | show the current goal + plan (plan mode only) |
853
+ | `/help` | show this help |
854
+ | `/quit`, `/exit` | save the session and exit |
836
855
 
837
- ## Testing
856
+ ## Development
838
857
 
839
- The project ships with a small standard-library test suite (no extra dependencies to install):
858
+ Linting, the test suite, CI and the release process are documented in
859
+ [**README_DEV.md**](README_DEV.md).
840
860
 
841
861
  ```bash
842
- # Run the whole suite from the repo root:
843
- python3 -m unittest discover -s tests -p "test_*.py"
844
-
845
- # ...or run a single test file:
846
- python3 tests/test_tools.py
847
- python3 tests/test_sandboxing.py
848
- python3 tests/test_agent_loop.py
849
- python3 tests/test_shell_safety.py
862
+ python3 scripts/lint.py # lint (standard library only)
863
+ python3 -m unittest discover -s tests -p "test_*.py" # run the test suite
850
864
  ```
851
865
 
852
- The tests focus on the parts of the agent that are easy to get wrong and worth guarding:
866
+ Releases are cut by tagging `main`: pushing a `v*` tag triggers
867
+ [`.github/workflows/release.yml`](.github/workflows/release.yml), which builds the sdist + wheel,
868
+ verifies them with `twine check`, and attaches them to a new GitHub release.
869
+
870
+
871
+
872
+ ## Modes & safety
873
+
874
+ ### Shell execution — `-s` / `--enable-shell`
875
+
876
+ Everything the agent runs from the shell first passes a **safety classifier** that sorts the
877
+ command into one of three tiers:
878
+
879
+ | Tier | Examples | What happens |
880
+ | --- | --- | --- |
881
+ | **DENY** | `rm -rf /`, `dd of=/dev/...`, `mkfs.*`, fork bombs | refused outright, never run |
882
+ | **ASK** | `rm file`, `sudo ...`, `chmod`, `curl ... \| sh` | requires your confirmation |
883
+ | **ALLOW** | `ls`, `cat`, `git status` | runs without prompting |
884
+
885
+ > [!WARNING]
886
+ > The classifier is **always enforced** — even in auto-mode and with `--sudo` — so the agent
887
+ > cannot run destructive commands unattended. It is a heuristic, not a sandbox: use it with care.
888
+ > `--allowed-dir` sandboxes **file tools**, not the shell.
889
+
890
+ ### Plan mode — `-p` / `--plan`
891
+
892
+ The loop keeps two human-readable tracking files in the session directory: `CURRENT_GOAL.md`
893
+ (your latest instruction) and `CURRENT_PLAN.md` (a step-by-step plan for that goal, marked
894
+ finished when it is done). They are authored by the *loop*, not the agent, live outside
895
+ `--allowed-dir`, and can be inspected any time with `/plan`.
853
896
 
854
- - **`test_sandboxing.py`** — the `--allowed-dir` sandbox. Verifies that child paths are allowed, while `..` traversal and sibling paths outside the allowed directory are rejected.
855
- - **`test_tools.py`** — the tool functions. Confirms they *return* their results/errors (instead of printing), that `run_shell_command` captures stderr and honors a timeout, and that the generated tool schema exposes the expected parameters.
856
- - **`test_agent_loop.py`** — agent-loop behaviour. Confirms that enabling the shell forces per-command permission prompts, that memory compaction is correctly wired (accepts token accounting), and that token-usage formatting handles servers that report no usage.
857
- - **`test_shell_safety.py`** — the shell command classifier. Confirms commands are sorted into the three tiers correctly: destructive commands (`rm -rf /`, `dd of=/dev/...`, `mkfs.*`, fork bombs) are **DENY**, risky ones (`rm file`, `sudo`, `curl | sh`, redirects to `/etc/...`) are **ASK**, and safe ones (`ls`, `cat`, `git status`) are **ALLOW**.
897
+ > [!NOTE]
898
+ > Plan mode also changes **history compaction**: after the transcript is compacted to a summary,
899
+ > `CURRENT_PLAN.md` and `CURRENT_GOAL.md` are re-injected, so the agent keeps working against the
900
+ > same goal. When the work looks done the plan is reviewed and any outstanding task is re-queued
901
+ > before the agent returns to you.
858
902
 
859
- This keeps the tool honest as it grows, and makes it safe to experiment with riskier features (like `--enable-shell`) without regressions.
903
+ ### Sessions — resume, or start fresh
860
904
 
861
- ## Other useful commands:
905
+ Every session is saved under `--cache-dir` (default `~/.cache/mini/sessions/`).
906
+
907
+ > [!TIP]
908
+ > If a previous session exists but you did **not** ask to resume one (neither
909
+ > `--load-last-session` nor `--restore-session`), the prompt offers **Resume / Start new / Exit**
910
+ > before the conversation begins. Ctrl-C or EOF there is a graceful exit. This is the *asking*
911
+ > variant; `--load-last-session` is the *silent* one.
912
+
913
+
914
+ | Flag | Behaviour |
915
+ | --- | --- |
916
+ | `--restore-session PATH` | continue that exact session |
917
+ | `-l`, `--load-last-session` | continue the session recorded in the `.mini/last_session.json` pointer, without asking |
918
+
919
+ `--load-last-session` resumes under a **brand-new session id**, so the original is never
920
+ overwritten; an explicit `--restore-session` wins if both are given. The "most recent" session
921
+ comes from a single source — the tiny `.mini/last_session.json` pointer written at the end of
922
+ every interactive session inside `--allowed-dir` (deliberately no timestamp fallback: with no
923
+ pointer, a fresh session starts). That pointer lives in the same `.mini` directory as `--skills`,
924
+ but as its own dedicated file, so the two never clash.
925
+
926
+ ### Context compaction — `--max-context-tokens`
927
+
928
+ Compaction is decided by **tokens only**, never by message count: a few large tool outputs can
929
+ fill a window that hundreds of short turns would not. The next request is projected from the
930
+ server-reported `prompt_tokens`, plus an estimate of what was appended since, plus the output
931
+ reserve (`--max-tokens`). Unset (default) it is derived from the model's context window minus the
932
+ output reserve and a safety margin. Lower it to compact sooner, raise it to compact later — there
933
+ is no message-count cap to configure.
934
+
935
+
936
+ ## Serving a model locally
937
+
938
+ Tested with vLLM v0.30 (tool calling enabled):
862
939
 
863
- ### Serving a vllm model locally (with correct tools). vllm v0.30 (tested):
864
940
  ```bash
865
941
  vllm serve ornith-ai/Ornith-1.5-397B-FP8 \
866
942
  --tensor-parallel-size 4 \
@@ -874,17 +950,19 @@ vllm serve ornith-ai/Ornith-1.5-397B-FP8 \
874
950
 
875
951
  ## Citation
876
952
 
877
- If you use `mini-code-cli` in your research or writing, please cite it using the BibTeX entry below:
953
+ If you use `mini-code-cli` in your research or writing, please cite it:
878
954
 
879
955
  ```bibtex
880
956
  @misc{mini-code-cli,
881
957
  author = {Rozanov, Nikolai},
882
958
  title = {mini-code-cli: A minimal, dependency-light coding agent},
883
959
  year = {2026},
884
- version = {0.1.0.0},
960
+ version = {0.1.1.0},
885
961
  howpublished = {\url{https://github.com/ai-nikolai/mini-code-cli}},
886
962
  note = {A no-bloat, dependency-free agent CLI for experimenting.}
887
963
  }
888
964
  ```
889
965
 
890
- ## (C) Nikolai Rozanov, 2026 - Present
966
+ ## License
967
+
968
+ [AGPL-3.0](LICENSE) — (C) Nikolai Rozanov, 2026 – present.