@go-labs-sg/bb 2.19.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,22 +6,49 @@ For AI agents: bills and claims are stored as the same underlying bill records.
6
6
 
7
7
  For AI agents using this CLI: always check whether a newer `@go-labs-sg/bb` version is available before running Budget Builder commands, then update the CLI if needed so command flags and API behavior stay current.
8
8
 
9
- For AI agents using this CLI: run `bb auth whoami` before reading or changing Budget Builder data. The CLI displays every command regardless of the authenticated user's role, but the API authorizes each request using the API-key owner's role, resource ownership or project assignment, current workflow state, and approval assignment. See the [role-aware agent guide](./role-aware-agent-guide.md) before choosing commands.
9
+ For AI agents using this CLI: run `bb auth whoami` before reading or changing Budget Builder data. The CLI displays every command regardless of the authenticated user's role, but the API authorizes each request using the current browser-authorized CLI user or automation API-key owner, resource ownership or project assignment, current workflow state, and approval assignment. See the [role-aware agent guide](./role-aware-agent-guide.md) before choosing commands.
10
10
 
11
11
  For AI agents using this CLI: do not execute mutations until the user explicitly confirms the exact entity, target state, and side effects. Inspect the entity first, summarize what will change and whether emails, external systems, deletions, or financial records are involved, then wait for a clear confirmation from the user. Canonical v2 mutations print an effect-aware workflow preview before one interactive `CONFIRM` prompt. Non-interactive automation must supply every applicable granular `--allow-*` flag; the CLI rejects the command before its first API call when any flag is missing.
12
12
 
13
13
  **Registry:** [`@go-labs-sg/bb`](https://www.npmjs.com/package/@go-labs-sg/bb)
14
14
 
15
- ## Requirements
15
+ ## Runtime and installation
16
16
 
17
- - **Node.js** 24+ (ESM; relative imports in `dist` use `.js` extensions)
18
- - A Budget Builder account with any active user role
19
- - A **Budget Builder API key** (the same key is used for the CLI and MCP server)
17
+ The CLI requires [Bun](https://bun.com/docs/installation) 1.4.0 or newer and a Budget Builder account with any active user role.
20
18
 
21
- ## Install
19
+ Check whether a compatible Bun version is already available:
20
+
21
+ ```bash
22
+ bun --version
23
+ ```
24
+
25
+ If Bun is missing, install it for the current operating system:
26
+
27
+ **macOS (Homebrew)**
28
+
29
+ ```bash
30
+ brew install oven-sh/bun/bun
31
+ ```
32
+
33
+ **Windows (PowerShell)**
34
+
35
+ ```powershell
36
+ powershell -c "irm bun.sh/install.ps1|iex"
37
+ ```
38
+
39
+ **Linux**
40
+
41
+ ```bash
42
+ curl -fsSL https://bun.com/install | bash
43
+ ```
44
+
45
+ If Bun is installed but older than 1.4.0, run `bun upgrade`. Open a new terminal if the installer changes `PATH`, then verify `bun --version` again. Installation agents should skip the platform installer when Bun 1.4.0 or newer is already available.
46
+
47
+ Install and verify the CLI:
22
48
 
23
49
  ```bash
24
50
  bun add --global @go-labs-sg/bb
51
+ bb version
25
52
  ```
26
53
 
27
54
  Or run without installing:
@@ -32,33 +59,37 @@ bunx @go-labs-sg/bb <command>
32
59
 
33
60
  ## Authentication
34
61
 
35
- Sign in to Budget Builder and create your first key under **API Keys**. Every
36
- active user can manage their own keys; an admin is only required to manage a key
37
- for someone else.
38
-
39
- Load the key from your shell's secret manager or environment before running
40
- commands:
62
+ Interactive users authorize the CLI through Budget Builder's normal Google-backed
63
+ browser session:
41
64
 
42
65
  ```bash
43
- export BB_API_KEY="<your-key>"
66
+ bb auth login
67
+ bb auth status
68
+ bb auth whoami
44
69
  ```
45
70
 
46
- Do not put the raw key in a command argument, commit it to a repository, or paste
47
- it into logs. The CLI redacts API-key values from its request tracing. If you use
48
- a local `.env`, keep it out of version control and restrict its file permissions.
71
+ The browser always requires an explicit **Authorize CLI** action, even when it is
72
+ already signed in. The CLI polls automatically and stores only Budget Builder-issued
73
+ credentials through `Bun.secrets`. It never stores Google credentials. Use
74
+ `bb auth logout` to revoke the interactive session. For SSH or containers, pass
75
+ `--no-browser` and open the printed URL on another device.
49
76
 
50
- Once authenticated, any user can rotate or manage their own keys from the CLI:
77
+ Budget Builder API keys remain supported for MCP, CI, and non-interactive
78
+ automation. When `BB_API_KEY` is present it takes precedence over the interactive
79
+ session for that process. Create and manage automation keys under **API Keys** or
80
+ with the commands below:
51
81
 
52
82
  ```bash
53
- bb auth whoami
54
- bb user api-key create --name "My CLI"
83
+ bb user api-key create --name "My automation"
55
84
  bb user api-key list
56
85
  bb user api-key revoke <api-key-id>
57
86
  ```
58
87
 
59
- The raw key is returned only by `bb user api-key create`; copy it immediately. Listing
60
- keys returns metadata only. Revoking the key currently stored in `BB_API_KEY`
61
- will cause subsequent commands to fail until it is replaced.
88
+ The raw key is returned only by `bb user api-key create`; copy it immediately.
89
+ Never put it in command arguments, source control, or logs. Listing returns metadata
90
+ only. Revoking the key currently stored in `BB_API_KEY` causes that automation
91
+ process to fail until the environment credential is replaced or removed so the
92
+ interactive session can be used.
62
93
 
63
94
  Admins can provision API-only service identities and manage their keys from the
64
95
  CLI. These identities are not human web accounts: `create-user` does not create
@@ -75,14 +106,14 @@ The CLI talks to `https://budget-builder.getout.events` by default. For staging
75
106
 
76
107
  ## Role-aware agent startup
77
108
 
78
- Every agent session that uses an API key must begin with:
109
+ Every agent session must begin with:
79
110
 
80
111
  ```bash
81
112
  bb version
82
113
  bb auth whoami
83
114
  ```
84
115
 
85
- `whoami` returns the identity and database role attached to the active key inside the v2 response envelope:
116
+ `whoami` returns the identity and database role attached to the active browser session or automation key inside the v2 response envelope:
86
117
 
87
118
  ```json
88
119
  {
@@ -142,7 +173,7 @@ bb supplier list
142
173
 
143
174
  Global options and command flags use `--key=value` or `--key value`. Run `bb help` for the canonical command catalog and `bb help --legacy` for the transition-era detailed flat-command reference.
144
175
 
145
- Run `bb version` before agent-driven work to record the installed package version and production API target. This is read-only and does not require `BB_API_KEY`.
176
+ Run `bb version` before agent-driven work to record the installed package version and production API target. This is read-only and does not require authentication.
146
177
 
147
178
  **Authoritative command list:** run `bb help` or inspect the generated `command-reference.md` / `command-manifest.json`. The catalog includes every canonical route, global option, and effect classification, but does not filter by the current `whoami` role. During the handler migration, command-specific arguments retain the compatibility dispatcher's validation and are explicitly marked `legacy-passthrough` in the manifest; use `bb help --legacy` for their detailed transition reference. Version 2 uses grouped, resource-first commands such as `bb budget list` and `bb bill attachment upload`. Flat commands such as `bb list-budgets` and their MCP-style `snake_case` aliases remain available during the v2 transition, with a deprecation notice and an equivalent grouped command in help. MCP exposes a subset of the same tRPC surface; the CLI additionally includes a few procedures mainly used by the web UI.
148
179
 
@@ -181,6 +212,10 @@ New sources are registered against an existing Typeform form ID and always start
181
212
  with processing disabled in `COLLECT_ONLY`; creating a source does not call any
182
213
  external provider.
183
214
 
215
+ Deal-lifecycle retries require Slack and Asana to succeed. Google Calendar is
216
+ attempted afterward; a Calendar failure is logged without failing the overall
217
+ lifecycle operation.
218
+
184
219
  ### Mutation safety
185
220
 
186
221
  While an estimate email is `QUEUED`, `PROCESSING`, or awaiting provider
@@ -233,6 +268,8 @@ The table below is a behavior index keyed by the compatibility dispatcher's lega
233
268
 
234
269
  Project and budget query payloads keep the Asana identities explicit: `asanaTaskId` is the Deals task GID, while `asanaProjectGid` and `asanaProjectUrl` identify the operational project created for Won delivery work.
235
270
 
271
+ Bill, claim, and quotation mutations accept only suppliers whose approval status is `APPROVED`. An active supplier that is `PENDING_APPROVAL`, `REJECTED`, or `SUPERSEDED` must be approved before it can be used.
272
+
236
273
  | Area | Legacy handler labels (reference only; non-exhaustive) |
237
274
  | --- | --- |
238
275
  | **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`, `rename-budget-version`, `restore-budget-version`, `update-budget-status` (`ESTIMATE_ACCEPTED` requires win proof, auto-marks `PITCH` or `LOST` projects `WON`, and auto-creates an Asana Event Ops section from Prompt 5 tasks when enabled; Prompt 5 skips quantity-zero items, combines matching non-GO-internal suppliers, keeps each GO internal item separate, removes generated work that repeats another line item or group, and schedules applicable subtasks relative to the project start date; `--projectStatusOnCommercialRejection PITCH\|LOST` is required when rejecting the only accepted/closed budget on a commercial project), `mark-budget-won` (`<budgetId>` + proof file path; `PITCH` or `LOST` projects become `WON` automatically), `create-budget` / `update-budget` (`--payload`; cloned unavailable lines require `unavailableItemReviewAcknowledged: true`), `delete-budget`, `create-budget-approval` (also sends approval request emails), `create-estimate`, `send-estimate-to-contact-person` (same contact-person email workflow as web), `add-budget-items`, `update-budget-item`, `replace-budget-item`, `approve-unavailable-item-exception` (Lead/Admin), `remove-budget-item`, `reorder-budget-items`, `update-budget-item-supplier`, `mark-budget-items-not-utilized`, `restore-budget-item`, `create-placeholder-bill` (admin recovery), `create-budget-category`, `update-budget-category`, `delete-budget-category`, `update-budget-commission`, `delete-budget-commission`, `update-budget-discount`, `delete-budget-discount` (`--payload` where noted), `upload-budget-attachment` (`<budgetId>` + local file path; uses `attachment.requestBudgetAttachmentUpload` + PUT + `attachment.confirmBudgetAttachment`) |
@@ -243,7 +280,7 @@ Project and budget query payloads keep the Asana identities explicit: `asanaTask
243
280
  | **Companies & projects** | `list-companies`, `get-company`, `create-company`, `update-company` (`--payload`), `delete-company`, `list-projects`, `get-project` (its budget overview returns `totalRevenue`, calculated only from Estimate Accepted and Estimate Closed budgets), `get-project-hub-status`, `setup-project-hub`, `sync-project-hub-commercial-documents`, `create-project` (required: `--name`, `--companyId`, `--contactPersonId`, `--insideSalesId`, `--businessDevelopmentId`, `--venue`, `--startDate` as ISO datetime for project/window start; when `--asanaTaskId` is omitted, the CLI searches open Asana lead tasks in the Deals project, prompts for one of the top five matches, and resolves Slack channel fields from the selected deal card; optional `--asanaSearch`, `--pax`, `--endDate`, `--description`, `--projectManagerId`; always requests QBO project import like the web app), `update-project` (`--payload` with `dateRange.from` / `dateRange.to` for the project window; optional `projectManagerId` and `requestQboAccountantNotification` in JSON), `delete-project`, `check-project-reconciliation <id>` (runs the web app's live checks without changing status), `reconcile-project <id>` (reruns checks transactionally and marks an eligible project `RECONCILED`), `complete-project <id>` (reruns validation, marks a reconciled project `COMPLETED`, and queues QuickBooks placeholder cleanup), `import-qbo-project`, `update-project-status` (`<id>` `<status>`: `PITCH` \| `WON` \| `COMPLETED` \| `RECONCILED` \| `LOST`; close-out follows `WON` → `RECONCILED` → `COMPLETED`, and reconciliation requires every accepted/closed budget line to have an Approved/Paid bill or claim or be explicitly Not Utilized; marking `COMPLETED` queues deletion of every remaining project placeholder bill from QuickBooks; for `PITCH` → `WON` also pass a Budget Builder user `--projectManagerId` or `--projectManagerEmail`; when marking `WON` without an accepted/closed budget or proof, pass `--wonOverrideReason`) |
244
281
  | **Contacts** | `list-contacts`, `create-contact-person` (`--payload`), `update-contact-person` (`--payload`) |
245
282
  | **Suppliers & items** | `list-suppliers` (defaults to active suppliers, `--perPage 10`, sorted by `createdAt` desc; supports `--name`, `--sortBy` for scalar supplier fields, `--sortDir`, `--createdBy`, `--gstRegistered`, `--status`, `--supplierTags`, `--active false` for archived suppliers), `create-supplier` (`--payload`; when supplier status is `PENDING_APPROVAL`, also runs `supplier.createSupplierApproval` and `email.sendSupplierApprovalRequestEmail`), `update-supplier` (`--payload`; when supplier status is `PENDING_APPROVAL`, also runs `supplier.createSupplierApproval` and `email.sendSupplierApprovalRequestEmail`), `delete-suppliers` (`--ids` CSV; admin; archives/deactivates related items), `reactivate-suppliers` (`--ids` CSV; admin; reactivates related items), `create-certification` / `create-payment-method` / `create-supplier-role` / `create-supplier-tag` (`--name`), `get-supplier-details` (includes `supplierApprovalSummary` for pending approvers, superseded approvers, and the actual responder/respondedAt metadata), `get-supplier-analytics` (admin), `list-items` (`--includeQuickBooksDeactivationPending true` discovers interrupted QuickBooks deactivations for Admin retry), `create-item` (`--payload`), `update-item` (`--payload`), `archive-items` (`--ids` CSV, max 100; Budget Builder-only; open estimates retain unavailable snapshot lines for resolution), `delete-item` (admin; archives in Budget Builder and makes the item inactive in QuickBooks; blocked while an open estimate references it), `get-item`, `list-item-categories`, `create-item-category` / `update-item-category` / `delete-item-categories` (admin; `--ids` CSV for delete) |
246
- | **Dashboard & users** | `whoami` (current API-key owner identity and role), `list-users`, `create-user` (admin; provisions an API-only service identity with no Google sign-in; `--email`, optional `--name`, optional `--role` defaulting to `USER`), `create-api-key` (`--name`; defaults to the caller; admin-only `--userId` for another user; raw key shown once), `list-api-keys` (defaults to the caller; admin-only `--userId` for another user), `revoke-api-key` (key ID; admin-only `--userId` for another user), `get-user-performance`, `get-dashboard`, `get-monthly-metrics`, `get-system-overview`, `get-estimate-performance`, `get-financial-overview` (performance/dashboard commands are admin-only) |
283
+ | **Dashboard & users** | `whoami` (current authenticated identity and role), `list-users`, `create-user` (admin; provisions an API-only service identity with no Google sign-in; `--email`, optional `--name`, optional `--role` defaulting to `USER`), `create-api-key` (`--name`; defaults to the caller; admin-only `--userId` for another user; raw key shown once), `list-api-keys` (defaults to the caller; admin-only `--userId` for another user), `revoke-api-key` (key ID; admin-only `--userId` for another user), `get-user-performance`, `get-dashboard`, `get-monthly-metrics`, `get-system-overview`, `get-estimate-performance`, `get-financial-overview` (performance/dashboard commands are admin-only) |
247
284
  | **Errors (admin)** | `get-recent-errors`, `get-error-metrics` |
248
285
  | **Automation (admin)** | `list-integration-operations`, `retry-integration-operation` (Resend resolution requires `--confirmExternalStateReconciled true` plus `--outboundEmailResolution ACCEPTED\|NOT_ACCEPTED_RETRY`; include `--providerMessageId` when accepted) |
249
286
  | **Historical / benchmarks** | `get-approved-budgets`, `get-budget-category-benchmarks`, `get-item-pricing-history`, `get-supplier-pricing-history` |
@@ -258,7 +295,7 @@ The CLI intentionally wraps low-level upload-request/confirm procedures into fil
258
295
  - **Legacy compatibility:** flat aliases keep their raw success JSON, `{ "error": "..." }` failures, and default action tracing during the transition
259
296
  - **Exit codes:** `0` success, `2` usage/validation/confirmation failure, `1` API/auth/network/internal failure, `130` interruption
260
297
 
261
- A `.env` file in the **current working directory** is loaded automatically (for `BB_API_KEY`, etc.).
298
+ A `.env` file in the **current working directory** is loaded automatically for automation settings such as `BB_API_KEY`. Interactive browser credentials remain exclusively in `Bun.secrets`.
262
299
 
263
300
  ## Developing in this repo
264
301