Purpose
Ship @nyuchi/mzizi-cli — the command-line tool for developers working with the Mzizi framework and any Mzizi-based project (the Nyuchi Design System, Fundi, external adopters' projects).
Naming rule (locked)
npm is infrastructure. Infrastructure is always Nyuchi. So the only npm scope used is @nyuchi. The package name after the slash carries the rest of the meaning — what the package works against, not who operates the publishing infrastructure.
@nyuchi/mzizi-cli — CLI for Mzizi
@nyuchi/mzizi-core — Mzizi framework primitives (when needed)
@nyuchi/bundu-tokens — Bundu canonical tokens, packaged for npm consumption
@nyuchi/fundi-sdk — Fundi client SDK
Same rule generalises to other infrastructure registries (PyPI, crates.io, container registries) — they all use the nyuchi namespace when Nyuchi operates the publish.
Depends on: #78, #79. Plays well with #80 but doesn't strictly require it.
Package details
- Name:
@nyuchi/mzizi-cli
- Binary:
mzizi (primary), nyuchi-mzizi (verbose alias for environments where mzizi collides)
- Runtime: Node.js ≥ 20
- Distribution: npm, public
- Versioning: starts at
0.1.0, follows Mzizi cadence
Commands
mzizi login
Walks the user through pasting a first-party token into a stored config file.
$ mzizi login
? Paste your first-party API key: ********************
✓ Stored in ~/.mzizi/credentials (mode 0600)
✓ Verifying with portal…
✓ Recognised as first-party: clientId=nyuchi-cli-bryan, brand=nyuchi
Verification step calls the whoami MCP tool. Failure flow on a junk token:
✗ Token not recognised. Body: {"authenticated": false}
The token was saved locally but you're not currently first-party.
Contact a portal admin to be added to the allow-list.
mzizi logout
Removes stored credentials.
mzizi whoami
Shells out to the whoami MCP tool.
$ mzizi whoami
authenticated: true
firstParty: true
clientId: nyuchi-cli-bryan
brand: nyuchi
For non-first-party: authenticated: false.
mzizi add <name> [...names]
Wraps shadcn@latest add with the bearer token attached. Works against the Mzizi resolver, so a component on Node 2 (primitive) gets fetched from its registered upstream (shadcn / shadcn-svelte / Material / crates.io / etc.) with any project-specific overrides applied at install time.
$ mzizi add nyuchi-fundi
✓ Adding nyuchi-fundi (node 9, registry:lib)
✓ Wrote lib/fundi/nyuchi-fundi.ts (8.2 KB)
mzizi search <query> [--node N]
Searches the registry through /api/v1/search with the auth header. Surfaces components visible to the current caller (first-party sees opt-in components; anon does not).
mzizi list --node N
Lists components in a given node (1–10) for the current caller.
mzizi convention [slug]
Prints a Bundu convention. With no slug, lists active conventions.
$ mzizi convention
ownership-convention Bundu ecosystem ownership convention v1.0.0
$ mzizi convention ownership-convention
[full text of the convention]
CLI surface for the get_bundu_convention / list_bundu_conventions MCP tools.
mzizi describe [tool-name]
Shells out to mcp_describe. With no tool name, prints the live catalogue grouped by category. With a tool name, prints the schema and gating rules for that tool. Subcommands are generated from the registry — adding a tool to mcp_tool_registry surfaces a new subcommand automatically (depends on #83 for auto-generation).
Credential storage
~/.mzizi/credentials # mode 0600
{
"token": "<raw bearer token>",
"portalUrl": "https://design.nyuchi.com",
"savedAt": "2026-04-28T..."
}
- Mode
0600 enforced on write.
- Override via
MZIZI_TOKEN env var (CI use case). Env wins over file.
- Override via
MZIZI_PORTAL_URL for staging.
- Token never echoed, logged, or visible in
--verbose output.
Auth header
Every CLI call attaches:
Authorization: Bearer <token>
If the upstream environment strips Authorization, the CLI also sends:
Matches #79's token-extraction priority.
Implementation notes
- TypeScript, compiled to single ESM bundle via
tsup.
- HTTP client: native
fetch.
- Arg parsing:
commander.
- Prompts:
@inquirer/prompts for login.
- No telemetry. If we want metrics later, prompt for opt-in.
- Repo location:
packages/mzizi-cli/ in the design-portal monorepo.
Acceptance criteria
Documentation
Out of scope
- Browser-based OAuth — future, when there's a portal user account system.
mzizi publish (component contribution) — future.
- Per-machine token rotation — future.
- Telemetry — explicitly never, unless opt-in.
Risks
- Bundle size. Target < 2 MB compressed. Tsup + tree-shaking; avoid heavy deps.
- shadcn version drift. Pin shadcn as a peer dep. Document supported range in README.
- Allow-list provisioning bottleneck. Until a self-service UI exists, new first-party developers need an admin to insert a row. Acceptable for v1; flagged in README.
Sequencing
Can ship in parallel with #80 — the CLI doesn't depend on requires_auth existing, only on whoami (#79) being live so login can verify tokens. If #80 isn't done yet, first-party features still work; they just don't have opt-in components to flex against.
Purpose
Ship
@nyuchi/mzizi-cli— the command-line tool for developers working with the Mzizi framework and any Mzizi-based project (the Nyuchi Design System, Fundi, external adopters' projects).Naming rule (locked)
npm is infrastructure. Infrastructure is always Nyuchi. So the only npm scope used is
@nyuchi. The package name after the slash carries the rest of the meaning — what the package works against, not who operates the publishing infrastructure.@nyuchi/mzizi-cli— CLI for Mzizi@nyuchi/mzizi-core— Mzizi framework primitives (when needed)@nyuchi/bundu-tokens— Bundu canonical tokens, packaged for npm consumption@nyuchi/fundi-sdk— Fundi client SDKSame rule generalises to other infrastructure registries (PyPI, crates.io, container registries) — they all use the
nyuchinamespace when Nyuchi operates the publish.Depends on: #78, #79. Plays well with #80 but doesn't strictly require it.
Package details
@nyuchi/mzizi-climzizi(primary),nyuchi-mzizi(verbose alias for environments wheremzizicollides)0.1.0, follows Mzizi cadenceCommands
mzizi loginWalks the user through pasting a first-party token into a stored config file.
Verification step calls the
whoamiMCP tool. Failure flow on a junk token:mzizi logoutRemoves stored credentials.
mzizi whoamiShells out to the
whoamiMCP tool.For non-first-party:
authenticated: false.mzizi add <name> [...names]Wraps
shadcn@latest addwith the bearer token attached. Works against the Mzizi resolver, so a component on Node 2 (primitive) gets fetched from its registered upstream (shadcn / shadcn-svelte / Material / crates.io / etc.) with any project-specific overrides applied at install time.mzizi search <query> [--node N]Searches the registry through
/api/v1/searchwith the auth header. Surfaces components visible to the current caller (first-party sees opt-in components; anon does not).mzizi list --node NLists components in a given node (1–10) for the current caller.
mzizi convention [slug]Prints a Bundu convention. With no slug, lists active conventions.
CLI surface for the
get_bundu_convention/list_bundu_conventionsMCP tools.mzizi describe [tool-name]Shells out to
mcp_describe. With no tool name, prints the live catalogue grouped by category. With a tool name, prints the schema and gating rules for that tool. Subcommands are generated from the registry — adding a tool tomcp_tool_registrysurfaces a new subcommand automatically (depends on #83 for auto-generation).Credential storage
0600enforced on write.MZIZI_TOKENenv var (CI use case). Env wins over file.MZIZI_PORTAL_URLfor staging.--verboseoutput.Auth header
Every CLI call attaches:
If the upstream environment strips
Authorization, the CLI also sends:Matches #79's token-extraction priority.
Implementation notes
tsup.fetch.commander.@inquirer/promptsforlogin.packages/mzizi-cli/in the design-portal monorepo.Acceptance criteria
npm install -g @nyuchi/mzizi-clisucceeds;mzizi --versionprints0.1.0.mzizi loginwrites~/.mzizi/credentialswith mode0600.mzizi loginverifies the token viawhoamibefore declaring success.mzizi logoutremoves the file.mzizi whoamicorrectly reports first-party / public status.mzizi add <public-component>works (parity withnpx shadcn add).mzizi add <opt-in-component>works only when first-party. Without auth: surfaces the 401reasonfield with the hint URL.mzizi searchandlistsee opt-in components when first-party, do not when public.mzizi conventionandmzizi convention <slug>work againstbundu_conventions.mzizi describeworks againstmcp_describe.MZIZI_TOKENenv var overrides the file.MZIZI_PORTAL_URLenv var overrides the default endpoint.whoamiagainst the live portal as anon.Documentation
packages/mzizi-cli/README.mdwith install, login, common commands./docs/clipage ondesign.nyuchi.com.Out of scope
mzizi publish(component contribution) — future.Risks
Sequencing
Can ship in parallel with #80 — the CLI doesn't depend on
requires_authexisting, only onwhoami(#79) being live sologincan verify tokens. If #80 isn't done yet, first-party features still work; they just don't have opt-in components to flex against.