A standalone terminal AI agent in a single C file. Quiet, model-agnostic, skill-driven.
site · releases · changelog · hako (models) · hako-edit · org
![]() local hako model by default, via mithraeum |
![]() :models · local hako + 13 cloud providers
|
![]() arrow-key :theme picker · live swatches
|
| 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 ——
- Local models run on the native engine — no ollama, no server. Plain
makeis all the agent needs; it runs Qwen-class models by spawning the hako engine as a one-shothakmsubprocess per turn (hakm <model.mlf2> --chat-stdin) over mmap'd MLF2 weights. No in-process link, no compile flag, no daemon, no socket. Install the engine CLI once withmake hakm(→~/.hako/bin/hakm). Drop a.mlf2in~/.hako/models/andhakoauto-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<tool name="...">{...}</tool>calls parse on small models. Convert a GGUF with the engine'stools/gguf2mlf.py, or:pull <tier>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 <name>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 (↑ ↓),
^Rreverse-search, Home/End, kill-word, kill-line, bracketed paste. Multi-row aware redraw, no flicker. - Theme presets + arrow-key picker.
:theme <name>swaps the palette directly; bare:themeopens a popup you arrow through, each row showing that theme's colors as live swatches. Same picker on bare:provider. Persisted in~/.hakorc. Truecolor where supported, 16-color fallback for the error chip in tmux withoutRGBpassthrough. - HAKO.md project context. Per-project
<cwd>/.hako/HAKO.mdis 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,edit_file(str_replace),edit_lines(line range),run_shell(10s timeout),read_skill. Per-call[y]/[n]/[a]approval; untrusted dir = all tools refused.:trustonce per project. - Persistent sessions + skills. Per-cwd session id, 7-day resume, append-only JSONL history. Skills are markdown — flat or directory dispatchers (corp-style) — pulled on demand via the
read_skilltool. Notes you keep on disk for the agent to find. - Self-update.
hako --updatepulls 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 ——
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 buildDeps: libc + pthread +
curl(1)on PATH. No third-party libraries linked.
curl -fsSL https://mithraeums.github.io/install.sh | shDetects 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 |
Local, zero config (recommended) — build with the engine, drop in a weight, launch:
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 directoryOr wire a cloud provider:
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-flashOr one-shot:
hako -p "summarize README.md"Self-update:
hako --update # check + atomic-replace if newer—— III ——
| 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.
: is the primary prefix (vim / hako style). / works as a legacy alias.
:help :clear :retry :edit :undo :usage :q
:providers :models :provider <name> :model <id>
:login [<prov>] :logout [<prov>] :accounts
:history [local|global]
:skills [reload] :skill install <url> :skill uninstall <name>
:tools on|off :toolgate on|off :toolmode native|react :trust [revoke]
:sessions :resume <id> :session [new]
TAB completes commands and provider names after :login / :provider / :logout.
—— IV ——
~/.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/<encoded-cwd>/state per-project session id, turn count
~/.hako/projects/<encoded-cwd>/trust sentinel: tools allowed in this cwd
~/.hako/projects/<encoded-cwd>/sessions/ append-only JSONL session history
~/.hakorc user config
<cwd>/.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: ensureollama serveis 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 [<provider>] 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 → <PROVIDER>_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.
| Provider | id (:provider <id>) |
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.
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:
:toolmode react # model emits <tool name="X">{...}</tool> blocks in prose
:toolmode native # back to native function-calling (default)ReAct mode injects a tool schema in the system prompt and parses <tool>...</tool> blocks from the model's response. Each tool call is executed and the result is appended as <observation tool="X">...</observation> for the next turn. Works with any instruct-tuned model.
—— V ——
~/.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 <files> manifest. The agent reads inner files on demand via read_skill(skill, path) — no trust gate (skills are user-installed), path-traversal blocked.
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.
—— VI ——
edit_file+edit_lines— change part of a file without rewriting it; indentation-tolerant match + an over-run guard so a small model can't clobber its own edit.- Local-model tool reliability — greedy tool turns, cross-turn dedup, raw
<write_file>channel, write/edit nudges, and brevity + anti-refusal prompt rules so small models actually use their tools. - Arrow-key popup picker — bare
:theme(live color swatches) and:provider; numbered fallback when piped. - 256-color fallback — detects truecolor and maps the brand palette to 256 itself on terminals without it (e.g. macOS Terminal.app), so colors stay on-brand.
- Per-call tool permission —
[y]/[n]/[a]at the single exec chokepoint, every provider;:auto/--yoloto bypass. - MCP client — stdio JSON-RPC (
~/.hako/mcp.json,mcp__server__tool); local models see and fuzzy-resolve MCP tools. - Context + display —
HAKO_CTXdefault 8192; honest write chips; CommonMark underscores; spinner tracks the active theme.
See CHANGELOG.md for the full history (v0.1.4 → present).
—— VII ——
- Termios line editor
-
--update - directory skills +
read_skill - universal2, Linux arm64, FreeBSD x86_64
- 4 OAuth providers (Anthropic, Copilot, GH Models, OpenRouter)
- Anthropic OAuth tool calls (CC-fingerprint prose mode)
- local hako auto-default (
hako-sho3B /hako-koi7B) via the hakm subprocess - hako native engine wired as a
hakmsubprocess (--chat-stdin, one-shot per turn) — no ollama, no in-process link -
edit_file(str_replace) +edit_lines(line-range) tools - local-model tool reliability — greedy tool turns, cross-turn dedup, raw
<write_file>channel, write nudges + fence-autowrite,HAKO_CTX - MCP client (stdio JSON-RPC,
mcp__server__tool, local-model visibility + fuzzy resolve) - arrow-key popup picker (
:theme/:provider, live swatches) — reusable for:modelnext - 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 ——
If you share the belief that simplicity empowers creativity, feel free to contribute.
- Forking this repo
- Submitting a Pull Request
- Bug reports and feature requests
Please ensure your code follows the existing style.
This project started out of curiosity and as a branch of 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 —



