本地模型需先自行启动 llama-server 或 ollama serve,hax 不会代拉模型;从源码构建需先跑 scripts/install_deps.sh 装 libcurl、jansson、meson、ninja 等依赖;浏览器下载的 macOS 二进制可能被隔离,需 xattr -d com.apple.quarantine 清除。
hax
OleksandrChekhovskyiMIT活跃维护用 C 写的极简终端编码助手,直接在命令行里跑,支持 OpenAI、Anthropic、OpenRouter 和本地 llama.cpp 模型。
A minimalist, terminal-native coding agent written in C.
brew install oleksandrchekhovskyi/hax/haxREADME 未说明具体显存要求;本地模型需自行运行 llama-server 或 ollama serve,资源占用取决于所选模型。支持 Linux、macOS、FreeBSD、OpenBSD,Windows 需在 WSL 下使用。
用 C 写的极简终端编程 agent,单二进制、省内存,适合在终端里跑本地模型
用 C 写的极简终端编码助手,直接在命令行里跑,支持 OpenAI、Anthropic、OpenRouter 和本地 llama.cpp 模型。
核心能力
- 单个原生 C 二进制,依赖少,启动快,内存占用仅几 MB
- llama.cpp 本地模型开箱即用,自动发现模型与运行时能力
- 流式 Markdown 与工具输出按终端宽度重排,保留原生滚动缓冲
- Ctrl+T 查看发给模型的完整请求与回复,可开启协议级 trace
- 支持 OpenAI、Anthropic、OpenRouter、DeepSeek、Ollama 等多家 provider
容易踩的坑
- v0.6.1hax v0.6.1最新正式版2026-10-15 · 2026-10-15 15:24 UTC
Added
- Releases now include a prebuilt macOS binary for Apple Silicon. It needs only libraries that ship with macOS, so it runs without Homebrew.
Changed
- The prebuilt Linux binaries are a quarter of their former size, about 2 MB, by bundling a libcurl built with only what hax needs.
Fixed
- OpenAI and Codex models no longer have to fill in every optional tool parameter. GPT-6 models could hang or run unrequested commands, and had to set a bash timeout on every call, often far above the two-minute default after which long commands move to the background.
- The prebuilt Linux binaries connect over HTTPS on openSUSE and other distributions that keep
their CA bundle somewhere other than
/etc/ssl/certs/ca-certificates.crt, instead of failing every request with "Problem with the SSL CA cert".
- v0.6.0hax v0.6.02026-10-09 · 2026-10-09 18:07 UTC
查看更新说明
Added
- DeepSeek provider (
deepseek): setDEEPSEEK_API_KEY;/usageshows the account balance. See docs/providers.md for pricing and privacy caveats. - Shell-like Tab completion for
/commands and their arguments, including model ids and config keys and values. Press Tab again to list matches; a dim hint shows the next argument. /provider <id>,/model <id>, and/effort <level>switch directly without a picker./model <id>also works when the provider cannot list models;/provider <id>uses its default model, or leaves it unset until you choose one.- Preset shorthand:
hax reviewmeanshax --preset review; it also works with-p. - Built-in pickers support Ctrl-J/Ctrl-K to move the selection and Ctrl-W or Alt-Backspace to delete a query word, matching fzf.
reasoning_requiredprovider setting for Chat Completions proxies that require a reasoning field even when empty;autofollows the model catalog.
Changed
- One-shot runs are now unlimited by default, rather than stopping after 100 model round-trips.
max_turnsdefaults to0in both modes;autois no longer accepted. Set a positive number to keep a limit. - Custom providers must now set
catalog_idexplicitly (for example"catalog_id": "groq") to retain models.dev pricing and context metadata. Local servers and proxies without one never trigger a catalog download. See docs/providers.md. HAX_REASONING_ROUNDTRIPis renamedHAX_OPENAI_REASONING_ROUNDTRIPfor consistency with the otheropenai-compatibleenvironment variables; the old name is no longer read./sessiontotals survive resume and include undone user turns and retried requests. The report shows tokens per model, undone turns, and inherited fork context separately from the fork's own usage. Resume also restores the last user turn's stats line.- Session files are append-only:
/undorecords the cut instead of truncating the file. Scripts reading sessions should handle the new records described in docs/sessions.md. - Prompt history (Up, Ctrl-R) is now scoped to the working directory, beside its session files.
The old global
~/.local/state/hax/historyis no longer read; prompts from other projects no longer appear in recall. - Chat Completions providers replay reasoning by default in the field the server streamed,
preserving thinking models' earlier reasoning on custom and local servers, including Ollama.
reasoning_roundtripacceptsauto,off, or a field name;onnow meansauto, not alwaysreasoning_content. /modeland/effortbriefly wait for catalog refreshes to show pricing and context metadata on a cold cache. Model listings and catalog downloads now use compression.- The "enter to continue" hint appears inside the prompt after a pause or interruption; continuing no longer leaves an empty prompt row.
- Tool headers wrap long arguments instead of dropping them. Collapsed rows preserve suffixes
such as line ranges and identify
task_waittargets on resume. - Collapsed bash previews cover read-only git commands (
log,show,diff,status,blame) and tolerate separators such asecho ---between searches. - Model guidance favors native tools for ordinary file operations and reserves backgrounding for useful concurrent work rather than an immediate wait.
Fixed
- DeepSeek models on OpenCode Go and Zen no longer fail mid-task with missing
reasoning_content. Models whose catalog entry names a reasoning field now receive it even when empty. - Multi-line YAML skill descriptions, including
>and|block scalars, are read in full instead of being dropped or cut off. - Background task completion notes distinguish "output pending" from "nothing to collect";
task_waiton a collected task returns its final status instead ofno such task. - Quitting or switching conversations no longer adds
- DeepSeek provider (
- v0.5.0hax v0.5.02026-09-04 · 2026-09-04 19:40 UTC
查看更新说明
Added
hax --json(implies-p) streams new conversation records as JSONL, followed by aresultrecord with the outcome, final text, cost, and session id. Plain-poutput is unchanged, and the session-file schema is now a supported read surface. See docs/sessions.md.- A resumed one-shot run no longer requires a prompt:
hax --resume=ID -p(or--json) continues from where the conversation stopped. - Codex
/loginnow offers a local-browser OAuth flow for organizations that block device login; the device flow remains available for ssh sessions. See docs/providers.md. - Provider blocks accept
metadata_apito select the/modelsprotocol independently of the request protocol. All user-facing providers now also honor per-providersort_modelsandcatalog_idsettings. See docs/providers.md. extra_headerscan override or remove provider defaults and interpolate the stable{session_id}for gateways that route or cache by conversation. See docs/providers.md.
Changed
- Anthropic-protocol models on OpenCode Zen/Go and
anthropic-compatibleendpoints now use prompt caching and choose adaptive or budget thinking from model metadata, as first-party Anthropic now does.thinking_modeaddsauto(the default) andprefer-adaptive. - One-shot runs stop cleanly on signals: SIGINT or SIGTERM interrupts the run with status 130,
while SIGUSR1 pauses at the next turn boundary. Completed work remains resumable,
--jsonemits a final result when possible, and a second signal still kills immediately. See docs/usage.md. max_turnsnow bounds one-shot runs as well as interactive turns. Its default isauto: unlimited interactively and 100 in one-shot mode.- Token counts and their
k/mconfig suffixes now use decimal units; byte sizes remain 1024-based. For example,context_limit: "272k"means 272000 tokens. catalog.modelsoverrides now take precedence over live provider metadata and may be scoped by runtime provider id. This allows codex context overrides without changing OpenAI metadata; the model picker shows both the served window and its reported ceiling. See docs/providers.md.- Skill discovery now searches
.agents/skillsfrom the current directory to the repository root, then~/.config/hax/skillsand~/.agents/skills; the nearest same-named skill wins. See docs/usage.md. - Provider routing and prompt-cache keys now remain stable for a conversation across restarts.
OpenRouter sends this id as
x-session-id, and/newstarts with a fresh id. - The first-party
openai,anthropic, andopenrouterproviders pin their protocol along with their endpoint:providers.<id>.apinow warns instead of switching the wire. Usemodel_apisfor per-model protocols, or a custom provider. - The
providers.openrouter.titleandproviders.openrouter.referersettings and theirHAX_OPENROUTER_*aliases are gone; override or remove the attribution headers throughproviders.openrouter.extra_headers. See docs/providers.md.
Fixed
- OpenCode Zen and Go now send the required
x-opencode-sessionheader; requests without it may fail starting 2026-09-06. - Chat Completions streams now retry upstream failures signaled through
errorornetwork_errorfinish reasons and report an error after retries, instead of returning an empty success. - Interactively resumed interrupted conversations now show the resume hint and accept empty Enter to continue.
- OpenCode Go usage-window limits now surface immediately instead of triggering futile retries.
- The retry indicator shows the active attempt after backoff instead of remaining at "retrying in 1s" while the request is in flight.
- v0.4.0hax v0.4.02026-08-22 · 2026-08-22 12:20 UTC
查看更新说明
Added
- OpenCode Zen and Go providers (
opencode-zen,opencode-go): setOPENCODE_API_KEY, choose a model, and hax selects the API it needs./usageshows OpenCode Go's subscription limits. See docs/providers.md. /loginsigns in to ChatGPT for the codex provider and keeps the token refreshed, so the codex CLI is no longer required. Existing codex CLI credentials remain a read-only fallback. See docs/providers.md.- llama.cpp multi-model router support:
/modelshows the server catalog and load state, selecting an idle model warms it in the background, and hax never loads a model you did not select. - Custom gateways can route different models through their required APIs. Provider blocks also
accept
extra_bodyandextra_headersfor documented gateway features such as routing rules, service tiers, and additional credentials. See docs/providers.md. - The transcript records the provider, model, and reasoning effort used for each turn, plus a different model or OpenRouter endpoint reported by the response.
- FreeBSD and OpenBSD can now build from source, and Arch Linux users can install the
haxAUR package. Stable releases update both the AUR package and Homebrew tap automatically.
Changed
- Breaking: provider settings now belong to
providers.<id>blocks and no longer leak between endpoints. Several keys and environment variables changed scope; users with advanced provider configuration should revisit docs/providers.md and docs/configuration.md. llama.cpp settings now live under the dot-freeproviders.llamacppconfig block; the user-facingllama.cppselection remains accepted. Auto-selection tries the built-in providers before compatible and custom providers. /modelnow uses a version-aware order by default: model families stay together and newer versions appear first. Setsort_modelstooffto preserve server order.- Only presets with a
descriptionare offered to the model as subagent roles. Favorite-only presets remain user shortcuts instead of inviting unrequested delegation based on a name alone. /providershows human-readable display names while keeping the selectable id visible. Unknown or inapplicable provider settings now warn instead of being silently ignored, and/configkeeps provider settings out of its general picker.- Reasoning effort now applies to Anthropic-compatible models on custom gateways unless an explicit
thinking_modeoverrides it. - Config updates made by hax preserve JSON numbers and booleans instead of rewriting them as strings.
Fixed
- Interrupted and failed responses no longer carry unfinished reasoning into the next request. An interrupt before any answer text or tool call leaves the conversation unchanged, while a stream that ends unexpectedly is retried automatically from a clean attempt.
- Reasoning now continues correctly across turns for affected Kimi, GLM, DeepSeek, and MiniMax models on OpenCode, and OpenAI, Gemini, Kimi, and MiniMax models on OpenRouter.
- Completed tool calls whose arguments arrive all at once, including Grok on OpenCode Go, no longer run with empty arguments.
- Markdown headings, multi-part reasoning summaries, wrapped styling, and consecutive reasoning blocks render consistently in both the live and history views.
- Transcript, history, editor, and file-picker views preserve non-ASCII text and no longer expose terminal escape sequences when used with a plain pager or without a configured locale.
- HTTP traces redact credentials found in request and error bodies, including values loaded from environment variables for provider headers.
- Keyless custom providers with a configured URL are selectable even when they do not expose a model-list endpoint.
- Custom prompt caching defaults to the sa
- OpenCode Zen and Go providers (
- v0.3.0hax v0.3.02026-08-12 · 2026-08-12 14:08 UTC
查看更新说明
Added
- Installable via the
oleksandrchekhovskyi/haxHomebrew tap. Each stable release points the formula at the published source tarball automatically. make installandmake symlinkcomplete the from-source flow.scripts/install_deps.shnow defaults to the full desktop set (build deps plusfzf), takescifor the bare set, and supports Fedora/RHEL and openSUSE./sessionshows the resolved context window before any request has reported usage (? / 256k), so the limit is visible up front.
Changed
- The
task_killtool is merged intotask_wait: akillargument stops the background task and returns its final output in the same call — immediately, or aftertimeout_secondsto give the task a last window to finish on its own. Stopping a task and collecting its output no longer takes two model round trips. - Compiled-in default model names are gone. Defaults now come only from live state (llama.cpp
server discovery, or the model Codex mirrors from
~/.codex/config.toml), so shipped binaries no longer park first-time users on a stale or expensive tier. Without a default, pick one with/modelor--model. - An unset
$VISUAL/$EDITORfalls back to the first ofeditor/nano/vim/vionPATH, and an unset$PAGERtoless -Rormore, instead of assumingviandless. A configured value that does not resolve is reported as an error rather than failing at spawn. --helpwraps at the terminal width the same way/helpdoes, so it no longer overflows narrow terminals.
Fixed
/newand/resumenow stop running background tasks and record each task's final state in the conversation being left, as quitting always did. Completed work no longer announces itself into a conversation that never started it, and task ids restart att1with each fresh conversation.- The parked "working..." spinner no longer blinks off and on around every silent tool call (reads, quiet bash). Erase, cluster text, and repark now land as one frame.
- Installable via the
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
hax
A minimalist, terminal-native coding agent written in C.
Key features
- Lightweight by design — A single native C binary with a small dependency set. Starts instantly and uses only a few MB of memory, leaving more RAM for local models.
- Local models are first-class — Start
llama-server -m [model].gguf, thenhax --provider llama.cpp, and hax auto-discovers the model and runtime capabilities. No custom provider config block is needed for the default setup. - Respects your terminal — Streaming Markdown and live tool output, reflowed for display in the terminal. Only redraws the current streaming line or the input area, native scrollback is preserved. Does not take over or mess with your terminal.
- Inspectable — See exactly what was sent to the model and what it replied in a usable transcript view (Ctrl+T). Optionally collect a detailed wire protocol trace.
- Broad provider support — OpenAI (+compatible), Anthropic (+compatible), Codex (via a ChatGPT subscription), OpenRouter, OpenCode Zen/Go, DeepSeek, llama.cpp, Ollama, and custom endpoints.
- Well-behaved Unix tool — XDG paths, clean stdout in
-pone-shot mode with resume hints on stderr, plain-text config and session files, composition via subprocesses instead of plugins.
Target audience
Developers who live in the terminal, run local models, audit what their tools do, package software for distros, or run agents where resources are scarce. If you want MCP marketplaces, a plugin runtime, IDE panels, or per-command permission prompts, other agents build exactly that — hax deliberately doesn't, and docs/philosophy.md explains each omission and the pattern that covers the need.
If "fancy new AI tech in an old-school minimalist package" sounds like your vibe, you might like this.
Install
hax runs on Linux, macOS, FreeBSD, and OpenBSD; on Windows, use it under WSL. The BSDs build from source only.
With Homebrew (macOS or Linux):
brew install oleksandrchekhovskyi/hax/hax
On Arch Linux, hax is in the AUR as hax.
Alternatively, prebuilt binaries for Linux (x86_64 and aarch64) and macOS (Apple Silicon) are
available from the latest release:
unpack the hax binary into any directory on your PATH. The Linux binaries are fully static,
and the macOS one needs only libraries that ship with macOS. If macOS refuses to run a binary
downloaded through a browser, clear its quarantine flag with xattr -d com.apple.quarantine hax.
From source
Building from source gives a binary linked against your system's shared libraries instead of the libraries the prebuilt binaries bundle:
git clone https://github.com/OleksandrChekhovskyi/hax.git
cd hax
scripts/install_deps.sh # Debian/Ubuntu, Fedora, Arch, openSUSE, Alpine, macOS, FreeBSD, OpenBSD
make # the binary is now at ./build/hax
make install # optional; may prompt for sudo
scripts/install_deps.sh installs the build dependencies — a C compiler, libcurl,
jansson, meson, ninja, and pkg-config — plus fzf, which hax uses for @file
completion when available. On other platforms, install those packages by hand and run make.
For hacking on hax, make symlink links the freshly built binary into ~/.local/bin so it
stays on PATH across rebuilds. make tests additionally needs tmux, which drives the
interactive scenarios (scripts/install_deps.sh tests installs it), and make lint needs
clang-format and clang-tidy (scripts/install_deps.sh lint installs them).
The examples below use hax as if it is on PATH; after a plain build, use ./build/hax.
Connect a provider
The easiest first run is interactive: start hax, then use /provider to see available providers
and choose a model. hax remembers interactive provider, model, and effort selections.
| Provider | Setup |
|---|---|
codex | Run /login inside hax. |
openai | Set OPENAI_API_KEY. |
anthropic | Set ANTHROPIC_API_KEY. |
openrouter | Set OPENROUTER_API_KEY. |
opencode-zen / opencode-go | Set OPENCODE_API_KEY. |
deepseek | Set DEEPSEEK_API_KEY. |
llama.cpp | Run llama-server. |
ollama | Run ollama serve. |
| Compatible or custom endpoint | See docs/providers.md. |
Quick start
Run hax from the project directory you want it to work in:
hax # interactive REPL
hax -p "list TODOs" # run one prompt and print the final answer
printf "explain x" | hax -p # read the prompt from stdin
hax -c # continue the latest session for this directory
hax --resume # pick a past session for this directory
hax --resume=ID -p "next" # resume a specific session in one-shot mode
Run hax --help for CLI usage, or man hax where the man pages are installed. In the REPL, type
/help for slash commands and shortcuts. See docs/usage.md for more detailed
usage documentation.
Configuration
Configuration is optional. Interactive selections are remembered separately from your config file; CLI flags apply only to the current run, and environment variables are useful for shells and scripts. Resumed conversations restore their own provider, model, effort, and preset unless a CLI selection flag overrides them.
See docs/configuration.md for the file format, resolution order, presets, and the setting reference.
Extras
Optional companions that live outside the core binary, each a small Python CLI with a skill that tells hax when to use it:
- hax-web — web search and readable page fetching.
- hax-mcp — tools of MCP servers, with definitions entering the model's context only as a task needs them.
More docs
- docs/sessions.md — the session-file format and the
hax --jsonstream. - docs/debugging.md — trace/transcript logs, mock provider, and demo scripts.
- CONTRIBUTING.md — how to propose, prepare, and submit a change.
License
MIT.