helper: the command is hanzo-helper — only the native binary is hanzo

@hanzo/[email protected] declared `"bin": {"hanzo": "dist/cli.js"}`, so
`npm i -g @hanzo/helper` put a second program named `hanzo` on PATH next to the
Hanzo CLI (v1.9.18, from hanzo.sh / brew). Whichever came first on PATH won, and
the two disagree about every verb: in the real CLI signing in is
`hanzo auth login`, and a bare `hanzo login` is swallowed as an AI task.

Renamed to `hanzo-helper`, and the same for the white-label builds:
lux-helper / zoo-helper / zen-helper. @hanzo/kms keeps `kms` — no collision.
Nothing is unpublished; 1.0.7 stays on npm.

The README's command table was the old bin name throughout, and its
"smart tiers" table documented `zen-auto` / `zen-normal` / `zen-pro` /
`zen-max` / `zen-code` / `zen-agent` as models you can ask for. The live
catalog has none of them — the authenticated /v1/models returns 105 ids whose
Zen family is zen5, zen5-coder, zen5-flash, zen5-mini, zen5-pro, enso,
enso-flash, enso-ultra plus the zen-<modality> models. Table cut; the README now
says to read the catalog. (`models.ts` already checks aliases against the live
catalog before printing them, so the code was honest and only the prose was not.)
`use --model` help stopped advertising the same six words.

In-program prose said `hanzo login` / `hanzo status` / `hanzo kms` in 15 files —
all now `hanzo-helper`, verified by running the built CLI.

Also dropped "every model (Claude, GLM, GPT, DeepSeek, Kimi, ...)" from the
opening: we describe our own catalog. Naming Claude Code and Codex stays — this
program's whole job is configuring them, which is a fact about the tool, not a
benchmark.

Left alone, for the model-routing owner: DEFAULT_MODEL is still the upstream id
`glm-5.2`, which commander prints as the advertised default of `--model`.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-08-01 13:38:01 -07:00
co-authored by Hanzo Dev
parent 09a6ade307
commit ccdef7d8fb
25 changed files with 182 additions and 137 deletions
+60 -57
View File
@@ -1,12 +1,12 @@
# @hanzo/helper
> Sign in to Hanzo and use its AI models in Claude Code, Codex, and other coding tools.
> Sign in to Hanzo and point your coding tools at Hanzo Cloud.
One command points your coding tool at [Hanzo Cloud](https://hanzo.ai): browser
device login, an API key minted for you, and the tool configured to talk to
`api.hanzo.ai` — which speaks both the OpenAI (`/v1/chat/completions`) and
Anthropic (`/v1/messages`) protocols, so every model (Claude, GLM, GPT,
DeepSeek, Kimi, …) works in tools built for either.
One command does browser device login, mints an `hk-` API key for you, and writes
the config your coding tools read. `api.hanzo.ai` answers on both the
`/v1/chat/completions` and `/v1/messages` shapes, so a tool built for either
works against the whole Hanzo catalog — the Zen family (`zen5`, `zen5-coder`,
`enso`, …) and every model your key can route to.
## Quick start
@@ -21,69 +21,69 @@ That will:
3. Let you pick a default model.
4. Configure the coding tools you choose.
Then just run your tool — it's already talking to Hanzo:
Then run your tool — it is already talking to Hanzo.
## The command is `hanzo-helper`, not `hanzo`
`hanzo` is the [Hanzo CLI](https://hanzo.sh), a native binary with a command
group per Hanzo Cloud product. This package installs `hanzo-helper` so the two
never shadow each other on PATH. (In the CLI, signing in is `hanzo auth login`; a
bare `hanzo login` is read there as an AI task.)
```bash
claude # Claude Code → Hanzo Cloud
codex # Codex → Hanzo Cloud
npm i -g @hanzo/helper
hanzo-helper login
```
## Commands
| Command | What it does |
| --- | --- |
| `hanzo login` | Device login, mint API key, configure tools |
| `hanzo use [tool]` | Point a tool at Hanzo using your saved key |
| `hanzo unuse [tool]` | Detach a tool from Hanzo (keep its other settings) |
| `hanzo status` | Session + every tool's configuration state |
| `hanzo models` | List models available to your key |
| `hanzo auth status` | Who you're signed in as |
| `hanzo auth key [--reveal]` | Show your current API key |
| `hanzo auth rotate` | Mint a fresh API key (old one stops working) |
| `hanzo auth revoke` | Revoke your API key |
| `hanzo auth logout` | Clear local credentials |
| `hanzo models --tiers` | Show the smart tiers (effort words → cloud aliases) |
| `hanzo kms pull` | Pull env secrets from KMS for local dev (also `kms`) |
| `hanzo install [parts…]` | Set up the ecosystem (dev, mcp, node, apps, …) |
| `hanzo doctor` | Diagnose connectivity and tool configuration |
| `hanzo-helper login` | Device login, mint API key, configure tools |
| `hanzo-helper use [tool]` | Point a tool at Hanzo using your saved key |
| `hanzo-helper unuse [tool]` | Detach a tool from Hanzo (keep its other settings) |
| `hanzo-helper status` | Session + every tool's configuration state |
| `hanzo-helper models` | List models available to your key |
| `hanzo-helper auth status` | Who you're signed in as |
| `hanzo-helper auth key [--reveal]` | Show your current API key |
| `hanzo-helper auth rotate` | Mint a fresh API key (the old one stops working) |
| `hanzo-helper auth revoke` | Revoke your API key |
| `hanzo-helper auth logout` | Clear local credentials |
| `hanzo-helper kms pull` | Pull env secrets from KMS for local dev (also `kms`) |
| `hanzo-helper install [parts…]` | Set up the ecosystem (dev, mcp, node, apps, …) |
| `hanzo-helper doctor` | Diagnose connectivity and tool configuration |
Bare `hanzo-helper` runs login if you are signed out, and status if you are not.
## Choosing a model
The catalog is read live from `api.hanzo.ai/v1/models` — nothing is hardcoded, so
new models appear without a release here.
```bash
hanzo-helper models # the live catalog for your key
hanzo-helper use claude-code --model zen5-coder
```
`--model` takes any id the catalog returns.
### Secrets for local dev (`kms`)
One login, one mechanism. Your `hanzo login` mints an IAM OIDC token; `kms`
exchanges it for a short-lived KMS token and reads an environment's secrets.
KMS owns secrets, envs and authz (`/v1/kms/*`); IAM only issues the token
(`/v1/iam/*`) — they compose through the token, nothing braided.
One login, one mechanism. Your login mints an IAM OIDC token; `kms` exchanges it
for a short-lived KMS token and reads an environment's secrets. KMS owns secrets,
envs and authz (`/v1/kms/*`); IAM only issues the token (`/v1/iam/*`) — they
compose through the token, nothing braided.
```bash
kms pull --env devnet # write .env for local dev (also: hanzo kms pull)
kms pull --env devnet # write .env for local dev (also: hanzo-helper kms pull)
kms list --env devnet # secret names only, no values
kms pull --env testnet --out - # print to stdout
```
Environments: `devnet` (default), `testnet`, `mainnet`, `production`. CI uses
the *same* `/v1/kms/*` exchange with a GitHub OIDC token — see
Environments: `devnet` (default), `testnet`, `mainnet`, `production`. CI uses the
*same* `/v1/kms/*` exchange with a GitHub OIDC token — see
`.github/actions/kms-secrets` and the reusable `.github/workflows/npm-release.yml`.
### Smart tiers
The catalog is read live from `api.hanzo.ai/v1/models` — nothing is hardcoded.
Beyond concrete ids (`glm-5.2`, `deepseek-v4-pro`, …) you can ask for an
**effort word** and let the cloud pick the model:
| Word | Routes to | |
| --- | --- | --- |
| `auto` | `zen-auto` | the cloud chooses (recommended default) |
| `fast` | `zen-normal` | quick, everyday |
| `high` | `zen-pro` | stronger reasoning & coding |
| `max` | `zen-max` | top tier (needs credits) |
| `code` | `zen-code` | coding-specialised |
| `agent`| `zen-agent` | agentic |
```bash
hanzo use claude-code --model high # or auto / fast / max / glm-5.2 …
hanzo models # full live catalog for your key
```
### Supported coding tools
- **Claude Code** — adds a `providers.hanzo` block to `~/.claude/settings.json`
@@ -95,14 +95,14 @@ hanzo models # full live catalog for your key
### The whole ecosystem
```bash
hanzo install # interactive checklist (core tools pre-checked)
hanzo install dev mcp # CLI agent + MCP server (npm)
hanzo install list # everything available
hanzo-helper install # interactive checklist (core tools pre-checked)
hanzo-helper install dev mcp # CLI agent + MCP server (npm)
hanzo-helper install list # everything available
```
| Part | Kind | |
| --- | --- | --- |
| `dev` | npm | `@hanzo/dev` — CLI coding agent (`code`) |
| `dev` | npm | `@hanzo/dev` — CLI coding agent |
| `mcp` | npm | `@hanzo/mcp` — MCP server (tools, browser, cloud) |
| `node` | guide | local inference node (bundles the engine) |
| `desktop` | guide | desktop app + the Enso browser |
@@ -114,7 +114,7 @@ hanzo install list # everything available
## How it works
```
hanzo login
hanzo-helper login
│
├── device login ─────────────▶ hanzo.id (RFC 8628; proxies to iam.hanzo.ai)
│ POST /oauth/device → user_code + verification_uri
@@ -127,8 +127,8 @@ hanzo install list # everything available
~/.codex/config.toml
│
your coding tool ──────────────────▶ api.hanzo.ai
OpenAI /v1/chat/completions (one key, every model)
Anthropic /v1/messages
/v1/chat/completions (one key, every model)
/v1/messages
```
### Self-hosted / white-label
@@ -141,6 +141,9 @@ Point the CLI at a different deployment with environment variables:
| `HANZO_API_URL` | `https://api.hanzo.ai` | Cloud API (keys, inference) |
| `HANZO_CLIENT_ID` | `hanzo-app` | OAuth client id (e.g. `lux-app`) |
The same build ships as `@luxfi/helper` (`lux-helper`), `@zooai/helper`
(`zoo-helper`) and `@zenlm/helper` (`zen-helper`) with that brand's defaults.
## Configuration
`~/.hanzo/config.json` (mode `0600`) holds your login token, API key, and
+21 -8
View File
@@ -1,15 +1,28 @@
# @luxfi/helper
> Sign in to Lux and use its AI models in Claude Code, Codex, and more.
> Sign in to Lux and point your coding tools at the Lux AI cloud.
```bash
npx @luxfi/helper
npx @luxfi/helper login
```
The Lux-branded build of [`@hanzo/helper`](https://github.com/hanzoai/helper) —
identical engine, Lux defaults (`lux.id`, `api.lux.network`, `lux-app`). One
command does browser device login, mints your Lux API key, and points your
coding tools at the Lux AI cloud.
One command does browser device login, mints your Lux API key, and writes the
config your coding tools read.
See the [upstream README](https://github.com/hanzoai/helper) for the full
command reference. License: Apache-2.0.
The Lux-branded build of [`@hanzo/helper`](https://www.npmjs.com/package/@hanzo/helper) —
identical engine, Lux defaults (`lux.id`, `api.lux.network`, `lux-app`).
## The command is `lux-helper`
`lux` is the Lux CLI, a different program. Installing this package gives you
`lux-helper`, so the two never shadow each other on PATH.
```bash
npm i -g @luxfi/helper
lux-helper login
lux-helper status
lux-helper models
```
See the [upstream README](https://github.com/hanzoai/helper) for the full command reference.
License: Apache-2.0.
+4 -4
View File
@@ -1,10 +1,10 @@
{
"name": "@luxfi/helper",
"version": "1.0.6",
"description": "Lux CLI helper — sign in to Lux and use its AI models in Claude Code, Codex, and more",
"version": "1.0.7",
"description": "Lux CLI helper \u2014 sign in to Lux and use its AI models in Claude Code, Codex, and more",
"type": "module",
"bin": {
"lux": "bin/lux.js"
"lux-helper": "bin/lux.js"
},
"files": [
"bin",
@@ -28,6 +28,6 @@
},
"homepage": "https://lux.network",
"dependencies": {
"@hanzo/helper": "^1.0.6"
"@hanzo/helper": "^1.0.8"
}
}
+21 -8
View File
@@ -1,15 +1,28 @@
# @zenlm/helper
> Sign in to Zen and use its AI models in Claude Code, Codex, and more.
> Sign in to Zen and point your coding tools at the Zen AI cloud.
```bash
npx @zenlm/helper
npx @zenlm/helper login
```
The Zen-branded build of [`@hanzo/helper`](https://github.com/hanzoai/helper) —
identical engine, Zen defaults (`id.zenlm.org`, `api.zenlm.org`, `zen-app`). One
command does browser device login, mints your Zen API key, and points your
coding tools at the Zen AI cloud.
One command does browser device login, mints your Zen API key, and writes the
config your coding tools read.
See the [upstream README](https://github.com/hanzoai/helper) for the full
command reference. License: Apache-2.0.
The Zen-branded build of [`@hanzo/helper`](https://www.npmjs.com/package/@hanzo/helper) —
identical engine, Zen defaults (`id.zenlm.org`, `api.zenlm.org`, `zen-app`).
## The command is `zen-helper`
`zen` is the Zen CLI, a different program. Installing this package gives you
`zen-helper`, so the two never shadow each other on PATH.
```bash
npm i -g @zenlm/helper
zen-helper login
zen-helper status
zen-helper models
```
See the [upstream README](https://github.com/hanzoai/helper) for the full command reference.
License: Apache-2.0.
+4 -4
View File
@@ -1,10 +1,10 @@
{
"name": "@zenlm/helper",
"version": "1.0.6",
"description": "Zen CLI helper — sign in to Zen and use its AI models in Claude Code, Codex, and more",
"version": "1.0.7",
"description": "Zen CLI helper \u2014 sign in to Zen and use its AI models in Claude Code, Codex, and more",
"type": "module",
"bin": {
"zen": "bin/zen.js"
"zen-helper": "bin/zen.js"
},
"files": [
"bin",
@@ -29,6 +29,6 @@
},
"homepage": "https://zenlm.org",
"dependencies": {
"@hanzo/helper": "^1.0.6"
"@hanzo/helper": "^1.0.8"
}
}
+21 -8
View File
@@ -1,15 +1,28 @@
# @zooai/helper
> Sign in to Zoo and use its AI models in Claude Code, Codex, and more.
> Sign in to Zoo and point your coding tools at the Zoo AI cloud.
```bash
npx @zooai/helper
npx @zooai/helper login
```
The Zoo-branded build of [`@hanzo/helper`](https://github.com/hanzoai/helper) —
identical engine, Zoo defaults (`zoolabs.id`, `api.zoo.ngo`, `zoo-app`). One
command does browser device login, mints your Zoo API key, and points your
coding tools at the Zoo AI cloud.
One command does browser device login, mints your Zoo API key, and writes the
config your coding tools read.
See the [upstream README](https://github.com/hanzoai/helper) for the full
command reference. License: Apache-2.0.
The Zoo-branded build of [`@hanzo/helper`](https://www.npmjs.com/package/@hanzo/helper) —
identical engine, Zoo defaults (`zoolabs.id`, `api.zoo.ngo`, `zoo-app`).
## The command is `zoo-helper`
`zoo` is the Zoo CLI, a different program. Installing this package gives you
`zoo-helper`, so the two never shadow each other on PATH.
```bash
npm i -g @zooai/helper
zoo-helper login
zoo-helper status
zoo-helper models
```
See the [upstream README](https://github.com/hanzoai/helper) for the full command reference.
License: Apache-2.0.
+4 -4
View File
@@ -1,10 +1,10 @@
{
"name": "@zooai/helper",
"version": "1.0.6",
"description": "Zoo CLI helper — sign in to Zoo and use its AI models in Claude Code, Codex, and more",
"version": "1.0.7",
"description": "Zoo CLI helper \u2014 sign in to Zoo and use its AI models in Claude Code, Codex, and more",
"type": "module",
"bin": {
"zoo": "bin/zoo.js"
"zoo-helper": "bin/zoo.js"
},
"files": [
"bin",
@@ -28,6 +28,6 @@
},
"homepage": "https://zoo.ngo",
"dependencies": {
"@hanzo/helper": "^1.0.6"
"@hanzo/helper": "^1.0.8"
}
}
+3 -3
View File
@@ -1,11 +1,11 @@
{
"name": "@hanzo/helper",
"version": "1.0.7",
"description": "Hanzo CLI helper for API access, cloud services, MCP, and plugins",
"version": "1.0.8",
"description": "Sign in to Hanzo and point Claude Code, Codex and other coding tools at Hanzo Cloud",
"type": "module",
"main": "./dist/index.js",
"bin": {
"hanzo": "dist/cli.js"
"hanzo-helper": "dist/cli.js"
},
"exports": {
".": {
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@hanzo/kms",
"version": "1.0.6",
"description": "Standalone `kms` CLI — sign in with IAM and pull environment secrets for local dev",
"version": "1.0.7",
"description": "Standalone `kms` CLI \u2014 sign in with IAM and pull environment secrets for local dev",
"type": "module",
"bin": {
"kms": "bin/kms.js"
@@ -31,6 +31,6 @@
},
"homepage": "https://hanzo.ai",
"dependencies": {
"@hanzo/helper": "^1.0.6"
"@hanzo/helper": "^1.0.8"
}
}
+4 -1
View File
@@ -18,8 +18,11 @@ import { version } from './lib/version';
const program = new Command();
// `hanzo` is the Hanzo CLI (a native binary, curl -fsSL https://hanzo.sh | sh).
// This program is `hanzo-helper`. Two programs under one name is how `hanzo
// login` came to mean different things depending on install order.
program
.name(brand.bin)
.name(`${brand.bin}-helper`)
.description(`Sign in to ${brand.name} and use its AI models in Claude Code, Codex, and more`)
.version(version);
+6 -6
View File
@@ -1,5 +1,5 @@
/**
* `hanzo auth` — inspect or clear the saved session, and manage the `hk-` key.
* `hanzo-helper auth` — inspect or clear the saved session, and manage the `hk-` key.
*
* Hanzo issues ONE per-user Cloud API key (the IAM accessKey). There is no list
* of named keys; you read it, rotate it, or revoke it.
@@ -17,7 +17,7 @@ export const authCmd = new Command('auth').description('Manage your Hanzo sessio
authCmd
.command('login')
.description('Sign in with IAM (device login) — same session as `hanzo login`')
.description('Sign in with IAM (device login) — same session as `hanzo-helper login`')
.option('--no-browser', 'Do not open the browser automatically')
.action(async (opts: { browser: boolean }) => {
try {
@@ -35,7 +35,7 @@ authCmd
.action(async () => {
const { user, apiKey, accessToken } = await getConfig();
if (!apiKey && !accessToken) {
console.log(chalk.yellow('Not signed in. Run `hanzo login`.'));
console.log(chalk.yellow('Not signed in. Run `hanzo-helper login`.'));
process.exit(1);
}
console.log(chalk.green('✓ Signed in'));
@@ -65,7 +65,7 @@ authCmd
const key = await readApiKey(token);
spinner.stop();
if (!key) {
console.log(chalk.yellow('No API key yet. Create one with `hanzo auth rotate`.'));
console.log(chalk.yellow('No API key yet. Create one with `hanzo-helper auth rotate`.'));
return;
}
console.log(opts.reveal ? key : maskKey(key));
@@ -86,7 +86,7 @@ authCmd
await setConfig((c) => ({ ...c, apiKey: key }));
spinner.succeed(chalk.green('New API key minted'));
console.log(chalk.bold(key));
console.log(chalk.dim('Saved locally and shown once. Re-run `hanzo use` to update your tools.'));
console.log(chalk.dim('Saved locally and shown once. Re-run `hanzo-helper use` to update your tools.'));
} catch (err) {
spinner.fail(chalk.red(err instanceof Error ? err.message : String(err)));
process.exit(1);
@@ -111,7 +111,7 @@ authCmd
async function requireToken(): Promise<string> {
const { accessToken } = await getConfig();
if (!accessToken) {
console.error(chalk.red('Not signed in. Run `hanzo login` first.'));
console.error(chalk.red('Not signed in. Run `hanzo-helper login` first.'));
process.exit(1);
}
return accessToken;
+1 -1
View File
@@ -28,7 +28,7 @@ export const doctorCmd = new Command('doctor')
checks.push({
name: 'Session',
pass: Boolean(apiKey),
detail: apiKey ? `signed in${user ? ` as ${user.name}` : ''}` : 'run `hanzo login`',
detail: apiKey ? `signed in${user ? ` as ${user.name}` : ''}` : 'run `hanzo-helper login`',
});
const configured = TARGETS.filter((t) => t.status().configured).map((t) => t.displayName);
+3 -3
View File
@@ -1,9 +1,9 @@
/**
* `hanzo install [components...]` — set up the Hanzo ecosystem.
* `hanzo-helper install [components...]` — set up the Hanzo ecosystem.
* no args, interactive → pick from a checklist (core tools pre-checked)
* no args, non-interactive → install the core tools (dev, mcp)
* named → install exactly those
* `hanzo install list` → show everything available
* `hanzo-helper install list` → show everything available
*/
import { Command } from 'commander';
@@ -22,7 +22,7 @@ export const installCmd = new Command('install')
.action(async (ids: string[]) => {
const chosen = ids.length > 0 ? resolveIds(ids) : await pickComponents();
await installComponents(chosen);
if (chosen.length > 0) console.log(chalk.dim('\n Done. `hanzo install list` shows the rest.'));
if (chosen.length > 0) console.log(chalk.dim('\n Done. `hanzo-helper install list` shows the rest.'));
});
installCmd
+5 -5
View File
@@ -1,11 +1,11 @@
/**
* `hanzo kms` (also installed as the standalone `kms` command) — pull
* `hanzo-helper kms` (also installed as the standalone `kms` command) — pull
* environment secrets from KMS for local dev, using your existing IAM login.
*
* kms pull [--env devnet] [--org <org>] [--out .env] write a dotenv file
* kms list [--env devnet] [--org <org>] names only (no values)
*
* Auth is your `hanzo login` session — one login, one token store. Your org
* Auth is your `hanzo-helper login` session — one login, one token store. Your org
* comes from that login (override with --org). KMS decides what you may read
* per env; this is just the client.
*/
@@ -20,7 +20,7 @@ import { listSecrets, pullSecrets, KMS_ENVS, KMS_PROD_ENVS, KmsError } from '../
const DEFAULT_ENV = 'devnet';
export const kmsCmd = new Command('kms')
.description('Pull environment secrets from KMS for local dev (uses your hanzo login)');
.description('Pull environment secrets from KMS for local dev (uses your hanzo-helper login)');
kmsCmd
.command('pull')
@@ -60,12 +60,12 @@ kmsCmd
async function session(orgOverride?: string): Promise<{ token: string; org: string }> {
const cfg = await getConfig();
if (!cfg.accessToken) {
console.error(chalk.red('Not signed in. Run `kms login` (or `hanzo login`) first.'));
console.error(chalk.red('Not signed in. Run `kms login` (or `hanzo-helper login`) first.'));
process.exit(1);
}
const org = orgOverride ?? cfg.user?.org;
if (!org) {
console.error(chalk.red('No organization found. Pass --org <org> or run `hanzo login` again.'));
console.error(chalk.red('No organization found. Pass --org <org> or run `hanzo-helper login` again.'));
process.exit(1);
}
return { token: cfg.accessToken, org };
+3 -3
View File
@@ -1,5 +1,5 @@
/**
* `hanzo login` — the one command that does everything:
* `hanzo-helper login` — the one command that does everything:
* 1. Device login against hanzo.id (no password typed into the terminal).
* 2. Mint (or reuse) a Hanzo API key.
* 3. Pick a default model.
@@ -77,7 +77,7 @@ export async function runLogin(opts: LoginOptions): Promise<void> {
const targets = await resolveTargets(opts);
if (targets.length === 0) {
console.log(chalk.yellow('\nNo coding tools selected. Nothing configured.'));
console.log(chalk.dim('Your API key is saved; run `hanzo use <tool>` later.'));
console.log(chalk.dim('Your API key is saved; run `hanzo-helper use <tool>` later.'));
return;
}
@@ -269,7 +269,7 @@ async function maybeOfferEcosystem(opts: LoginOptions): Promise<void> {
},
]);
if (!go) {
console.log(chalk.dim(' Later: `hanzo install`'));
console.log(chalk.dim(' Later: `hanzo-helper install`'));
return;
}
await installComponents(await pickComponents());
+2 -2
View File
@@ -36,7 +36,7 @@ export const modelsCmd = new Command('models')
.action(async (name: string | undefined, opts: { all?: boolean; tiers?: boolean }) => {
const { apiKey } = await getConfig();
if (!apiKey) {
console.error(chalk.red('Not signed in. Run `hanzo login` first.'));
console.error(chalk.red('Not signed in. Run `hanzo-helper login` first.'));
process.exit(1);
}
@@ -144,7 +144,7 @@ async function showTiers(apiKey: string): Promise<void> {
const ok = live.has(alias) ? chalk.green('●') : chalk.dim('○');
console.log(` ${ok} ${chalk.bold(word.padEnd(7))} → ${alias}`);
}
console.log(chalk.dim('\n Use anywhere a model is asked for: `hanzo use --model high`'));
console.log(chalk.dim('\n Use anywhere a model is asked for: `hanzo-helper use --model high`'));
console.log(chalk.dim(' ● = live in your catalog. The alias is a real id; the cloud routes it.'));
}
+2 -2
View File
@@ -1,5 +1,5 @@
/**
* `hanzo status` — one screen showing the session and every coding tool's state.
* `hanzo-helper status` — one screen showing the session and every coding tool's state.
*/
import { Command } from 'commander';
@@ -22,7 +22,7 @@ export async function runStatus(): Promise<void> {
console.log(chalk.dim(` key ${maskKey(apiKey)}`));
console.log(chalk.dim(` api ${endpoints.api}`));
} else {
console.log(` ${chalk.yellow('○')} not signed in — run ${chalk.cyan('hanzo login')}`);
console.log(` ${chalk.yellow('○')} not signed in — run ${chalk.cyan('hanzo-helper login')}`);
}
console.log(chalk.bold('\n Coding tools'));
+4 -4
View File
@@ -1,6 +1,6 @@
/**
* `hanzo use <tool>` / `hanzo unuse <tool>` — point an already-installed coding
* tool at Hanzo (or detach it) using the API key saved by `hanzo login`.
* `hanzo-helper use <tool>` / `hanzo-helper unuse <tool>` — point an already-installed coding
* tool at Hanzo (or detach it) using the API key saved by `hanzo-helper login`.
*/
import { Command } from 'commander';
@@ -13,11 +13,11 @@ import { TARGETS, getTarget, codexEnvHint } from '../targets';
export const useCmd = new Command('use')
.description('Point a coding tool at Hanzo using your saved API key')
.argument('[tool]', 'Tool id (claude-code, codex). Omit to apply to all installed tools.')
.option('--model <id|tier>', 'Model id or effort (auto, fast, high, max, code, agent)', DEFAULT_MODEL)
.option('--model <id>', 'Model id from the live catalog (`hanzo-helper models`)', DEFAULT_MODEL)
.action(async (tool: string | undefined, opts: { model: string }) => {
const { apiKey } = await getConfig();
if (!apiKey) {
console.error(chalk.red('Not signed in. Run `hanzo login` first.'));
console.error(chalk.red('Not signed in. Run `hanzo-helper login` first.'));
process.exit(1);
}
+2 -2
View File
@@ -3,7 +3,7 @@
* Standalone `kms` command — pull environment secrets for local dev.
*
* Self-sufficient: `kms login` signs in via IAM (the same device flow and the
* same ~/.hanzo/config.json token store as `hanzo login`), so `kms pull` works
* same ~/.hanzo/config.json token store as `hanzo-helper login`), so `kms pull` works
* whether you signed in through `kms` or `hanzo`. One flow, one token store.
*/
@@ -19,7 +19,7 @@ const program = new Command('kms')
program
.command('login')
.description('Sign in with IAM (device login) — shared with `hanzo login`')
.description('Sign in with IAM (device login) — shared with `hanzo-helper login`')
.option('--no-browser', 'Do not open the browser automatically')
.action(async (opts: { browser: boolean }) => {
try {
+1 -1
View File
@@ -66,7 +66,7 @@ export async function revokeApiKey(accessToken: string): Promise<void> {
/**
* Return a usable `hk-` key: reuse the account's existing one, else mint a new
* one. Reading first means re-running `hanzo login` does not rotate (and break)
* one. Reading first means re-running `hanzo-helper login` does not rotate (and break)
* a key already wired into the user's coding tools.
*/
export async function ensureApiKey(accessToken: string): Promise<string> {
+2 -2
View File
@@ -72,7 +72,7 @@ export const COMPONENTS: readonly Component[] = [
steps: [
'Download the node for your platform from the link above.',
'Run it once to start the local engine (serves an OpenAI-compatible API).',
'Point a tool at it with `hanzo use --model <id>` once it is running.',
'Point a tool at it with `hanzo-helper use --model <id>` once it is running.',
],
},
{
@@ -107,7 +107,7 @@ export const COMPONENTS: readonly Component[] = [
steps: [
'VS Code → search "Hanzo" in the Extensions marketplace.',
'JetBrains → search "Hanzo" in Settings → Plugins → Marketplace.',
'Sign in with your API key (saved by `hanzo login`) when prompted.',
'Sign in with your API key (saved by `hanzo-helper login`) when prompted.',
],
},
{
+2 -2
View File
@@ -119,7 +119,7 @@ export async function pollForToken(
case 'access_denied':
throw new DeviceAuthError('Login was denied.');
case 'expired_token':
throw new DeviceAuthError('Login code expired. Please run `hanzo login` again.');
throw new DeviceAuthError('Login code expired. Please run `hanzo-helper login` again.');
case undefined:
throw new DeviceAuthError(`Login failed (${res.status} ${res.statusText})`);
default:
@@ -127,7 +127,7 @@ export async function pollForToken(
}
}
throw new DeviceAuthError('Login timed out. Please run `hanzo login` again.');
throw new DeviceAuthError('Login timed out. Please run `hanzo-helper login` again.');
}
/**
+1 -1
View File
@@ -37,7 +37,7 @@ const base = (org: string) => `${endpoints.kms}/v1/kms/orgs/${encodeURIComponent
const authFail = (res: Response, what: string): KmsError =>
res.status === 401 || res.status === 403
? new KmsError(`KMS denied ${what} (${res.status}). Run \`hanzo login\` to refresh, or check your org access.`)
? new KmsError(`KMS denied ${what} (${res.status}). Run \`hanzo-helper login\` to refresh, or check your org access.`)
: new KmsError(`KMS ${what} failed (${res.status} ${res.statusText})`);
/** List an env's secret keys (no values) for the org. */
+2 -2
View File
@@ -1,11 +1,11 @@
/**
* Device sign-in — the one IAM login primitive, shared by every entry point
* (`hanzo login`, `hanzo auth login`, `kms login`). It runs the RFC 8628 device
* (`hanzo-helper login`, `hanzo-helper auth login`, `kms login`). It runs the RFC 8628 device
* flow against hanzo.id, resolves the user, and persists the access token +
* identity to the shared ~/.hanzo/config.json. One token store, one flow.
*
* It deliberately does NOT mint an API key or configure tools — that is
* `hanzo login`'s job on top of this. A caller that only needs an IAM session
* `hanzo-helper login`'s job on top of this. A caller that only needs an IAM session
* (e.g. `kms` reading secrets) uses this alone.
*/
+1 -1
View File
@@ -86,7 +86,7 @@ export const codex: CodingTarget = {
};
/**
* The env line that makes the key available to Codex. `hanzo login` prints this
* The env line that makes the key available to Codex. `hanzo-helper login` prints this
* so users can add it to their shell rc; sourcing ~/.hanzo/env also works.
*/
export function codexEnvHint(): string {