This document describes setup, architecture, tooling, and contributor workflow for the monorepo.
- TypeScript (
strict) on Node.js 20+ - ES modules (
module: NodeNext) - CLI framework:
commander - Validation:
zod - HTTP and service integration:
axios - PostgreSQL access for
hdb:pg - Linting: ESLint (
eslint.config.mjs) - Testing: Vitest (
vitest.config.ts) - Git hooks: Husky + lint-staged
- Node.js
>=20 - npm
- Install dependencies:
npm ci
- Configure env file in the default helper path:
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/helper"cp .env.example "${XDG_CONFIG_HOME:-$HOME/.config}/helper/.env"
- Set Coinbase credentials path in that env file:
HELPER_COINBASE_CREDENTIALS_PATH=/absolute/path/to/coinbase-credentials.json
- Explicitly opt in to live Coinbase requests:
HELPER_ALLOW_LIVE_EXCHANGE=true
- Optional env override:
HELPER_ENV_FILE=/absolute/path/to/.env
Coinbase API key setup reference:
- https://docs.cdp.coinbase.com/coinbase-app/authentication-authorization/api-key-authentication
- In CDP key creation, select the
ECDSAsignature algorithm (ES256).
Never commit secrets, .env files, or credential material.
src/shared/: shared Coinbase integration, common utilities, schemas, logging, and helper binariessrc/apps/cb/:cbCLI (Coinbase trading commands)src/apps/hdb/:hdbCLI (database-oriented tools and command groups)src/apps/hdb-portal/: local read-only web portal overhdbdatasrc/version.ts: package version exporttest/: repository-level Vitest test suitestest/setup/no-network.ts: global outbound-network block for testsdist/: compiled output
Use explicit relative imports with .js specifiers under NodeNext.
src/apps/cb/cli.tssrc/apps/hdb/cli.tssrc/shared/bin/validate-env.ts(helper-env-check)
For src/apps/cb, keep these boundaries:
commands/: command intent handlers onlyservice/order-builders.ts: pure, testable order sizing/validation/merge logicservice/order-prompts.ts: user interaction (console/prompt formatting)service/order-service.ts: orchestration onlysrc/shared/coinbase/orders-client.ts: order-focused transport APIsrc/shared/coinbase/rest.ts: low-level HTTP/signed request primitives
Command registration in src/apps/cb/commands/register/ should use:
withAction(commandName, parser, handler)fromregister/register-utils.ts- parser helpers (
parseArg,parseArgOptions,parseProductId,parseProductIdOptions, etc.)
Avoid introducing additional one-off wrapper helpers when parser composition is sufficient.
Order command topology is intentionally nested:
cb order get <order_id>cb order list [product]cb order cancel <order_id>cb order modify <order_id> ...
npm run dev: runcbfrom TypeScript (tsx src/apps/cb/cli.ts)npm run dev:hdb: runhdbfrom TypeScript (tsx src/apps/hdb/cli.ts)npm run dev:hdb-portal: run the localhdbportalnpm run build: clean + compile todist/+ mark CLI files executablenpm run clean: removedist/npm run lint: run ESLintnpm run lint:fix: run ESLint with autofixnpm run typecheck: run TypeScript checks without emitnpm run test: run unit tests (safe default)npm run test:unit: run unit testsnpm run test:integration: run integration tests undertest/integration/**npm run test:integration:smoke: run integration tests with a sanitized environment and readonly CI guard enablednpm run test:watch: run unit tests in watch modenpm run smoke:bin: smoke-test builtcbCLI (node dist/apps/cb/cli.js --help)npm run pack:dry: preview npm package contentsnpm run release:check: lint + typecheck + test + pack dry runnpm run prepare: build during install (including git-based installs)npm run patch|minor|major: version bump + push commit/tag after checks
Useful direct commands:
node dist/apps/hdb/cli.js --help(run builthdb)node dist/apps/hdb-portal/cli.js(run builthdb-portal)
- Implement changes.
- Run quality checks using risk-tiered validation:
- Low risk (docs/CSS/static copy): targeted lint on touched files is the minimum.
- Medium risk (non-critical logic/refactors/parser-output): targeted lint + targeted tests during iteration.
- High risk (order logic, math, schemas/validation, shared core utilities): strict targeted lint + targeted tests during iteration.
- End-of-task gate for medium/high: run full
npm run typecheck && npm run lint && npm run testonce before handoff. - If mixed scope, use the highest risk tier. If uncertain, default to medium.
- Validate build artifacts:
npm run buildnpm run smoke:bin
- Optional release preflight:
npm run release:check
- Unit tests live under
test/src/**/*.test.ts(plustest/setup/no-network.test.ts). - Integration tests live under
test/integration/**/*.test.ts. - Prefer unit tests for pure logic and schema parsing.
- Mock side effects and external service calls.
- Outbound network access is blocked by default in tests.
- Keep
test/setup/no-network.tsenabled invitest.config.ts.
npm run test:integration:smoke starts from an empty environment (env -i) and only passes:
PATHHOMEHELPER_ENV_FILE(defaults to${INTEGRATION_ENV_FILE:-$HOME/.config/helper/.env.readonly})HELPER_ALLOW_LIVE_EXCHANGE=trueCI_INTEGRATION_READONLY=true
This avoids inheriting a fully loaded local shell env while still allowing explicit read-only live checks.
Behavior matrix for Coinbase REST calls:
HELPER_ALLOW_LIVE_EXCHANGE |
CI_INTEGRATION_READONLY |
GET requests |
non-GET requests |
|---|---|---|---|
false |
false |
blocked | blocked |
false |
true |
blocked | blocked |
true |
false |
allowed | allowed |
true |
true |
allowed | blocked |
hdbuses PostgreSQL for local workflows.- Configure
HELPER_POSTGRES_DATABASE,HELPER_POSTGRES_USERNAME, andHELPER_POSTGRES_PASSWORD;hdbdoes not currently readDATABASE_URL. - Local Postgres setup examples are documented in
src/apps/hdb/README.postgres.md. - For troubleshooting, prefer
hdb ... --jsonfor command-owned read-only views and use a local read-only SQL role such ashdb_readonlyfor ad hoc inspection.
ESLint is type-aware and enforces consistency around:
- promise handling
- import/type style
- control-flow safety (e.g., exhaustive switches)
- general formatting and correctness rules
If a rule appears incorrect for a valid case, discuss before disabling it.
After npm run build, package binaries are:
cb->dist/apps/cb/cli.jshdb->dist/apps/hdb/cli.jshelper-env-check->dist/shared/bin/validate-env.js
For local shell usage:
npm linkexport PATH="$(npm prefix -g)/bin:$PATH"command -v cb hdb helper-env-check
npm link creates the command symlinks under $(npm prefix -g)/bin. Persist
that directory in your shell's PATH if the verification command cannot find
them. For a permissions error, configure a user-owned npm prefix; do not run
npm link with sudo.
Verify the linked entrypoints without making network or database requests:
cb --helphdb --helphelper-env-check --help
Husky + lint-staged is configured:
.husky/pre-commitrunsnpx lint-staged- staged
*.{ts,tsx,js,mjs,cjs}files runeslint --fix
If hooks are not active in your clone:
git config core.hooksPath .husky/_
GitHub Actions workflow: .github/workflows/ci.yml
- Triggers on pull requests and pushes to
master - Uses Node.js 20
checksjob runs:npm cinpm run release:check
Integration smoke tests remain available for local development (npm run test:integration:smoke) but are not executed in GitHub Actions.
To enforce merge blocking, configure branch protection on master to require:
checks
npm run patchnpm run minornpm run major
Each command runs release:check, bumps version via npm version, and pushes commits/tags.
Pushing v* tags triggers .github/workflows/release.yml to create a GitHub Release.
Please include:
- a concise summary of behavior changes
- tests for behavior changes
- notes for API, schema, or command-surface changes