mirror of
https://github.com/hanzoai/helper.git
synced 2026-09-30 22:42:13 +00:00
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:
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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": {
|
||||
".": {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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 };
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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.'));
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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> {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
*/
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user