UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

139 lines (90 loc) 7.02 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Solo (`@hiero-ledger/solo`) is a CLI tool for deploying and managing private Hedera Networks on Kubernetes. It orchestrates consensus nodes, mirror nodes, block explorers, and JSON-RPC relays via Helm charts on Kind clusters. - **Language:** TypeScript (ES2022, ESM) - **Runtime:** Node.js >= 22.0.0 - **CLI Framework:** Yargs with Listr2 for task execution ## Common Commands All task commands use [Task](https://taskfile.dev/) (`task`): ```bash # Install dependencies npm install # Build (compile TypeScript + lint) task build # Compile only task build:compile # Run unit tests with coverage task test # Auto-fix lint/formatting issues (run before committing) task format # List all available tasks including E2E tests task --list-all # Run a specific E2E test suite task test-e2e-integration task test-e2e-standard # Run solo via tsx (development mode, without building) npm run solo-test -- <COMMAND> <ARGS> ``` To run a single unit test file directly: ```bash npx mocha 'test/unit/path/to/test.ts' ``` Logs are written to `$HOME/.solo/logs/solo.log`. Tail with: `tail -f $HOME/.solo/logs/solo.log | jq` ## Architecture The codebase follows a layered, command-driven architecture with dependency injection (`tsyringe-neo`): **Entry point:** `solo.ts``ArgumentProcessor` (Yargs) → Command Layer ### Layer Overview 1. **`src/commands/`** — 14 CLI commands (account, deployment, network, node, cluster, block-node, explorer, mirror-node, relay, one-shot, backup-restore, rapid-fire, file). Each command extends `BaseCommand`. Command schemas are in `src/commands/command-definitions/`. 2. **`src/core/`** — ~95 services: `account-manager.ts`, `config-manager.ts`, `chart-manager.ts`, `key-manager.ts`, `lock/` (distributed leases), `logging/` (Pino), `dependency-managers/` (installs Helm, Kind, kubectl), `dependency-injection/` (service container + `InjectTokens`). 3. **`src/integration/`** — External system clients: `kubernetes/` (K8s API wrapper), `helm/` (Helm chart execution), `kind/` (cluster provisioning), `git/`, `npm/`. 4. **`src/business/`** — Runtime state, local/remote config providers, address book management, path/crypto utilities. 5. **`src/data/`** — Configuration schema (JSON schema validation + migrations), mapper (class↔object), storage backends. ### Key Patterns - **Dependency Injection:** Services registered via `InjectTokens` enum; `@inject()` decorators on constructors. The DI container is initialized in `src/core/dependency-injection/`. - **Task Execution:** All long-running operations are Listr2 task arrays, enabling progress rendering and cancellation. - **Configuration:** Local (in-memory) and Remote (Kubernetes ConfigMap) config providers; validated against JSON schemas with migration support. - **Error Hierarchy:** `SoloError` (base), `SilentBreak` (exit without display), specialized errors in `src/core/errors/`. - **Component Versions:** Managed in `version.ts` at the repo root. ## Environment Variable Documentation There are two categories of environment variables to keep in sync with `docs/site/content/en/docs/env.md`. This requirement does NOT apply to variables used only in the `test/` directory. ### 1. Direct env vars When adding, removing, or modifying environment variables consumed via `getEnvironmentVariable()` in `src/**/*.ts` or `version.ts`, update `env.md`. Each entry must include the variable name, a short description, and its default value (as defined in the source). ### 2. Config-system env vars The layered config system (`EnvironmentConfigSource`, prefix `SOLO`) allows environment variables to override any `@Expose()`d field on `SoloConfigSchema` and its nested schemas (`HelmChartSchema`, `TssSchema`, `WrapsSchema`). When adding, renaming, or removing `@Expose()`d properties on these schema classes, update `env.md` to reflect the corresponding env var. **Naming convention:** Each camelCase property name segment is converted to `UPPER-KEBAB-CASE` (dashes separate words within a segment); schema object nesting levels are joined with `_`; the whole thing is prefixed with `SOLO_`. | Config property path | Env var | |---|---| | `helmChart.directory` | `SOLO_HELM-CHART_DIRECTORY` | | `tss.readyMaxAttempts` | `SOLO_TSS_READY-MAX-ATTEMPTS` | | `tss.wraps.libraryDownloadUrl` | `SOLO_TSS_WRAPS_LIBRARY-DOWNLOAD-URL` | This is **not** the same as plain `UPPER_SNAKE_CASE` — dashes within a segment represent camelCase word boundaries, not underscores. ## Architecture and Design Before implementing a new feature or undertaking a major refactor, review the architecture and design documentation under [`docs/design/architecture/`](docs/design/architecture/) and align the implementation with the patterns and standards described there. For small enhancements to existing features or bug fixes, architectural alignment is not required. ## Coding Standards Follow the project's TypeScript style guide at [`docs/contributing/typescript-code-style.md`](docs/contributing/typescript-code-style.md) for all code changes. Before writing or modifying code, review these configuration files to avoid lint and formatting issues: - **`.prettierrc.json`** — formatting rules (indentation, quotes, line length, etc.) - **`eslint.config.mjs`** — linting rules and TypeScript-specific restrictions - **`.remarkrc.mjs`** — Markdown linting rules (applies to `.md` files) Key rules enforced as ESLint **errors** (not warnings): - **`import type`** — When all identifiers in an import are used only as types, use `import type {Foo} from '...'`. For mixed imports, use the inline form: `import {SomeClass, type SomeInterface} from '...'`. See §3.3.4 of the TypeScript style guide. - **Abbreviations**`unicorn/prevent-abbreviations` bans common short names (`fn`, `vars`, `envVar`, `cb`, `err`, `opts`, etc.) in identifiers **and file names**. See §5.1.2 of the TypeScript style guide for the full substitution list. - **Explicit types** — Every variable declaration and every callback (including `it()` / `describe()` callbacks in tests) must have an explicit type annotation. See §6.1 and §6.1.1 of the style guide. - **One class/interface per file** — Each exported class or interface must be in its own file, named in kebab-case to match the class/interface name. See §3.5 of the style guide. Run `task format` to auto-fix formatting and lint issues before committing. Note that `task format` fixes Prettier and some ESLint issues automatically, but **abbreviation violations and missing type annotations must be fixed manually** — they appear as errors in the lint output. ## PR Requirements - **DCO sign-off** on all commits (`git commit -s`) - **Cryptographically signed commits** (GPG or SSH — must show "Verified" on GitHub) - **Conventional Commit PR titles:** `feat:`, `fix:`, `docs:`, `chore:`, etc.