mini-agent is a local-first AI CLI agent written in Go. It resolves Ollama
first, can fall back to supported remote providers, and provides an
interactive REPL (chat), single-shot execution (run), tool management
(tool), goal-driven autonomous execution (/goal inside chat), and
session persistence (session) via SQLite.
| Package | Purpose |
|---|---|
github.com/spf13/cobra |
CLI framework |
github.com/spf13/viper |
Configuration management |
github.com/joho/godotenv |
.env file loading |
gorm.io/gorm + gorm.io/driver/sqlite |
ORM and SQLite driver |
github.com/google/uuid |
UUID generation for sessions |
github.com/fatih/color |
Terminal colors |
- English Only: All output strings, comments, docs, and variable names must be in English. No exceptions.
- Go 1.25.4: Locked. Do not modify
go.modGo version. - Windows-First: Development happens on Windows. Do not assume Unix-only
behavior. Use
filepath,os.PathSeparator, and cross-platform exec. Prefer PowerShell command execution on Windows. - Lint-Free:
go vet,golangci-lint, andstaticcheckmust pass. No unused variables or imports. - Test-Driven: Every new package or exported function gets unit tests. Mock HTTP and filesystem boundaries.
- Git Hooks:
pre-commit:go fmt,go vet,golangci-lint runpre-push:go test ./... -race
- Release Process:
- Every published version must update
CHANGELOG.md - Every published version must use a tag like
v0.0.1 .github/workflows/release.ymlpublishes release artifacts only for new matching tags
- Every published version must update
User Input -> cmd/ -> agent/ -> mcp/ -> llm/ -> ollama or remote provider
|
v
tools/ (registry + exec)
|
v
storage/ -> db/ -> SQLite
- LLM Factory: Resolves Ollama-first or OpenAI-compatible remote providers (OpenAI, OpenRouter, Groq, DeepSeek) from flags, env, and saved profiles.
- Provider Profiles: Persist endpoint, model, encrypted API key, timeout, temperature, extra headers, and raw request options per remote profile.
- Ollama Client: Plain HTTP client. POST
/api/chatwith JSON and honorcontext.Contextcancellation. - Secrets Manager: Encrypts saved remote provider API keys with a local
AES-GCM master key stored under
~/.mini-agent/master.key. - MCP Server: Receives messages, attaches
tools, calls Ollama. If the response containstool_calls, executes them viatools.Registry, appends results astoolrole messages, and re-calls Ollama. It also accepts plain JSON tool-call fallbacks, caps tool calls per iteration, and stops after repeated tool or validation failures. - Tools:
run_shell,read_file,write_file,list_dir,search_files,glob_files,git_status,git_diff,run_validation,apply_patch. Each implements theToolinterface. - Sandbox Policy: Optional workspace sandboxing can constrain file tools to a configured root and reduce shell execution to allowed read or validation commands.
- Agent: Manages the REPL loop. Persists every message to SQLite via
storage.SessionStore. - Goal Manager: Creates persistent goal runs, tracks work items, and coordinates iterative execution until completion or manual stop, including heuristic context selection, bounded repair attempts after failed validation, persisted context visibility in session output, throttled stop polling, and reduced redundant progress writes during execution.
- Repo Context Selector: Ranks likely-relevant files from the goal text, recent messages, session summary, and git changes before goal execution.
- Planner: Builds a lightweight execution plan before entering goal mode, including risk level and suggested starting context for normal and repair prompts.
- Memory: Stores a compact session summary after goal execution.
- SessionStore: GORM-backed CRUD for
Session,Message,GoalRun, andWorkItem, plus provider profile persistence.
- Create a new file in
internal/tools/(e.g.,git.go). - Implement the
Toolinterface:Name(),Description(),Parameters(),Execute(ctx, args). - Register it in
tools.NewRegistry(). - Add unit tests in
internal/tools/(mock filesystem or exec). - Run
go test ./...and lint.
- Create
cmd/<command>.go. - Use
cobra.CommandwithRunorRunE. - Add
init()to register withrootCmd. - Bind persistent flags in
cmd/root.goif needed. - Keep business logic in
internal/;cmd/is thin.
- Update
internal/models/session.go. - GORM AutoMigrate handles additions, but back up data if renaming columns.
- Update
internal/storage/session.goif queries change. - Add migration tests if logic is complex.
- Modify
internal/ollama/client.go. - Ensure
ToolDefis the single source of truth (defined only here). internal/tools/registry.goimportsmini-agent/internal/ollamaand returns[]ollama.ToolDef.- Update
mcp/server.goonly if the tool-call loop logic changes.
- Update
internal/llm/for provider resolution and remote client behavior. - Keep Ollama as the default path unless the user selects another provider.
- Store saved provider API keys only through
internal/secrets/. - Keep runtime files under
~/.mini-agent. - Keep provider profile schema, CLI flags, and remote request settings aligned.
- If sandbox is enabled, keep tool policy, CLI wiring, and prompt wording aligned.
- Duplicate
ToolDef: Never redefineToolDefintools/. Import fromollamapackage. - Missing Context: Always pass
ctx context.Contextdown the stack. Respect cancellation and timeouts. - English Leak: Do not write Spanish or other languages in error strings or UI output. Use English only.
- Windows Paths:
path.Joinis for URLs;filepath.Joinis for files. - Uncommitted Tests: If you change logic, you must update or add tests.
- Race Conditions: The agent is currently single-threaded (REPL), but
go test -raceshould still pass. - Goal Loops: Goal mode must always respect stop signals and iteration limits, tool-call limits, and consecutive-failure limits.
- Sandbox Drift: Do not update shell or filesystem tools without checking whether sandbox policy enforcement must also change.
- Secrets: Never log or print decrypted API keys.
- Provider Output:
provider showand related UX must redact secrets. - Patch Safety: Prefer
apply_patchfor existing files to reduce accidental full-file rewrites.
- Unit tests: Test each tool in isolation with mocked
exec.Commandorafero(if we add virtual FS). - Integration tests: Use a temporary SQLite DB (
:memory:or temp file) for storage tests. - HTTP tests: Use
httptest.Serverto mock Ollama responses inollama/client_test.go. - Agent tests: Mock the MCP server and storage to test the REPL loop without real HTTP or DB calls.
mini-agent/
├── .env
├── .github/
│ └── workflows/
│ ├── pages.yml
│ └── release.yml
├── CHANGELOG.md
├── go.mod
├── go.sum
├── lefthook.yml
├── main.go
├── cmd/
│ ├── root.go
│ ├── chat.go
│ ├── run.go
│ ├── tool.go
│ └── session.go
├── internal/
│ ├── config/
│ │ └── config.go
│ ├── db/
│ │ └── db.go
│ ├── llm/
│ │ ├── client.go
│ │ ├── client_test.go
│ │ ├── openai_compatible.go
│ │ └── openai_compatible_test.go
│ ├── goal/
│ │ ├── manager.go
│ │ ├── manager_test.go
│ │ └── types.go
│ ├── context/
│ │ ├── context.go
│ │ ├── context_test.go
│ │ └── ranker.go
│ ├── memory/
│ │ ├── summary.go
│ │ └── summary_test.go
│ ├── models/
│ │ └── session.go
│ ├── secrets/
│ │ ├── manager.go
│ │ └── manager_test.go
│ ├── storage/
│ │ ├── session.go
│ │ └── session_test.go
│ ├── ollama/
│ │ ├── client.go
│ │ └── client_test.go
│ ├── tools/
│ │ ├── registry.go
│ │ ├── shell.go
│ │ ├── shell_test.go
│ │ ├── files.go
│ │ ├── files_test.go
│ │ ├── git.go
│ │ ├── git_test.go
│ │ ├── glob.go
│ │ ├── glob_test.go
│ │ ├── patch.go
│ │ ├── patch_test.go
│ │ ├── validate.go
│ │ └── validate_test.go
│ ├── mcp/
│ │ ├── server.go
│ │ └── server_test.go
│ ├── agent/
│ │ └── agent.go
│ ├── planner/
│ │ ├── planner.go
│ │ ├── planner_test.go
│ │ └── prompt.go
│ └── ui/
│ └── ui.go
When asked to generate code:
- Generate complete file contents, not diffs, unless explicitly asked for a patch.
- Include package declaration and all imports.
- Run
goimports-style logic mentally: remove unused imports, group standard library vs third-party. - Follow the Windows-first and English-only rules strictly.
- If a change requires a new dependency, warn the user and justify it.
- If a change breaks existing tests, update the tests in the same response.
- If a change touches goal execution, keep
/goal,/stop, iteration limits, and validation behavior consistent with the docs. - Prefer patch-based edits for existing files and document any repair-loop behavior changes.
- If a change affects release distribution, update
CHANGELOG.md,.github/workflows/release.yml, and the relevant release documentation. - Before any published version, prepare a changelog entry and create a version
tag such as
v0.0.1.