Documents how zoo/app shims hanzo/desktop, the BrandConfig contract, chain IDs (zoo 200200/200201/200202, hanzo 36900/36901), the sidecar list (Ollama dropped), and the read-order for new contributors.
4.9 KiB
Zoo / Hanzo Desktop Stack
Decomposition of the desktop-app architecture so Zoo AI Desktop is a declarative brand variant of Hanzo Desktop with no forked source.
Repos
| Path | Role | Language |
|---|---|---|
~/work/hanzo/desktop (hanzoai/desktop) |
Canonical desktop source. Tauri 2.x + React. | Rust + TypeScript |
~/work/zoo/app (zooai/app) |
Thin pnpm shim. pnpm build → BRAND=zoo upstream build. |
Bash + assets |
~/work/hanzo/node |
AI agent backend: chat router, MCP server, agent harness, tool runner. | Rust |
~/work/zoo/node |
Native chain node zood (consensus + EVM + AI-mining precompiles). |
Go |
~/work/lux/consensus |
Quasar consensus engine consumed by both nodes. | Go (with Rust FFI) |
~/work/zoo/logo |
Canonical brand-asset source for ~/work/zoo/app/brand/. |
SVG + PNG |
~/work/zoo/universe |
This repo. Architecture + ops docs. | Markdown + compose |
zood and hanzo-node are not interchangeable. hanzo-node is the
AI/agent router that the desktop app talks to over local HTTP. zood is the
chain node (validators + EVM + precompiled AI-mining contract). The desktop
ships hanzo-node as a sidecar; the chain RPC is remote.
Brand variants from one source
The Hanzo Desktop source supports both Hanzo and Zoo brands via:
libs/brand-config/— singleBrandConfigexported bygetBrand()apps/hanzo-desktop/src-tauri/tauri.conf.{hanzo,zoo}.json— overlay merged before invokingtauri buildapps/hanzo-desktop/scripts/brand-build.cjs— pre-merges Tauri config and patchesInfo.plistto fixCFBundleIdentifierpropagationapps/hanzo-desktop/src-tauri/src/local_hanzo_node/hanzo_node_options.rs—option_env!("BRAND")switches initial agent names at compile timeapps/hanzo-desktop/public/{visor,zoo-logo}.svg+{onboarding,zoo-onboarding}.png— both brands' assets coexist; React picks viagetBrand().brand
BrandConfig
interface BrandConfig {
brand: 'hanzo' | 'zoo';
name: string; // "Hanzo" | "Zoo"
productName: string; // "Hanzo Desktop" | "Zoo Desktop"
identifier: string; // com.hanzo.desktop | com.zoo.desktop
logo: { light, dark, favicon };
colors: { primary, bg, fg };
hosts: string[]; // hanzo.ai | zoo.ngo, zoo.network
storeUrl: { mac, win, ios, android };
// Native chain identity. Mining checkpoints submit to the AI-mining
// precompile on the brand's primary EVM/A-chain.
network: {
rpc: string; // https://rpc.hanzo.network | https://rpc.zoo.network
chainId: number; // 36900 hanzo / 200200 zoo
token: string; // $AI | $ZOO
aiMiningPrecompile: `0x${string}`; // 0x0300...0000
blockExplorer: string;
};
// Cloud AI inference (chat completions + embeddings). Distinct from chain RPC.
inferenceEndpoint: string; // https://gateway.hanzo.ai
// OAuth IAM provider for "Login with <Brand>".
iam: { baseUrl, clientId, redirectUri, callbackEvent };
}
Chain IDs
| Network | chainId | RPC |
|---|---|---|
| Hanzo Mainnet | 36900 | https://rpc.hanzo.network |
| Hanzo Testnet | 36901 | https://rpc.hanzo-test.network |
| Zoo Mainnet | 200200 | https://rpc.zoo.network |
| Zoo Testnet | 200201 | https://rpc.zoo-test.network |
| Zoo Devnet | 200202 | https://rpc.zoo-dev.network |
AI-mining precompile: 0x0300000000000000000000000000000000000000 on each.
Sidecars
| Binary | Purpose | Brand |
|---|---|---|
hanzo-node |
AI agent router, chat, MCP, tool runner | both |
deno, uv |
Tool sandboxes for hanzo-tools-runner | both |
Removed: ollama. Embeddings + LLM inference now go through the cloud
inference endpoint or via hanzo-node's built-in embedding (when available).
This drops ~62 MB from the bundle and removes a managed sidecar process.
Build
# Hanzo brand (canonical)
cd ~/work/hanzo/desktop/apps/hanzo-desktop
npm run build:hanzo
# -> Hanzo.app, com.hanzo.desktop
# Zoo brand (declarative shim)
cd ~/work/zoo/app
pnpm build
# -> Zoo.app, com.zoo.desktop
# Internally: ln -s brand/icons -> upstream/src-tauri/icons/zoo,
# then BRAND=zoo VITE_BRAND=zoo npm run build:zoo upstream-side.
Releases
| Brand | Registry | Releases |
|---|---|---|
| Hanzo | ghcr.io/hanzoai/* | github.com/hanzoai/desktop |
| Zoo | ghcr.io/zooai/* | github.com/zooai/desktop |
Container registries do not mix per the rule in ~/.claude/CLAUDE.md.
Reading order for new contributors
~/work/hanzo/desktop/libs/brand-config/src/index.ts— the contract~/work/hanzo/desktop/apps/hanzo-desktop/scripts/brand-build.cjs— how Tauri configs merge~/work/zoo/app/scripts/build.sh— how the shim invokes the upstream build~/work/hanzo/desktop/apps/hanzo-desktop/src-tauri/src/local_hanzo_node/hanzo_node_options.rs— howoption_env!("BRAND")selects the initial agents