npm package: @go-labs-sg/bb
Description: Budget Builder CLI — list budgets, bills, approvals, suppliers; approve bills; change status. For AI agents (e.g. Chuck/OpenClaw).
Latest version: 1.2.2

# bb

Command-line interface for **Budget Builder**. Call budgets, bills, approvals, suppliers, dashboard, and more from your terminal or from tools that don’t support MCP (e.g. some AI agents). Responses are JSON on stdout.

**Registry:** [`@go-labs-sg/bb`](https://www.npmjs.com/package/@go-labs-sg/bb)

## Requirements

- **Node.js** 18+ (ESM; relative imports in `dist` use `.js` extensions)
- A **Budget Builder API key** (same key used for the MCP server)

## Install

```bash
npm install -g @go-labs-sg/bb
```

Or run without installing:

```bash
npx @go-labs-sg/bb <command>
```

## Authentication

Set your API key before running commands:

```bash
export BB_API_KEY=<your-key>
```

Create or revoke keys in the web app: **Goracle → API Keys** (MCP API keys).

The CLI talks to the production API: `https://budget-builder.getout.events`.

## Usage

```bash
bb help
bb list-budgets
bb get-budget <budget-id>
bb update-budget-status <budget-id> <status>
bb list-bills
bb approve-bill <bill-id>
bb list-approvals
bb list-suppliers
```

Global options and flags use `--key=value` or `--key value` (see `bb help`).

**Authoritative command list:** run `bb help` — it includes every command, positional args, and flags. MCP exposes a subset of the same tRPC surface; the CLI additionally includes a few procedures mainly used by the web UI (e.g. `reorder-budget-items`, `update-budget-item-supplier`). You can also use MCP-style `snake_case` (e.g. `bb list_bills`); it is normalized to kebab-case.

**Mutations with `--payload`:** Commands such as `create-budget`, `create-bill`, `update-supplier`, etc. take a single JSON object (`--payload '<json>'`) matching the corresponding tRPC procedure input. Use ISO strings for date/datetime fields; the CLI coerces them where needed. The API still validates the full shape.

### Command overview

| Area | Commands (non-exhaustive) |
| --- | --- |
| **Budgets** | `list-budgets` (full payload by default; `--summary` or `--includeDetails false` for slim list), `get-budget`, `get-budget-items`, `get-budget-details`, `get-budget-categories`, `get-budget-versions`, `update-budget-status`, `create-budget` / `update-budget` (`--payload`), `delete-budget`, `create-budget-approval`, `add-budget-items`, `update-budget-item`, `remove-budget-item`, `reorder-budget-items`, `update-budget-item-supplier`, `create-budget-category`, `update-budget-category`, `delete-budget-category`, `update-budget-commission`, `update-budget-discount` (`--payload` where noted), `upload-budget-attachment` (`<budgetId>` + local file path; uses `attachment.requestBudgetAttachmentUpload` + PUT + `attachment.confirmBudgetAttachment`) |
| **Bills** | `list-bills`, `list-claims`, `create-bill` (`--payload`), `update-bill` (`--payload`), `delete-bill`, `create-bill-approval`, `update-bill-status`, `patch-bill-payment` (PAID bills: `--paymentTrackingUrl`, `--paymentReference`, `--quickbooksBillId`, `--paymentDate` ISO; clear with `--clearPaymentTrackingUrl` / `--clearPaymentReference` / `--clearQuickbooksBillId` / `--clearPaymentDate` `true`), `patch-bill-invoice-number`, `get-bill-attachments`, `upload-bill-attachment` (`<billId>` + local path), `get-bill-details` |
| **Approvals** | `list-approvals` / `get-pending-approvals`, `approve-bill`, `reject-bill`, `approve-budget`, `reject-budget`, `approve-supplier`, `reject-supplier` |
| **Companies & projects** | `list-companies`, `get-company`, `create-company`, `update-company` (`--payload`), `delete-company`, `list-projects`, `get-project`, `create-project` (optional `--requestQboAccountantNotification false` to skip QBO accountant emails), `update-project` (`--payload`, optional `requestQboAccountantNotification` in JSON), `delete-project`, `update-project-status` |
| **Contacts** | `list-contacts`, `create-contact-person` (`--payload`), `update-contact-person` (`--payload`) |
| **Suppliers & items** | `list-suppliers`, `create-supplier` (`--payload`), `update-supplier` (`--payload`), `delete-suppliers` (`--ids` CSV; admin), `create-certification` / `create-payment-method` / `create-supplier-role` / `create-supplier-tag` (`--name`), `get-supplier-details`, `get-supplier-analytics`, `list-items`, `create-item` (`--payload`), `update-item` (`--payload`), `delete-item`, `get-item`, `list-item-categories`, `create-item-category`, `update-item-category`, `delete-item-categories` (`--ids` CSV; admin) |
| **Dashboard & users** | `list-users`, `get-user-performance`, `get-dashboard`, `get-monthly-metrics`, `get-system-overview`, `get-estimate-performance`, `get-financial-overview` |
| **Errors** | `get-recent-errors`, `get-error-metrics` |
| **Historical / benchmarks** | `get-approved-budgets`, `get-budget-category-benchmarks`, `get-item-pricing-history`, `get-supplier-pricing-history` |

## Output

- **Stdout:** JSON (pretty-printed)
- **Stderr:** Error objects as JSON on failure
- **Action logs (default on):** Each run logs to **stderr**: (1) JSON lines for command start, then `ok` or `error` with `durationMs` (`--payload` and similar flags are redacted); (2) tRPC lines for every API procedure (path, timing). **Stdout** stays JSON-only for piping (e.g. `| jq`). Suppress with `--quiet`, `-q`, or `BB_CLI_QUIET=1`.
- **Exit code:** `0` on success, `1` on error

A `.env` file in the **current working directory** is loaded automatically (for `BB_API_KEY`, etc.).

## Developing in this repo

From the monorepo root (after `bun install`):

```bash
export BB_API_KEY=...
bun run bb -- list-budgets
```

Or from `packages/cli`:

```bash
bun run build          # emit dist/ via tsc
bun run typecheck      # tsc --noEmit
bun run src/index.ts list-budgets
```

### Layout

- **`src/prisma-enums.ts`** — Prisma enum string values for runtime; mirror `packages/db/src/generated/prisma/enums.ts` after schema changes.
- **`src/filter-enums.ts`** — “extended” filter enums (ALL + Prisma enums). Keep in line with `packages/utils/src/filter-enums.ts` when those values change.

### Publish

`prepublishOnly` strips `workspace:` / `catalog:` entries from this package’s `package.json`, runs `tsc`, then `postpack` restores the file — so the npm tarball does not contain monorepo protocol dependencies. Types from `@bb/api` are compile-time only (`import type`). Prisma enum **values** used at runtime live in `src/prisma-enums.ts` (kept in sync with `packages/db` generated enums) so npm installs do not need `@bb/db`.