23 Commits
Author SHA1 Message Date
Hanzo Dev 3699eb145f fix(claude-code): curated model picker always includes the selected model
The claude-code target listed a hardcoded HANZO_MODELS set (glm-5.2,
deepseek-v4-flash, deepseek-v4-pro, zen5-max — all verified routable) but
dropped the user's actual selection if it wasn't among them. Merge creds.model
in and dedupe so the picker never omits the chosen default, while keeping the
short curated list (the live catalog carries 60+ ids). Also add the missing
ClaudeSettings.model type and drop the redundant 'ultra' effort alias (== max).

v1.0.7
2026-07-03 11:18:53 -07:00
Hanzo Dev b8235f55de fix: KMS on its own host (kms.<brand>), stable doctor probes
Live infra drift (gateway redeploy): api.hanzo.ai/v1/kms is NOT proxied (404),
and the bare /health path moved (/health 404, /v1/health 200). Two fixes:

- KMS runs on its dedicated host kms.<brand> (kms.hanzo.ai, per IAM's per-brand
  KMSHost). Added brand.kms + endpoints.kms (HANZO_KMS_URL override); KMS client
  targets it instead of api.hanzo.ai/v1/kms. Verified live: kms.hanzo.ai/v1/kms/
  orgs/hanzo/secrets → 401 (gated, live).
- doctor now probes the STABLE endpoints the tool actually depends on — IAM
  /.well-known/openid-configuration + api /v1/models — not a bare /health that
  varies by gateway config. Both 200.
- kms-secrets action base-url default → kms.hanzo.ai.

Release 1.0.6 (helper + @hanzo/kms + lux/zoo/zen forks).
2026-06-30 22:37:29 -07:00
Hanzo Dev 925e692b8b fix: npx regression + version drift; add standalone @hanzo/kms package
Two real bugs:
- npx @hanzo/helper broke when the kms bin was added — a package with TWO bins
  can't be run by 'npx <pkg>' (could not determine executable). Reverted helper
  to its single 'hanzo' bin; kms stays as 'hanzo kms' AND as its own package.
- version.ts was hardcoded '1.0.0' — 'hanzo --version' always lied. Now injected
  from package.json at build (tsup define __HANZO_VERSION__), one source of truth.

- packages/kms: new standalone @hanzo/kms (single 'kms' bin) that re-runs the
  helper's kms CLI via the new ./kms-cli export. npm i -g @hanzo/kms → 'kms'.
- exports: add ./kms-cli so the standalone package imports it cleanly.

Published: @hanzo/helper@1.0.5, @hanzo/kms@1.0.5, @luxfi/@zenlm/@zooai/helper@1.0.5.
2026-06-30 21:36:08 -07:00
Hanzo Dev 2cd5a78ee5 release: forks → 1.0.3 (match @hanzo/helper); normalize fork package.json
Bump @luxfi/@zenlm/@zooai/helper to 1.0.3 with @hanzo/helper ^1.0.3 (picks up
the get-account/health endpoint fixes + kms login). npm pkg fix: bin paths and
repository URL normalized so publishes are warning-free.
2026-06-30 21:30:55 -07:00
Hanzo Dev 554f802e98 fix: correct account + health endpoints (get-account 404, /v1/health 404)
Three live-verified endpoint bugs, all where a call hit the wrong host/path:

- readApiKey + fetchUser hit api.hanzo.ai/v1/get-account (404). The account read
  lives on the IAM issuer: {iam}/get-account (…/v1/iam/get-account, 200). Same
  base as mint/revoke. Added IAM_PATHS.account.
- fetchUser also parsed the account at the top level, but GetAccount wraps it in
  a { status, sub, name, data, data2 } envelope — email/owner are under data, so
  org came back EMPTY (which kms pull needs). Now reads data.{email,owner,...}.
- doctor: api /v1/health (404) -> /health (200); iam /api/health -> /health
  (drop the /api/ prefix per house style).

Verified live: hanzo doctor now green (IAM 200, Cloud API 200); models table,
--tiers, and detail all work. Release 1.0.3.
2026-06-30 17:55:38 -07:00
Hanzo Dev a61c6b68f6 release: @hanzo/helper@1.0.2 (kms login + pull live on npm) 2026-06-30 17:37:24 -07:00
Hanzo Dev ea97280f9e kms: standalone login so 'kms pull' works self-sufficiently
The gap behind 'kms pull must work' was that the standalone kms had no way to
sign in — and an hk- API key can't auth to KMS (it needs an IAM JWT the KMS
verifies against hanzo.id JWKS). Fix: one device-login primitive, every door.

- lib/signin.ts: deviceSignIn() — the RFC 8628 flow against hanzo.id, persists
  accessToken + user to the shared ~/.hanzo/config.json. Extracted from login.ts.
- kms-cli.ts: 'kms login' + pull/list. Self-sufficient standalone tool.
- auth.ts: 'hanzo auth login' — same session.
- login.ts: browserLogin now composes deviceSignIn + key mint (DRY).

One token store: sign in via kms login, hanzo login, or hanzo auth login — all
write the same session, so kms pull works after any of them. Verified live:
kms login returns a real device code from hanzo.id.
2026-06-30 17:36:55 -07:00
Hanzo Dev e1ade87d38 kms: use the canonical live KMS API, drop invented endpoints
KMS already serves the one-way secret surface (hanzoai/kms embed.go): the dev's
IAM login token goes straight to /v1/kms/orgs/{org}/secrets — KMS verifies it
against hanzo.id JWKS (authorize + canActOnOrg). No /v1/kms/oidc/login or
/v1/kms/get-secrets exchange (those were invented; they 404). One token, one way.

- lib/kms.ts: listSecrets + getSecret + pullSecrets over the real endpoints.
  Respects KMS's security boundary — list returns KEYS ONLY; values are read
  one-by-one (bounded concurrency), no bulk-value dump.
- commands/kms.ts: org comes from the login session (--org override); IAM token
  from config.accessToken. pull/list unchanged in UX.
- actions/kms-secrets: same canonical list-then-get; token input is an
  IAM-issued token KMS trusts (GitHub OIDC only if KMS trusts that issuer).
- npm-release.yml: pass org=hanzo + KMS_IAM_TOKEN.

Verified: GET /v1/kms/orgs/hanzo/secrets?env=devnet is LIVE (401, gated) on
api.hanzo.ai — endpoint exists, needs a real IAM token to list.
2026-06-30 17:31:16 -07:00
Hanzo Dev 08946e40a2 kms: get-secrets (verb-noun, matches /v1/iam/get-account house style) 2026-06-30 14:18:27 -07:00
Hanzo Dev 8712aef343 kms: dev secrets via the one OIDC mechanism (IAM issues, KMS owns)
A developer's `hanzo login` already mints an IAM OIDC token; `kms pull --env
devnet` exchanges it for a short-lived KMS token and writes a local .env. Clean
orthogonal separation — IAM is a pure issuer (/v1/iam), KMS owns secrets/envs/
authz (/v1/kms); they compose through the token, neither imports the other. No
broker, no /api/, no compound words (oidc, not oidc-auth).

- src/lib/kms.ts: kmsLogin + kmsSecrets + pullSecrets over /v1/kms/oidc/login
  and /v1/kms/secrets; tolerant of {K:V} or [{secretKey,secretValue}] shapes.
- src/commands/kms.ts + src/kms-cli.ts: `hanzo kms` and standalone `kms` bin —
  one implementation, two entry points. pull/list, env devnet|testnet|mainnet|
  production (default devnet), dotenv out.
- CI shares the SAME mechanism: .github/actions/kms-secrets loads secrets via a
  GitHub OIDC token through /v1/kms/*; reusable .github/workflows/npm-release.yml
  publishes any package with NPM_TOKEN from KMS (self-hosted runners, no
  long-lived token in GitHub); release.yml ships helper + forks on tag.
- DRY: dev and CI use one /v1/kms exchange; one login, one token store.
2026-06-30 14:16:11 -07:00
Hanzo Dev a46e4a51f7 v1.0.1: expose ./cli subpath so brand forks can import the CLI
The forks (@luxfi/@zenlm/@zooai/helper) re-run our CLI with HANZO_BRAND set,
but exports only published '.', so import('@hanzo/helper/dist/cli.js') failed
with ERR_PACKAGE_PATH_NOT_EXPORTED. Add a stable './cli' export and point the
forks at @hanzo/helper/cli (not a deep dist path). Bump fork deps to ^1.0.1.
Fix stale zoo.id → zoolabs.id comment.

Published: @hanzo/helper@1.0.1, @luxfi/helper@1.0.0, @zenlm/helper@1.0.0,
@zooai/helper@1.0.0.
2026-06-30 13:42:45 -07:00
Hanzo Dev 2565652262 default model glm-5.2; Claude Code sets top-level model to the Hanzo default 2026-06-30 13:32:55 -07:00
Hanzo Dev 79144512fe models: rich live catalog from pricing.<brand>/v1/pricing/models
hanzo models now renders the same rich data as the console Models page —
provider (normalized: glm→Zhipu, qwen→Qwen, Zen first-party), plan tier,
context window, params/arch, and input/output $/Mtok — joined with your live
routing set for honest availability. Catalog ids are OpenRouter-style for
third-party (z-ai/glm-5.2); the routing id is the last path segment, so the
join keys on {id, name, last-segment} and each row shows the id you actually
pass to --model. Adds `hanzo models <name>` detail view + --all; falls back to
the plain id list if the catalog is unreachable. Pricing host derives from the
brand site (pricing.<host>), white-label correct.
2026-06-30 13:17:52 -07:00
Hanzo Dev 8d21f68d8a package: publishConfig.access=public for scoped first publish 2026-06-30 12:44:07 -07:00
Hanzo Dev 6c32048e12 Dynamic cloud catalog + smart tiers + one-command ecosystem installer
- models: read the catalog live from api.hanzo.ai/v1/models; nothing hardcoded.
  Effort words (auto/fast/high/max/code/agent) are sugar over the cloud's own
  zen-* routing aliases — the cloud picks the concrete model. Default = zen-auto.
- claude-code: write the live model list into providers.hanzo (was a static array).
- credentials carry the live model list so configure() stays sync + orthogonal.
- config: honor HANZO_API_KEY env so the CLI works headless / in CI.
- ecosystem: one data-driven registry (dev, mcp, node, desktop+Enso, extension,
  ide, slack, github); 'hanzo install' checklist + per-component npm/guide runner.
- login wizard offers ecosystem setup as its final out-of-box step.
- add eslint flat config (deps were present, config was missing); lint clean.
- brand: add public web root (site) so fork install links white-label correctly.
2026-06-30 12:43:52 -07:00
Hanzo Dev fba6864b8e Drop local .claude/settings.local.json from tracking; gitignore .claude/ 2026-06-29 15:27:10 -07:00
Hanzo Dev 581ab6c4f1 Two install modes, model tiers, providers-based Claude Code config
- Two install targets, user picks (or --mode shell|tools):
  * tools  — additive providers.hanzo block in tool config (Claude Code /
    Codex / Claude Desktop); keeps the default Anthropic login intact, switch
    per-session with /model hanzo/<model>. This is how Claude Code reads a
    custom provider (verified against a live ~/.claude/settings.json).
  * shell  — managed export block in the detected shell rc (zsh/bash/fish):
    ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN + ANTHROPIC_MODEL → Hanzo becomes
    the default for every Anthropic-compatible tool. Sentinel-delimited;
    install/uninstall round-trip preserves all other rc content (tested).
- Friendly model tiers → live ids (all verified against api.hanzo.ai/v1/models):
  default=glm-5.2, flash=deepseek-v4-flash, pro=deepseek-v4-pro,
  ultra=qwen3.5-397b, max=zen5-max. resolveModel() accepts a tier or a raw id;
  wired into login/use; `hanzo models --tiers` shows the map.
- Default model is glm-5.2 (fast all-rounder, works on both /v1/chat/completions
  and /v1/messages). Zen models confirmed live (zen5-pro returned exact output).

Verified live: tier 'pro' → deepseek-v4-pro → real completion.
2026-06-29 15:27:02 -07:00
Hanzo Dev 6ef8783e6b feat(models): expand HANZO_MODELS to full zen5 ladder + new DO-AI models 2026-06-29 15:23:43 -07:00
Hanzo Dev 2bd2ba08e8 brand: Zen login host is id.zenlm.org (we own zenlm.org, not zen.id)
zen.id is not a domain we control; use the id.<domain> pattern on the owned
domain (matches id.lux.network / id.zoo.network style). Zoo already correctly
uses zoolabs.id + api.zoo.ngo (no zoo.network).
2026-06-29 15:14:42 -07:00
Hanzo Dev efe37e747c Add brand white-labeling + lux/zoo/zen fork scaffolds
- brand.ts: one codebase, four ecosystems. HANZO_BRAND selects defaults for
  Hanzo (hanzo.id/api.hanzo.ai/hanzo-app), Lux (lux.id/api.lux.network/lux-app),
  Zoo (zoolabs.id/api.zoo.ngo/zoo-app), Zen (zen.id/api.zenlm.org/zen-app). IAM
  hosts verified against login/middleware.ts tenant map. Explicit
  HANZO_IAM_URL/API_URL/CLIENT_ID still override everything.
- endpoints.ts derives defaults from the active brand; CLI name/description are
  brand-aware so a fork shows its own identity (white-label rule: never show
  another brand).
- forks/{lux,zoo,zen}: thin packages (@luxfi/helper, @zooai/helper, @zenlm/helper)
  that set HANZO_BRAND and depend on @hanzo/helper — DRY, no code duplication.

Verified: all four brands resolve correct hosts; all three coding-tool targets
(Claude Code, Claude Desktop, Codex) round-trip configure/unconfigure cleanly.
2026-06-29 15:09:16 -07:00
Hanzo Dev 63bf9a1ad4 feat(targets): providers-based Claude Code config + Claude Desktop for all platforms
claude-code.ts: switch from env.ANTHROPIC_* (session hijack) to providers.hanzo
entry — additive, non-destructive. Users switch with /model hanzo/deepseek-v4-pro
without losing the default Anthropic connection. HANZO_MODELS list reflects the
live api.hanzo.ai catalog (Zen + GLM + DeepSeek + Qwen + Kimi + Nemotron).

claude-desktop.ts: new target. Writes mcpServers.hanzo into claude_desktop_config.json.
Config path is platform-aware: ~/Library/... (macOS), %APPDATA%\Claude (Windows),
~/.config/Claude (Linux). API key passed as env var to `npx @hanzo/mcp`.

index.ts: register claudeDesktop in TARGETS.
2026-06-29 15:08:24 -07:00
Hanzo Dev c74c6920e4 Align helper to canonical /v1/iam issuer + add bare-invoke and paste-key flows
- Single coherent endpoint model matching the dev CLI: IAM issuer base
  https://hanzo.id/v1/iam (HANZO_IAM_URL), all IAM ops issuer-relative
  (/oauth/device, /oauth/token, /mint-user-keys, /revoke-user-keys); cloud API
  https://api.hanzo.ai for /v1/get-account + inference. Device auth carries
  params in the query string with response_type=device_code, matching dev.
- Bare `hanzo` / `npx @hanzo/helper`: runs login+setup when signed out, shows
  status when signed in.
- `hanzo login` now offers browser device login OR pasting an existing hk- key;
  `--key` supports non-interactive setup.
- White-label override verified (HANZO_IAM_URL/API_URL/CLIENT_ID → lux-app etc).

Verified end-to-end: paste-key → Claude Code settings.json wired correctly.
2026-06-29 15:03:55 -07:00
Hanzo Dev a7d0be83ea Rebuild @hanzo/helper around real hanzo.id device login + coding-tool config
Verified against the actual Hanzo sources (iam, ai, console2, login):

- Device login (RFC 8628) against hanzo.id /oauth/device + /oauth/token,
  form-encoded, client_id hanzo-app, body-keyed pending/slow_down handling.
- API key = the per-user IAM accessKey (hk-): read via /v1/get-account,
  self-minted via /v1/iam/mint-user-keys (authorized as self by the login JWT).
- CodingTarget abstraction: one interface, Claude Code (settings.json env) and
  Codex (config.toml provider) implementations. Verified round-trip preserves
  all unrelated user config.
- Commands: login, use/unuse, auth (status/key/rotate/revoke/logout),
  status, models, install (dev/mcp/extension), doctor.
- Endpoints overridable for white-label (HANZO_IAM_URL/API_URL/CLIENT_ID).
- TypeScript 6, tsup bundle, clean typecheck.
2026-06-29 13:57:59 -07:00