@zap-proto/zap moved from the old MCP-misnamed Cap'n Proto package to
the native ZAP wire runtime, and rejoined the 1.x line at 1.1.0. The
new canonical surface has a single root export (builder, client/
ZapClient, envelope, pipeline, view, wire) and NO ./protocol, ./transport,
or ./rpc subpaths — and no Client/Server/BatchClient/MessageType symbols.
The wrapper's prior src (protocol/transport/rpc/client/server/types/error
re-exporting those now-nonexistent symbols and subpaths) no longer
compiles against it. Collapse the wrapper to its honest shape: a single
`export * from "@zap-proto/zap"` root re-export. ZapClient flows through
natively, so the old `Client as ZapClient` alias is dropped (it aliased
a symbol the canonical package no longer exports; ZapClient is now the
canonical name).
- dep: @zap-proto/zap ^1.0.0 -> ^1.1.0
- version: 1.0.0 -> 1.1.0 (minor; matches the underlying line, no major break)
- build: single-entry tsup (drop the dead multi-entry subpath build)
- exports: drop ./protocol ./transport ./rpc (canonical has no such subpaths)
- repository.directory: correct to hanzo-dev/zap/sdk/typescript
- test: --passWithNoTests (pure re-export; nothing of its own to test)
Reverts violations of the durable rule that current-state docs belong
in LLM.md and history belongs in git log. Removed files were session
handoffs, agent-style "complete success" / "1000%" reports, dated
audit dumps, and stub NOTES.
* infra: standardize ZAP duplex port to 9999
ZAP binary protocol duplex RPC standardizes on :9999 across every
service. Lux validator staking/RPC ports (9630/9631 mainnet, 9650/9651
devnet) are unchanged — those are luxd network protocol ports, not ZAP.
One ZAP port everywhere (was a mix of 9651/9652/9653/9633/9900).
* ci: upstream-sync workflow — auto-merge clean, issue on conflict
Periodic sync from just-every/code (the canonical upstream Hanzo dev tracks).
Every 6h: fetches upstream, attempts merge, opens PR with automerge label
if clean, otherwise opens an issue listing conflicting paths. Bot does not
resolve content conflicts.
* ci: upstream-sync drafts only, one workflow (drop upstream-merge)
- delete upstream-merge.yml (1106 lines, auto-merge, polled every 30 min)
in favour of single upstream-sync workflow
- upstream points to openai/codex (matches LLM.md), not just-every/code
- weekly cron Mon 06:00 UTC (was every 6h)
- branch named upstream-sync/<UTC-date>
- always opens draft PR, never auto-merges
- on conflict, commits markers in place and opens draft PR labelled conflict
so the branch is checkoutable for human resolution
- LLM.md documents the new flow
One way: there is now exactly one upstream-sync entry point.
codex-rs depends on v8 (via code-mode) which has no musl prebuilt,
breaking CI builds. Revert release workflow to hanzo-dev workspace
which doesn't have this dependency.
Also disable the ★ Upgrade Available ★ banner — updates are handled
via CI/CD releases, not in-TUI upgrade prompts.
- Remove duplicate multi_agents.rs (dir-based mod.rs is canonical)
- Sync hanzo-dev protocol with upstream: add ToolSearchCall,
ToolSearchOutput, namespace field on FunctionCall
- Add RequestError type to hanzo-dev backend-client
- Fix pattern matches for new CustomToolCallOutput name field
The IAM init_data.json uses <org>-<app> naming convention.
The actual provisioned app is "hanzo-app" (clientId=hanzo-app),
not "app-hanzo" which was never deployed. All IAM apps use
empty secrets (public clients with PKCE).
Review finding: unwrap_or_else(|_| reqwest::Client::new()) silently
reverts to native-tls if rustls builder fails, defeating the TLS fix.
Replace with expect() since rustls builder should never fail in
practice. Also includes linter cleanups.
The assistant bg tint was only painted within the content area (minus
padding), leaving 1-column gaps on the left and right edges. Now paints
the tint across the full history_area width so assistant messages have
edge-to-edge background color.
Zen models (qwen3-based) emit <think>...</think> blocks inline in the
answer stream. These were rendered as raw text in both the TUI and CLI.
Added ThinkTagFilter that handles streaming deltas where tags can span
multiple chunks. Applied to both:
- TUI streaming controller (push_and_maybe_commit + apply_final_answer)
- CLI event processor (AgentMessageDelta + AgentMessage)
Also increased assistant message background tint from 5% to 12% — the
original value was nearly invisible on dark/black terminals (resulted in
RGB ~(6,10,13) which looked identical to pure black).
When both rustls-tls and native-tls features are compiled in (via
chromiumoxide → reqwest default features), reqwest silently defaults to
native-tls. On macOS this is SecureTransport, which fails TLS handshake
against Go crypto/tls servers (Traefik ingress) with "bad protocol
version".
Fix: explicitly call .use_rustls_tls() on every reqwest::Client::builder()
to ensure consistent TLS behavior across all platforms.
Also reverts the earlier native-tls experiment in Cargo.toml files back
to rustls-tls and removes temporary TLS diagnostic logging.
When footer_height is 0 (zen mode), the input area was stretching
to fill all available height. Now it uses input_height and anchors
to the bottom of the available area, giving a compact input bar.
The textarea was painting its rows with the main background() color
instead of input_background(), causing the input area to show as
pure black instead of the subtle gray set by the Block. This broke
the contiguous background appearance of the input area.
Login screen now offers 5 options:
1. Sign in with Hanzo ID (default, via hanzo.id OAuth)
2. Sign in with ChatGPT (OpenAI OAuth)
3. Sign in with Claude (keychain auto-detect + claude.ai OAuth fallback)
4. Provide your own API key
5. Sign in with Device Code (headless)
CLI: `hanzo login --provider hanzo|openai|claude`
Auth error handling:
- 401/403 responses are no longer retryable (stops "Reconnecting..." loop)
- Clear error message: "Authentication failed (401). Run `hanzo login` to sign in."
- Maps to CodexErrorInfo::Unauthorized for frontend handling
Fixes:
- Remove duplicate test functions from merge (chatwidget/tests.rs)
- Fix SessionTelemetry::new() calls missing originator parameter (otel tests)
Auth changes:
- HANZO_API_KEY has highest priority, then CODEX_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY
- Default OAuth issuer changed to hanzo.id (Casdoor)
- Skip API key exchange for non-OpenAI issuers (Casdoor uses access_token directly)
- RefreshRequest includes client_secret for Casdoor compat
- id_token_or_access() fallback for Casdoor token refresh
- Login status detects provider from key prefix (sk-hanzo-, sk-ant-, sk-)
- Hanzo client credentials (app-hanzo) for OAuth flow
Branding:
- Welcome screen: "Hanzo Dev — AI development in the terminal"
- All user-facing "Codex" → "Hanzo Dev"
- Update URLs point to github.com/hanzoai/dev
- npm package: @hanzo/dev
- Windows toast: "Hanzo Dev"
- hanzo-zt: zap-schema path dep (../../../../zap/zap) → crates.io v1.0
- hanzo-zt: enable hanzo-tunnel dep from crates.io v0.1
- hanzo-zt: activate full feature (zap + tunnel)
- No more external path deps that break CI
- hanzo-tunnel v0.1.0 published to crates.io (was path dep to ../../../tunnel)
- cli: tunnel + tunnel-bridge deps now optional behind `tunnel` feature flag
- cli: cloud module (ZT + relay) gated with #[cfg(feature = "tunnel")]
- tunnel-bridge: all hanzo_tunnel usage gated behind `tunnel` feature
- CI: fix prettier by scoping JS globs, excluding symlinked CLAUDE.md
- CI: format all workflows and docs with prettier
- Workspace compiles clean without tunnel feature (CI default)
- Local builds with `--features tunnel` still work with crates.io dep
New crate at hanzo-dev/zt/ providing ZT overlay networking:
- ZtContext: authenticate, dial, listen, service discovery via ZT controller REST API
- HanzoJwtCredentials: Hanzo IAM JWT resolution from env/auth file
- BillingGuard: Commerce API balance check + usage recording (no free tier)
- ZtTransport: ZAP Transport trait impl for zt:// URL scheme
- CLI integration: cfg-gated zt:// support in cloud.rs
- 9 tests passing, 0 warnings
Switch from connect() to connect_and_register() so the CLI receives the
session URL from the bot gateway and displays it to the user. Add three
integration tests for the tunnel-bridge: connect+register flow,
reconnection, and graceful failure on unreachable gateway.
Add --cloud flag (or HANZO_CLOUD=1 env) to connect dev instances to the
Hanzo cloud relay at wss://api.hanzo.ai/v1/relay, making them remotely
manageable from app.hanzo.bot.
New crates:
- tunnel-bridge: translates cloud commands (chat.send, exec.approve) to
app-server JSON-RPC and app-server notifications back to cloud events
- cli/cloud.rs: CLI integration with clap args, auth resolution, and
background tunnel dispatch loop
Supports two modes:
- Cloud relay (default): wss://api.hanzo.ai/v1/relay
- Local gateway: --cloud local → ws://127.0.0.1:18789/v1/tunnel
Refactor transport.rs into transport/ module directory:
- transport/mod.rs: existing TCP/TLS/Unix transport (ZapTransport)
- transport/http.rs: new HTTP/SSE transport (HttpTransport) for
environments without raw TCP (browsers, serverless, proxied infra)
- Re-export HttpTransport from lib.rs