[CLI Architecture & Features]
Detailed specification of the Hoox Command-Line Interface, monorepo workspaces compilation, and task-management engines.
The hoox CLI (packages/cli) is the unified lifecycle engine of the trading platform monorepo. It governs local sandboxes, compiles TypeScript structures, coordinates Cloudflare infrastructure resources, deploys edge isolates, manages encrypted secrets, and executes self-healing diagnostics.
Monorepo Workspace Design
The CLI is integrated into our monorepo using Bun Workspaces, which link local packages together. This design ensures that the CLI binary can resolve and load local shared types (@jango-blockchained/hoox-shared) and TUI components (packages/tui) instantly without network downloads or pre-compilation overhead:
hoox-setup/ (Monorepo Root)
├── packages/
│ ├── cli/ # CLI Source code (entry binary: bin/hoox.js)
│ ├── tui/ # OpenTUI dashboard source code
│ └── shared/ # Common libraries (auth, router, error models)
├── workers/
│ └── ... # Edge V8 isolates
└── package.json # Root workspace manager
1. Command-Line Core Architectures
The CLI binary parses terminal instructions using the following architectural layers:
A. Command Dispatcher (packages/cli/src/index.ts)
Intercepts all incoming arguments (e.g. hoox infra provision), evaluates global flags (--json, --quiet), validates configuration integrity, and delegates execution to target command modules under src/commands/.
B. Cloudflare API Adapters (src/adapters/)
Translates command intentions (like hoox infra d1 create) into parameterized Cloudflare API REST payloads, bypassing wrangler wrappers when high-performance execution is needed.
C. State Engine (src/core/)
Tracks active project profiles, enabled worker matrices, and workspace configuration formats (wrangler.jsonc vs. wrangler.toml).
2. Declarative Config Mapping & Validation
To prevent configuration drift, the CLI enforces strict type validation on wrangler.jsonc files:
- Config Interfaces: Built-in parsers validate configuration files against type-safe TypeScript interfaces (
ConfigandWorkerConfig) defined insrc/core/types.ts. - Setup Verification (
hoox check setup): Compares active workspace profiles against example files, audits environment variables keys, and scans for missing bindings, outputting formatted terminal reports.
3. Self-Healing & Diagnostics Engine
One of the CLI's most powerful features is its guided repair framework (hoox repair command groups):
- Diagnostic Probes: The
hoox repair checkcommand runs a 5-step checklist (verifying submodule checkouts, NPM/Bun package resolutions, TypeScript variables, Cloudflare zone links, and encrypted credentials). - Automated Recovery: If a missing resource is identified (e.g. a D1 database ID is bound in
wrangler.jsoncbut the database doesn't exist on your Cloudflare account), the repair engine prompts you and provisions it automatically:
# Provision missing Cloudflare bindings and repair system states
hoox repair infra
Tip
Every single command supports the --json global flag. This outputs
machine-parseable JSON payloads (e.g. hoox check health --json), allowing
you to integrate the CLI with external telemetry dashboards or alert scripts
effortlessly!
4. Output Framework (v0.9.0+)
The CLI's terminal output is built on a shared framework of small, focused primitives
that every command composes. The framework lives in packages/cli/src/utils/ and
spans five layers:
Theme tokens (utils/theme.ts)
A single source of truth for color and iconography. Refined in v0.9.0 to a modern-minimal aesthetic (zinc/slate text, single indigo-400 accent, de-saturated status colors). New tokens available to every command:
- Text scale:
theme.text(zinc-200),textMuted(zinc-400),textSubtle(zinc-500),textFaint(zinc-600) - Status:
success(emerald-400),error(rose-400),warning(amber-400),info(sky-400),accent(indigo-400) - Borders:
border(zinc-700),borderStrong(zinc-600) - Spinner: braille dots
["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"]
All previous named tokens (success, error, heading, value, etc.) are
preserved for backward compatibility — only the values changed.
Output formatters (utils/formatters.ts)
Every command uses one of these for consistent output:
| Formatter | Purpose | Key options |
|---|---|---|
formatSuccess(msg) | Single-line success indicator | --json / --quiet |
formatError(err, opts?) | Card-style error with [code] badge, did you mean suggestion | suggestions?, inCard? |
formatTable(rows, opts?) | Box-drawn table | zebra, alignNumbers, colorizeStatus, compact |
formatKeyValue(pairs) | Aligned key: value pairs | — |
formatHeader(text, opts?) | Section heading with rule | subtitle? |
formatList(items) | Bulleted list | — |
formatJson(data) | Always-JSON output | — |
formatBadge(level, text?) | Inline status chip | — |
formatHint(text) | Subtle hint line | — |
formatCompletion(msg, opts?) | " Done in 1.2s" footer + next-step suggestion | durationMs?, suggestion? |
formatNumber(n) / formatBytes(n) | Compact notation (1.2K / 1.5M / 1.0 KiB) | — |
Rich mode gate (utils/format-mode.ts)
isRichMode(opts) is the single switch every formatter checks before
emitting color. It returns false (i.e. suppresses color) when any of these is true:
--jsonor--quietflag is set--no-colorflag is setNO_COLORenv var is set (https://no-color.org)TERM=dumbis set- stdout is not a TTY (piped, redirected, or running under CI)
This is the single place that encodes "is rich output appropriate right now?" — every formatter asks it instead of duplicating TTY/env detection.
Custom help formatter (utils/help-formatter.ts)
Replaces Commander's default flat help layout with a sectioned modern-minimal
layout for hoox --help and per-command --help:
hoox deploy all
Cloudflare Workers Platform
───────────────────────────────────────────────────
Usage
hoox deploy all [options]
Options
--auto Skip confirmations
--json Output JSON
Examples
$ hoox deploy all
$ hoox deploy all --auto
Wired into the program via program.configureHelp({ formatHelp: (cmd, helper) => renderHelp(cmd, helper) }).
"Did you mean" + completion footer (utils/completion.ts, utils/error-handler.ts)
Two small touches that improve UX on errors and after successful commands:
- Did you mean —
hoox deplpy→did you mean 'hoox deploy' ?. Uses Levenshtein distance with a threshold of 2; checks against all registered command names (top-level + nested). - Completion footer — every successful command prints
<message> in 1.2sand optionally→ next: hoox <next-command> (<reason>). Wired into the globalprogram.hook("postAction", ...)inindex.ts.
Banner (ui/banner.ts)
renderBanner() is called when the CLI runs with no arguments. The version is
read at module init by walking up from import.meta.url looking for the
@jango-blockchained/hoox-cli package.json — this works in source, bundle,
and global install layouts. Default variant is minimal (the cleanest of four);
legacy, horizon, and signal are opt-ins.
Adding a new output
When writing a new command, the pattern is:
import {
formatSuccess,
formatTable,
formatHint,
getFormatOptions,
} from "../../utils/formatters.js";
import { Command } from "commander";
export function registerMyCommand(program: Command) {
program.command("my").action(
withErrorHandling(async (cmd) => {
const opts = getFormatOptions(cmd);
const rows = await loadMyData();
formatTable(rows, opts); // respects --json / --quiet / --no-color
formatSuccess("Done", opts); // suppressed in --json/--quiet
formatHint("next: hoox deploy", opts);
})
);
}
Every formatter handles the format modes for you — you never read
process.stdout.isTTY or process.env.NO_COLOR yourself.
Next Steps
- CLI Reference Manual — Review the complete command tree, positional arguments, and flags.
- Wrangler Setup & Tooling — Configure Wrangler to bind local D1 and KV instances for dev testing.