https://github.com/mithraeums/hako-code
A local first agent. Written in C. Works with most providers. Uses local Hako models or BYO AI.
https://github.com/mithraeums/hako-code
ai-agents anthropic chatgpt claude claude-code claw clawdbot codex hako hakoclaw llm mithraeum moltbot openclaw skills tui
Last synced: 14 days ago
JSON representation
A local first agent. Written in C. Works with most providers. Uses local Hako models or BYO AI.
- Host: GitHub
- URL: https://github.com/mithraeums/hako-code
- Owner: mithraeums
- License: gpl-3.0
- Created: 2026-05-07T02:44:54.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-29T07:19:52.000Z (22 days ago)
- Last Synced: 2026-05-29T08:29:52.476Z (22 days ago)
- Topics: ai-agents, anthropic, chatgpt, claude, claude-code, claw, clawdbot, codex, hako, hakoclaw, llm, mithraeum, moltbot, openclaw, skills, tui
- Language: C
- Homepage: https://mithraeums.github.io
- Size: 747 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
A standalone terminal AI agent in a single C file. Quiet, model-agnostic, skill-driven.
site · releases · changelog · hako (models) · hako-edit · org

auto-defaults to a local hako model via mithraeum

:models · local hako + 13 cloud providers

also runs embedded inside hake (the editor)

themes · mithraeum · claude · nord · mono
```
╭───────────────────────────────────────────╮
│ ⠀⠀⠀⠀⠀⠀⠀⢀⣀⡀⠀⠀⠀⠀⠀⠀⢀⣀⡀⠀⠀⠀⠀⠀⠀⠀ │
│ ⠀⠀⠀⢀⣠⣶⣾⣿⣿⣿⣦⡀⠀⠀⢀⣴⣿⣿⣿⣷⣶⣄⡀⠀⠀⠀ │
│ ⣠⣴⣾⣿⣿⣿⣿⣿⣿⠿⠛⠉⢠⡄⠉⠛⠿⣿⣿⣿⣿⣿⣿⣷⣦⣄ │
│ ⠀⠻⣿⣿⣿⡿⠟⠋⠁⠀⠀⠀⢸⡇⠀⠀⠀⠈⠙⠻⢿⣿⣿⣿⠟⠁ │
│ ⠀⠀⠈⠋⠁⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠈⠙⠁⠀⠀ │
│ ⠀⠀⣰⣷⣦⣄⡀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⢀⣠⣴⣾⣆⠀⠀ │
│ ⢠⣾⣿⣿⣿⣿⣿⣷⣦⣄⠀⠀⢸⡇⠀⠀⣠⣴⣾⣿⣿⣿⣿⣿⣷⡄ │
│ ⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠖⠀⠀⠲⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋ │
│ ⠀⠀⠀⠉⠛⠿⣿⣿⣿⠟⢁⣴⡇⢸⣦⡈⠻⣿⣿⣿⠿⠛⠉⠀⠀⠀ │
│ ⠀⠀⠀⢸⣷⣦⣄⡉⢁⣴⣿⣿⡇⢸⣿⣿⣦⡈⢉⣠⣴⣾⡇⠀⠀⠀ │
│ ⠀⠀⠀⠈⠙⠻⢿⣿⣿⣿⣿⣿⡇⢸⣿⣿⣿⣿⣿⡿⠟⠋⠁⠀⠀⠀ │
│ ⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⢿⣿⡇⢸⣿⡿⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀ │
│ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⠈⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ │
│ │
│ hako 0.1.8 · mithraeum · hako-sho │
│ trust on · session resumed │
│ :help :providers :models :login :theme │
╰───────────────────────────────────────────╯
```
Local first.
Auto-defaults to any installed hako model — hako-sho (3B) or hako-koi (7B), runs on your device, no key, no cloud. The agent detects it and just works.
Single binary.
One C file. Builds with gcc -lpthread. Curl on PATH for HTTP. Nothing else linked.
13 cloud providers when you want them.
Anthropic OAuth (Claude Pro/Max sub), GitHub Copilot, GH Models (free), OpenRouter, plus 9 more over OpenAI-compat. Set a key or run a one-line :login — your call.
—— I ——
## Overview
- **Local models run on the native engine — no ollama, no server.** Plain `make`
is all the agent needs; it runs Qwen-class models by spawning the
[hako engine](https://github.com/mithraeums/hako) as a one-shot `hakm`
subprocess per turn (`hakm --chat-stdin`) over mmap'd MLF2 weights.
No in-process link, no compile flag, no daemon, no socket. Install the engine
CLI once with `make hakm` (→ `~/.hako/bin/hakm`). Drop a `.mlf2` in
`~/.hako/models/` and `hako` auto-defaults to the **mithraeum** provider on
first launch — no key, no `:login`, no config (preference: koi > sho,
fine-tunes over stock-wraps). Force prose tool mode is on so
`{...}` calls parse on small models. Convert a GGUF
with the engine's `tools/gguf2mlf.py`, or `:pull ` it from HuggingFace.
(ollama is also supported as a *separate* optional provider — `:login ollama` —
for non-hako models.)
- **13 cloud providers when you want them.** Anthropic native (SSE + OAuth via Claude Pro/Max), OpenAI function-calling, GitHub Copilot, GitHub Models (free), OpenRouter (PKCE), and OpenAI-compat aliases for Gemini, Groq, Cerebras, DeepSeek, Mistral, Together, Fireworks, xAI/Grok, custom. `:login ` walks you through OAuth or hands you to the provider's console for an API key.
- **Terminal-class line editor.** Termios raw mode, cursor keys, history (↑ ↓), `^R` reverse-search, Home/End, kill-word, kill-line, bracketed paste. Multi-row aware redraw, no flicker.
- **Theme presets.** `:theme mithraeum|claude|nord|mono` swaps the full palette live (persisted in `~/.hakorc`). Truecolor where supported, 16-color fallback for error chip in tmux without `RGB` passthrough.
- **HAKO.md project context.** Per-project `/.hako/HAKO.md` is auto-loaded into the system prompt — the CLAUDE.md equivalent for hako-code. Binary-safe + size-capped (200KB).
- **Trust-gated tools.** `read_file`, `list_dir`, `write_file` (with staging), `run_shell` (10s timeout). Untrusted dir = all tools refused. `:trust` once per project.
- **Persistent sessions + skills.** Per-cwd session id, 7-day resume, append-only JSONL history. Skills are markdown — flat or directory dispatchers ([corp](https://github.com/mithraeums/skills/tree/main/corp)-style) — pulled on demand via the `read_skill` tool. Notes you keep on disk for the agent to find.
- **Self-update.** `hako --update` pulls the latest GitHub release, verifies sha256, atomically replaces the binary. No reinstall, no rebuild.
- **Streaming + spinners.** Anthropic SSE streams live tokens. 8 spinner styles × 12 thinking labels rotate per turn (`⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏`).
—— II ——
## Build & Run
### Build
```sh
gcc hako.c -o hako -lpthread # one-liner
make # cross-OS Makefile
make UNIVERSAL=1 # macOS arm64 + x86_64 fat binary
make asan # ASan + UBSan build
```
> Deps: libc + pthread + `curl(1)` on PATH. No third-party libraries linked.
### Install
```sh
curl -fsSL https://mithraeums.github.io/install.sh | sh
```
Detects OS and arch, downloads the latest signed release, verifies the sha256 sidecar, drops `hako` into `/usr/local/bin` (or `~/.local/bin`). No package manager. No daemon. No telemetry.
macOS
universal2 · arm64 + x86_64
Linux
x86_64 · arm64
FreeBSD
x86_64
Windows
x86_64 · MinGW
iSh
linux-x86_64 binary
### First turn
**Local, zero config (recommended)** — build with the engine, drop in a weight, launch:
```sh
make # plain build — the agent
make hakm # installs the engine CLI → ~/.hako/bin/hakm
# convert a Qwen2.5-Coder GGUF once → ~/.hako/models/hako-sho.mlf2
# (python3 ../hako/tools/gguf2mlf.py model.gguf ~/.hako/models/hako-sho.mlf2)
hako # auto-detects the .mlf2, runs it via the hakm subprocess (mithraeum)
> :trust # grant tool access in this project
> list files in this directory
> :trust # grant tool access in this project
> list files in this directory
```
**Or wire a cloud provider:**
```sh
hako
> :login anthropic # OAuth — uses your Claude Pro / Max subscription
> :login github-models # free for any GitHub account
> :login gemini # paste a free-tier API key
> :model gemini-2.5-flash
```
Or one-shot:
```sh
hako -p "summarize README.md"
```
Self-update:
```sh
hako --update # check + atomic-replace if newer
```
—— III ——
## Key Bindings & Commands
### Normal Mode
| Key | Action |
|---|---|
| ← → | move cursor |
| ↑ ↓ | history prev / next |
| Home / End · `^A` / `^E` | line start / end |
| `^U` / `^K` / `^W` | kill to start / end / word |
| `^R` | reverse-incremental history search |
| `^L` | clear screen |
| Backspace · Delete | delete back / forward at cursor |
| `^C` | cancel current line |
| `^D` (empty) | EOF / exit |
*Bracketed paste enabled in raw mode — multi-line pastes batch-insert.*
### Commands (inside prompt):
`:` is the primary prefix (vim / hako style). `/` works as a legacy alias.
```
:help :clear :retry :edit :undo :usage :q
:providers :models :provider :model
:login [] :logout [] :accounts
:history [local|global]
:skills [reload] :skill install :skill uninstall
:tools on|off :toolgate on|off :toolmode native|react :trust [revoke]
:sessions :resume :session [new]
```
**TAB** completes commands and provider names after `:login` / `:provider` / `:logout`.
—— IV ——
## Configuration
### Auth · Trust · State
```
~/.hako/state provider, model, settings (mode 0600, no secrets)
~/.hako/credentials per-provider api_key / oauth tokens (obfuscated, 0600)
~/.hako/skills/ markdown behaviors (flat or dir-dispatcher)
~/.hako/input_history line editor history (last 500)
~/.hako/projects//state per-project session id, turn count
~/.hako/projects//trust sentinel: tools allowed in this cwd
~/.hako/projects//sessions/ append-only JSONL session history
~/.hakorc user config
/.hako/HAKO.md per-project context (auto-loaded into system prompt)
```
**Three auth paths:**
- **OAuth (subscription / account-bound)** — `:login anthropic` (Claude Pro/Max), `:login copilot` (GitHub Copilot Pro/Business), `:login github-models` (free for any GitHub user), `:login openrouter` (PKCE, auto-issue an OR API key). Inference bills against your subscription where applicable; no per-token API key needed.
- **API-key paste** — `:login openai`, `:login gemini`, `:login groq`, `:login cerebras`, `:login deepseek`, `:login mistral`, `:login together`, `:login fireworks`, `:login xai`, `:login anthropic-api`, `:login openrouter-api`, `:login custom`. Opens provider console in your browser, prompts with input hidden, persists into the cred store.
- **Local** — `:login ollama` / `:login ollamacloud`. Local: ensure `ollama serve` is running. Cloud: paste an Ollama key.
Run `:providers` for the full grouped list with `◎` (active) and `*` (saved login) markers. `:models` lists installed local models on Ollama or curated suggestions per provider. `:accounts` lists saved logins; `:logout []` wipes one. Mid-chat `:provider X` swaps secrets and flattens wire-format-specific message bodies so the conversation survives.
Resolution order: `HAKO_API_KEY` env → `_API_KEY` env → `~/.hako/credentials` (per provider). Legacy `CLAW_*` / `HAKOC_*` env names are read as fallback with a one-shot deprecation warning.
First run in any directory asks for trust. Untrusted = no tool access at all.
### Connection Matrix
| Provider | id (`:provider `) | Auth | Cost | Wire format | Notes |
|--- |--- |--- |--- |--- |--- |
| Anthropic | `anthropic` · `claude` | OAuth | sub | native + SSE | Claude Pro/Max subscription; live-tested |
| Anthropic API | `anthropic-api` · `claude-api` | paste | $/tok | native + SSE | regular API key, separate from sub |
| GitHub Copilot | `copilot` · `github-copilot` | OAuth | sub | OpenAI-compat | Copilot Pro/Business; device flow |
| GitHub Models | `github-models` · `ghmodels` | OAuth | free | OpenAI-compat | rate-limited; any GH account |
| OpenRouter | `openrouter` | OAuth (PKCE) | $/tok | OpenAI-compat | auto-issues user-scoped key; `:free` tier |
| OpenRouter API | `openrouter-api` | paste | $/tok | OpenAI-compat | paste existing key |
| OpenAI | `openai` · `gpt` | paste | $/tok | function-calling | |
| Gemini | `gemini` · `google` | paste | free/$ | OpenAI-compat | generous free tier on AI Studio |
| Groq | `groq` | paste | free | OpenAI-compat | fastest hosting for Llama family |
| Cerebras | `cerebras` | paste | free | OpenAI-compat | ultra-fast inference |
| DeepSeek | `deepseek` | paste | $/tok | OpenAI-compat | DeepSeek-Chat / Reasoner |
| Mistral | `mistral` | paste | $/tok | OpenAI-compat | Mistral Large / Small / Codestral |
| Together | `together` | paste | $/tok | OpenAI-compat | aggregator |
| Fireworks | `fireworks` | paste | $/tok | OpenAI-compat | aggregator |
| xAI | `xai` · `grok` | paste | $/tok | OpenAI-compat | Grok API at api.x.ai |
| Ollama (local) | `ollama` · `local` | none | local | native | needs `ollama serve` running |
| Ollama Cloud | `ollamacloud` · `ocloud` | paste | $/tok | native | ollama.com hosted |
| custom | `custom` | paste | depends | OpenAI-compat | set `ai_endpoint` in `.hakorc` |
*Three wire formats (native Anthropic, native Ollama, OpenAI-compat). Quickest paths: (a) **Claude Pro/Max** → `:login anthropic`. (b) **Copilot Pro** → `:login copilot`. (c) **Free, no card** → `:login github-models`, `:login gemini`, `:login groq`, or `:login ollama`. (d) **Pay-as-you-go** → any paste row. ChatGPT Plus piggyback deferred — no public OAuth surface yet.*
### Tool modes
Some smaller / non-tool-tuned models (Mistral 7B, Phi-4, DeepSeek-R1 distills, smaller Gemma / Llama variants) don't reliably emit OpenAI/Anthropic function-calling JSON. Toggle ReAct mode:
```sh
:toolmode react # model emits {...} blocks in prose
:toolmode native # back to native function-calling (default)
```
ReAct mode injects a tool schema in the system prompt and parses `...` blocks from the model's response. Each tool call is executed and the result is appended as `...` for the next turn. Works with any instruct-tuned model.
—— V ——
## Skills
```
~/.hako/skills/
├── style.md flat skill — whole file injected
└── corp/ directory skill — SKILL.md is the dispatcher
├── SKILL.md
└── agents/
├── CEO.md
├── DEV.md
└── QA.md
```
Directory skills inject only `SKILL.md` plus a `` manifest. The agent reads inner files on demand via `read_skill(skill, path)` — no trust gate (skills are user-installed), path-traversal blocked.
```sh
git clone https://github.com/mithraeums/skills ~/.hako/skills/_tmp
cp -r ~/.hako/skills/_tmp/corp ~/.hako/skills/
rm -rf ~/.hako/skills/_tmp
hako # "loaded 1 skill(s)"
```
Browse the catalog: [mithraeums/skills](https://github.com/mithraeums/skills).
—— VI ——
## Change Log
### v0.1.8 (Latest)
- **Local models now run via the `hakm` SUBPROCESS — in-process engine link REVERSED.** `hkMithraeumChat` spawns `hakm --chat-stdin` one-shot per turn and reads the reply off stdout. No ollama, no server, no daemon. **Why the reversal:** v0.1.7's in-process link was gated behind `-DHAKO_HAVE_HAKM`, so a plain `make`/`make install` shipped an engine-less `hako` → MITHRAEUM fell through to the ollama curl path → "empty response" (recurred twice). Subprocess = plain `make` always ships the path, can't be compiled out. `make hakm` now builds+installs the standalone engine CLI to `~/.hako/bin/hakm`; the agent finds it via `hkFindHakm()` (`~/.hako/bin` → PATH).
- **Provision** — relocate misplaced weights into `~/.hako/models/`, `:pull ` from HuggingFace (`mithraeum` acct), prompt-then-pull on a `:model` switch to an uninstalled tier.
### v0.1.7
- **`mithraeum` provider ran the native hako engine IN-PROCESS.** Linked `libhakm.a` and called `hkMithraeumChat` → `hakm_chat` in this process; build was `make hakm` (`-DHAKO_HAVE_HAKM`). *(Reversed in v0.1.8 — the gated link kept shipping engine-less binaries.)*
- **Model resolution off the filesystem** — `~/.hako/models/.mlf2`. `clDetectKoiDefault` + `:models` scan `~/.hako/models/*.mlf2` (no more `ollama list` / `/api/tags`). koi > koi-mini > sho; `-v*` over `-stock`.
- **Graceful weight fallback** — missing configured weight → `hkMithraeumFirstAvailable` picks the first installed `.mlf2` (prefers sho), warns, self-heals per-project state. Fixes the stale `ai_model=hako-koi-*` "no such file" crash.
- **`AI_PROVIDER_OLLAMA` kept as a separate optional provider** — only the hako-models path is ollama-free.
- Engine: int8 dot path → ~2.25 tok/s on the 3B (Intel i3). See `mithraeums/hako`.
### v0.1.6
- **Anthropic OAuth tool calls work.** System-as-array, CC fingerprint headers, prose-mode tool calls (Claude Code XML parser), JSON-unescape on `write_file` content. Verified live against Claude Pro/Max.
- **Storage rewrite — CC-style.** Per-project state at `~/.hako/projects//{trust,state,sessions/.jsonl}`. `/.hako/` only holds `HAKO.md` (project context, system-prompt-loaded). Old per-project files trigger startup warn.
- **Theme system** — `:theme mithraeum|claude|nord|mono` swap + persist.
- **Visual overhaul** — sigils (`›` user, `◆` AI, `!` err, `·` sys), box banner, first-run wizard, ghost-text autocomplete for slash/colon cmds.
- **Tool resolution hardened** — 20+ tool-name aliases case-insensitive (`bash`, `create_file`, `str_replace_based_edit_tool`, etc), param-name aliases (`command`→cmd, `file_path`→path, `file_text`→content) so CC-trained Claude works first try.
- **`run_shell` rewrite** — tmp-script execution + JSON-unescape. Heredocs and embedded quotes now work.
- **OPENAI + OLLAMA wires now carry `system_prompt`** — was silently dropped; BASE_PROMPT / skills / HAKO.md now reach Copilot / GH Models / OpenRouter / Gemini / Ollama / koi.
- **Pre-tool prose suppression** — matches Claude Code chip-first ordering; no more "Done!" before the tool runs.
- **Cached env probe** in system prompt — model knows `python3` vs `python` etc on first try.
- **Ollama perf knobs** — `keep_alive: 30m` + `num_predict` cap. Big win on local koi turns.
- **Error chip** — bold 16-color bright red + `✗` glyph (was rendering as invisible reverse-video bar in tmux).
- **Banner box auto-sizes** correctly (was undercounting multibyte `·`). Rows truncate with `…`.
### v0.1.5
- **4 OAuth providers** — `:login anthropic` (Claude Pro/Max), `:login copilot` (Copilot Pro), `:login github-models` (free for any GH user), `:login openrouter` (PKCE auto-issue).
- **Discovery** — `:providers` grouped catalog, `:models` live (Ollama) or curated suggestions (other providers), TAB completion.
- **Workflow parity** — `:retry`, `:edit`, `:undo`, up-arrow recall.
- **ReAct tool fallback** — `:toolmode react` for smaller / non-tool-tuned models (Mistral 7B, Phi-4, DeepSeek-R1 distills).
- **Cost tracking** — per-provider USD/M-token price table, session `$` in status line, `:usage reset`.
- **Rendering** — tool category glyphs, fenced code blocks with bronze gutter, last-turn latency in status line.
- **Per-provider cred store** — `~/.hako/credentials` (XOR + base64, 0600). `:accounts`, `:logout`.
- **Mid-chat provider swap** — `:provider X` flattens wire-format-specific bodies so conversation survives Anthropic↔OpenAI↔Ollama jumps.
### v0.1.4
- **`--pipe` mode** for hako integration — JSONL I/O over stdin/stdout.
- **Mithraeum palette by default** — gold / paper / rust / dim chalk truecolor.
See [CHANGELOG.md](CHANGELOG.md) for full history.
—— VII ——
## Roadmap
- [x] Termios line editor
- [x] `--update`
- [x] directory skills + `read_skill`
- [x] universal2, Linux arm64, FreeBSD x86_64
- [x] 4 OAuth providers (Anthropic, Copilot, GH Models, OpenRouter)
- [x] Anthropic OAuth tool calls (CC-fingerprint prose mode)
- [x] local hako auto-default (`hako-sho` 3B / `hako-koi` 7B) via the hakm subprocess
- [x] [hako](https://github.com/mithraeums/hako) native engine wired as a **`hakm` subprocess** (`--chat-stdin`, one-shot per turn) — no ollama, no in-process link
- [ ] MCP client mode with Dynamic Client Registration
- [ ] Inline SHA-256 to drop openssl runtime dep
- [ ] Vim-style error codes + Buddy BLE companion approval gateway — v0.2
—— VIII ——
## Contributing
If you share the belief that simplicity empowers creativity, feel free to contribute.
### Contribution is welcome in the form of:
- Forking this repo
- Submitting a Pull Request
- Bug reports and feature requests
Please ensure your code follows the existing style.
### Thank you for your attention.
This project started out of curiosity and as a branch of [hako-edit](https://github.com/mithraeums/hako-edit), a C-based modal text editor. If you hit any issues, feel free to open an issue on GitHub.
Pull requests, suggestions, or even thoughtful discussions are welcome.
— SEE LICENSE — · GPL-3.0
— deus sol invictus mithras —