`hanzo code` is the CLI's headline command and it runs `dev` by default. A public `curl hanzo.sh | sh` did not install `dev`, so the first thing a new reader ran answered: Error: the `dev` coding agent is not installed (not on PATH) The two reasons the installer named for skipping it are both gone — hanzoai/dev is public and publishes `dev-<os>-<arch>.tar.gz.sha256` — so it is one row in TOOLS, exactly as LLM.md said it would be. With no second name: the alias defaults to `hanzo-node`, which the CLI owns, and handing that name to a different program is how the delegate silently changes identity. Verified end to end in a clean HOME under both dash and bash: hanzo 1.9.18, hanzo-mcp 1.1.15, dev 0.6.91, and `hanzo code` now starts Hanzo Dev instead of erroring. The page rendered four components, not one. Hero is the whole page and carries its own header and footer, so the leftover Lovable-template Navbar, Features and Footer rendered a SECOND fixed nav, four invented feature cards, sixteen `href="#"` links that go nowhere, "Simplifying application development and deployment with innovative container solutions" for a company that does not sell containers, and a `© 2024` ten pixels under the real `© 2016–2026`. All five leftover components deleted. Rendered proof: 1 header, 1 footer, 0 dead links, 11 links and every one resolves. Two JSX text nodes shipped their escapes as text — the page literally read `source →` and `— the same build`. Fixed; 0 literal escapes render now. llms.txt: `hanzo usage` is a group, not a command (it prints subcommands and stops) -> `hanzo usage summary`. `hanzo engine serve enso` was published as if it worked; it needs the Hanzo engine binary this installer does not ship, and says so — stated as a gap rather than left to be discovered. Added the model ids that exist, the public catalog URL, and why `hanzo login` is not a command. The installer's version line printed the last field of `--version`, which is a build date for `dev` (`✓ dev 2026-04-01`); it now takes the first token that looks like a version. "installable today" is read off TOOLS instead of being a second hardcoded list. Co-authored-by: Hanzo Dev <[email protected]>
hanzo.sh
The install surface for the Hanzo tools. One command:
curl -fsSL https://hanzo.sh | sh
That downloads one prebuilt native binary per tool, verifies its sha256, and puts it on PATH — no runtime, no package manager, no build step:
| tool | also installed as | source |
|---|---|---|
hanzo |
hanzo-node |
hanzoai/cli |
hanzo-mcp |
mcp |
hanzoai/mcp |
Each pair is one build, symlinked, so the two names can never be two versions. Re-run to upgrade. One tool at a time:
curl -fsSL https://hanzo.sh/cli | sh
curl -fsSL https://hanzo.sh/mcp | sh
This repo
dist/index.html is a polyglot — the same bytes are the landing page in a
browser and the installer under sh. public/install.sh is the installer;
scripts/build-polyglot.js wraps the built HTML in a heredoc and appends it.
Downloading is NOT implemented here. hanzoai/cli/install.sh is the one
implementation of "fetch a Hanzo binary" — platform detection, asset naming,
checksum verification, the second-name symlink — and this drives it once per
tool. Keep it that way; a second copy of platform detection is a second thing to
drift.
pnpm install
pnpm dev # vite, :8080
pnpm build # -> dist/, including the polyglot rewrite
pnpm lint
Test an installer change without deploying, under both published shells:
cd dist && python3 -m http.server 8791 &
curl -fsSL http://127.0.0.1:8791 | sh
curl -fsSL http://127.0.0.1:8791 | bash
Deploying
.github/workflows/deploy.yml builds, publishes the Cloudflare Worker, then
re-fetches https://hanzo.sh and fails if the live bytes are not the bytes it
just built. This host was hand-published for a long time, which is how a merged
fix sat unseen for weeks while curl hanzo.sh | sh kept handing out the old
installer — so verifying the live URL is part of deploying, not a follow-up.
gh workflow run deploy.yml -R hanzo-apps/hanzo.sh --ref main
Run it explicitly. The workflow declares on: push too, but pushes to this repo
are not currently creating runs — measured, cause not established; see
LLM.md. Until that is fixed, a merge is not a deploy, so check:
curl -sS https://hanzo.sh | md5sum
LLM.md has the details, including the unfinished migration to hanzoai/static.