@go-labs-sg/bb 1.20.0 → 2.0.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 +142 -43
- package/command-manifest.json +6606 -0
- package/command-reference.md +1153 -0
- package/dist/api-client.js +44 -8
- package/dist/cli-trace.js +6 -1
- package/dist/commands.js +183 -23
- package/dist/index.js +389 -44
- package/dist/load-env.js +1 -1
- package/dist/parse-mutation-payload.js +22 -9
- package/dist/registry/generate-command-artifacts.js +36 -0
- package/dist/registry/index.js +583 -0
- package/dist/runtime/confirmation.js +76 -0
- package/dist/runtime/error.js +143 -0
- package/dist/runtime/index.js +6 -0
- package/dist/runtime/output.js +36 -0
- package/dist/runtime/process-runtime.js +28 -0
- package/dist/runtime/sanitize.js +50 -0
- package/dist/runtime/session.js +50 -0
- package/dist/runtime/types.js +1 -0
- package/package.json +13 -19
- package/role-aware-agent-guide.md +169 -0
package/README.md
CHANGED
|
@@ -6,96 +6,185 @@ 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:
|
|
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.
|
|
10
|
+
|
|
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.
|
|
10
12
|
|
|
11
13
|
**Registry:** [`@go-labs-sg/bb`](https://www.npmjs.com/package/@go-labs-sg/bb)
|
|
12
14
|
|
|
13
15
|
## Requirements
|
|
14
16
|
|
|
15
|
-
- **Node.js**
|
|
16
|
-
- A
|
|
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
20
|
|
|
18
21
|
## Install
|
|
19
22
|
|
|
20
23
|
```bash
|
|
21
|
-
|
|
24
|
+
bun add --global @go-labs-sg/bb
|
|
22
25
|
```
|
|
23
26
|
|
|
24
27
|
Or run without installing:
|
|
25
28
|
|
|
26
29
|
```bash
|
|
27
|
-
|
|
30
|
+
bunx @go-labs-sg/bb <command>
|
|
28
31
|
```
|
|
29
32
|
|
|
30
33
|
## Authentication
|
|
31
34
|
|
|
32
|
-
|
|
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:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
export BB_API_KEY="<your-key>"
|
|
44
|
+
```
|
|
45
|
+
|
|
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.
|
|
49
|
+
|
|
50
|
+
Once authenticated, any user can rotate or manage their own keys from the CLI:
|
|
33
51
|
|
|
34
52
|
```bash
|
|
35
|
-
|
|
53
|
+
bb auth whoami
|
|
54
|
+
bb user api-key create --name "My CLI"
|
|
55
|
+
bb user api-key list
|
|
56
|
+
bb user api-key revoke <api-key-id>
|
|
36
57
|
```
|
|
37
58
|
|
|
38
|
-
|
|
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.
|
|
39
62
|
|
|
40
63
|
Admins can provision API-only service identities and manage their keys from the
|
|
41
64
|
CLI. These identities are not human web accounts: `create-user` does not create
|
|
42
65
|
or link a Google OAuth account, so the resulting user cannot sign in with Google.
|
|
43
66
|
|
|
44
67
|
```bash
|
|
45
|
-
bb
|
|
46
|
-
bb
|
|
47
|
-
bb
|
|
48
|
-
bb
|
|
68
|
+
bb user create --email agent@example.com --name "Budget Agent" --role USER
|
|
69
|
+
bb user api-key create --userId <user-id> --name "Budget Agent CLI"
|
|
70
|
+
bb user api-key list --userId <user-id>
|
|
71
|
+
bb user api-key revoke <api-key-id> --userId <user-id>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The CLI talks to `https://budget-builder.getout.events` by default. For staging or local development, the target precedence is `--api-url`, then `BB_API_URL`, then production. Overrides must use HTTPS, except `http://localhost` and `http://127.0.0.1` for local development. `bb version` reports the effective target.
|
|
75
|
+
|
|
76
|
+
## Role-aware agent startup
|
|
77
|
+
|
|
78
|
+
Every agent session that uses an API key must begin with:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
bb version
|
|
82
|
+
bb auth whoami
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`whoami` returns the identity and database role attached to the active key inside the v2 response envelope:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"ok": true,
|
|
90
|
+
"data": {
|
|
91
|
+
"id": "...",
|
|
92
|
+
"name": "...",
|
|
93
|
+
"email": "...",
|
|
94
|
+
"role": "USER"
|
|
95
|
+
},
|
|
96
|
+
"meta": {
|
|
97
|
+
"command": "auth whoami",
|
|
98
|
+
"cliVersion": "2.0.0",
|
|
99
|
+
"apiBaseUrl": "https://budget-builder.getout.events"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
49
102
|
```
|
|
50
103
|
|
|
51
|
-
|
|
52
|
-
keys returns metadata only.
|
|
104
|
+
Record that identity in the agent's working context before selecting commands. Do not infer the role from the key name, email address, task description, or commands shown by `bb help`. Do not switch to another key to bypass a permission failure.
|
|
53
105
|
|
|
54
|
-
The
|
|
106
|
+
The following is a practical guide, not a client-side allowlist. The API remains authoritative.
|
|
107
|
+
|
|
108
|
+
| `whoami.role` | What an agent may normally do | Important limits |
|
|
109
|
+
| --- | --- | --- |
|
|
110
|
+
| `USER` | Manage its own API keys; use collaboration endpoints intentionally shared with every authenticated role, including company, contact, and project creation/update; work with resources it created or projects/budgets where its user ID is assigned; create its own bills, claims, and quotation drafts; request approval. | Shared collaboration endpoints are explicit API exceptions, not a general grant over every resource. No admin dashboards, user provisioning, integration recovery, final finance actions, or approval decisions. |
|
|
111
|
+
| `INSIDE_SALES` | All applicable base-user operations, assigned project/budget work, and the broader supplier workflow exposed to Inside Sales. | Budget and supplier approval requests still follow the Lead/Admin workflow. Assignment, ownership, state, and recorded-approver checks still apply. |
|
|
112
|
+
| `LEAD` | All applicable base-user operations plus Lead-stage budget and supplier approval work; supplier creation is auto-approved for this role. | Lead is not Admin. Do not attempt admin dashboards, user administration, integration recovery, final bill payment, or admin-only customer-invoice actions. |
|
|
113
|
+
| `ACCOUNTING_TEAM` | All applicable authenticated operations plus finance-stage bill work, including checking bills and correcting allowed payment or invoice-number metadata. Act on bill approvals only when the API lists the user as an approver. | Direct `APPROVED` and `PAID` bill status changes, customer-invoice payment, user administration, and system operations remain Admin-only. |
|
|
114
|
+
| `ADMIN` | Cross-user API-key and service-identity administration, global dashboard/error/integration operations, broad resource access, final bill approval/payment, and admin customer-invoice workflows. | Admin access does not bypass valid state transitions, required evidence, resource consistency, external-operation locks, or the agent's duty to obtain explicit confirmation for sensitive commands. |
|
|
115
|
+
|
|
116
|
+
Permissions are also resource- and state-dependent:
|
|
117
|
+
|
|
118
|
+
- Budget/project mutations generally require Admin, resource ownership, or assignment as Business Development, Inside Sales, or Project Manager.
|
|
119
|
+
- Bill and quotation edits/deletes are commonly limited to their creator or Admin, and only in supported statuses.
|
|
120
|
+
- Budget, supplier, bill, and quotation approval decisions require both a pending approval assigned to the authenticated user and the user's current database role. Budget/supplier decisions require `LEAD` or `ADMIN`, bill decisions require `ACCOUNTING_TEAM` or `ADMIN`, and quotation decisions require `ADMIN`; a stale assignment does not preserve authority after a role change.
|
|
121
|
+
- Customer-invoice approve/reject commands are Admin batch operations selected by batch ID, rather than approval-record-ID commands. The API maintains and resolves the internal pending Admin approval record as part of the batch workflow.
|
|
122
|
+
- Some company, contact, project, supplier, and catalog collaboration procedures intentionally allow every active authenticated role. Treat those endpoint-specific rules as exceptions; do not infer access to adjacent mutations.
|
|
123
|
+
- Own-key commands are available to every active role. Passing `--userId` to manage another user's keys requires Admin.
|
|
124
|
+
- `bb help` is a command catalog, not proof that the current identity is authorized.
|
|
125
|
+
|
|
126
|
+
If the API returns `FORBIDDEN`, stop. Report the command, target resource, `whoami` identity/role, and the missing ownership, assignment, approver, or role condition when known. Do not retry through a lower-level command or another credential unless the user explicitly changes the operating identity.
|
|
55
127
|
|
|
56
128
|
## Usage
|
|
57
129
|
|
|
58
130
|
```bash
|
|
59
131
|
bb help
|
|
60
|
-
bb
|
|
61
|
-
bb
|
|
62
|
-
bb
|
|
63
|
-
bb
|
|
64
|
-
bb
|
|
65
|
-
bb list
|
|
66
|
-
bb
|
|
132
|
+
bb version
|
|
133
|
+
bb auth whoami
|
|
134
|
+
bb budget list
|
|
135
|
+
bb budget get <budget-id>
|
|
136
|
+
bb budget status update <budget-id> <status>
|
|
137
|
+
bb bill list
|
|
138
|
+
bb bill approve <bill-id>
|
|
139
|
+
bb approval list
|
|
140
|
+
bb supplier list
|
|
67
141
|
```
|
|
68
142
|
|
|
69
|
-
Global options and flags use `--key=value` or `--key value`
|
|
143
|
+
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.
|
|
70
144
|
|
|
71
|
-
|
|
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`.
|
|
72
146
|
|
|
73
|
-
**
|
|
147
|
+
**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.
|
|
74
148
|
|
|
75
|
-
**
|
|
149
|
+
**Budget status automation:** Setting a budget to `ESTIMATE_ACCEPTED` requires a confirmed win-proof attachment. The first accepted estimate also requires `--invoiceSettings '<json>'` while customer invoicing is enabled. Provide `depositPercentage`, `balancePercentage`, `deliveryMethod`, and the matching `billingEmail` or HTTPS `uploadUrl`; revenue at or below S$5,000 requires `100/0`. If the parent project is `PITCH` or `LOST`, the API marks it `WON` automatically and runs enabled Asana automation. When rejecting the only accepted/closed budget on a commercial project, pass `--projectStatusOnCommercialRejection PITCH|LOST`.
|
|
150
|
+
|
|
151
|
+
### Mutation safety
|
|
152
|
+
|
|
153
|
+
Every canonical command is classified by effect: `state-change`, `email`, `external-write`, `delete`, and/or `financial-write`. Interactive runs require one exact `CONFIRM`. Non-interactive runs require the corresponding flags (`--allow-state-change`, `--allow-email`, `--allow-external-write`, `--allow-delete`, and `--allow-financial-write`); commands with multiple effects require every matching flag. Agents must still get user confirmation in chat first—the runtime gate is not user authorization.
|
|
76
154
|
|
|
77
155
|
**Approval email exclusions:** Approval requests create pending database records for every eligible approver, including configured non-recipient admin accounts. Automated approval-request emails skip those accounts.
|
|
78
156
|
|
|
79
|
-
**Locked estimate budget changes:**
|
|
157
|
+
**Locked estimate budget changes:** Legacy flat commands retain their additional interactive `yes` prompt when the current budget is locked. Canonical v2 commands use the single effect-aware confirmation gate; non-interactive execution requires `--allow-state-change` plus any other effects declared for that command.
|
|
158
|
+
|
|
159
|
+
**Mutations with `--payload`:** Commands such as `bb budget create`, `bb bill create`, and `bb supplier update` 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. Plain `description` fields for item create/update are converted to `descriptionRichText`; pass `descriptionRichText` directly when formatted Tiptap JSON is required. For **`bb project update`**, the project window is `dateRange.from` and `dateRange.to` (optional end); there are no separate event-date fields on the project payload. **`bb budget create` / `bb budget update`** do not accept `asanaTaskId`; configure the deal card on the project (`bb project update` / project settings).
|
|
160
|
+
|
|
161
|
+
**Contact-person estimate email:** `bb budget estimate send --payload '<json>'` calls the same `email.sendEstimateToContactPerson` procedure as the web composer. The payload requires `budgetId`, `estimateId`, optional `estimateDocNumber`, `to`, `cc`, `replyTo`, `subject`, HTML `content`, and HTML `signature`. It sends the raw PDF returned by QuickBooks together with the standard terms and Budget Builder budget attachments, then marks the budget `ESTIMATE_SENT`. The command requires interactive `CONFIRM`; inspect the budget, recipients, and HTML first, and do not retry blindly after an ambiguous delivery failure.
|
|
80
162
|
|
|
81
|
-
**
|
|
163
|
+
**Customer-invoice workflow parity:** `bb customer-invoice list` uses the same global/project list procedure and metrics as the web pages; omit filters for the global list or use `--projectId` for project scope. `bb customer-invoice send` uses the same protected email workflow as the web composer and marks a successful invoice `SENT`. `bb customer-invoice approve` and `bb customer-invoice reject` are Admin-only batch operations: callers select a batch ID, and the API resolves its internal pending Admin approval record. `bb customer-invoice payment mark-paid` requires an admin, a payment date, and a local PDF/GIF/JPEG/PNG proof up to 20MB; it uploads the proof, creates a QuickBooks Payment for the live outstanding balance when necessary, attempts to attach the proof in QuickBooks, records the result in Budget Builder, and sets the invoice status to `PAID`. `bb customer-invoice sync` follows QuickBooks' paid state and zero balance, restoring `SENT` or `APPROVED` if that payment is reversed. Invoice approval refuses voided invoices and closes the estimate only when approved invoice coverage totals 100%; deletion, voiding, rejection, expiry, and QBO synchronization use the same estimate-reopening and live-payment guards as the web app.
|
|
82
164
|
|
|
83
|
-
|
|
165
|
+
For agent-driven invoice work, use this read-before-write sequence:
|
|
166
|
+
|
|
167
|
+
1. Run `bb customer-invoice get <batchId>` and, when composing email, `bb customer-invoice email-context get <batchId>`.
|
|
168
|
+
2. For creation, run `bb customer-invoice eligible-budget list <projectId>` or `bb customer-invoice readiness check <budgetId>` first.
|
|
169
|
+
3. State the exact invoice or batch, current status, intended mutation, QuickBooks effect, email recipients, proof file, and estimate-closing/reopening effect to the user.
|
|
170
|
+
4. Wait for explicit confirmation, then run the sensitive command interactively and verify its JSON result. Do not treat the runtime `CONFIRM` prompt as user authorization.
|
|
84
171
|
|
|
85
172
|
### Command overview
|
|
86
173
|
|
|
87
|
-
|
|
174
|
+
The table below is a behavior index keyed by the compatibility dispatcher's legacy handler labels. It is not invocation syntax. AI agents and new automation must resolve and use the grouped v2 route from `bb help`, [`command-reference.md`](./command-reference.md), or [`command-manifest.json`](./command-manifest.json); never copy a flat label from this table into a new command.
|
|
175
|
+
|
|
176
|
+
| Area | Legacy handler labels (reference only; non-exhaustive) |
|
|
88
177
|
| --- | --- |
|
|
89
178
|
| **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`), `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`, `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`) |
|
|
90
|
-
| **Bills / claims** | `list-bills` (`--isClaimable false` for bills, `--isClaimable true` for claims, omit for both), `list-claims` (claims only), `validate-bill-selection` (`--payload`; runs the same supplier, line-item, and quotation-coverage checks as the web flow), `stage-bill-attachment` (securely uploads invoice/payment-proof files before creation and returns attachment JSON), `cleanup-staged-bill-attachments`, `create-bill` (`--payload`; set `isClaimable=false` for a bill, `isClaimable=true` for a claim; supplier bills require positive `extractedAmount` and `amount`, with `amount <= extractedAmount`; an already-paid supplier bill sets `alreadyPaid=true` and requires `paymentReference` plus a staged PDF in `paymentProofAttachments
|
|
179
|
+
| **Bills / claims** | `list-bills` (`--isClaimable false` for bills, `--isClaimable true` for claims, omit for both), `list-claims` (claims only), `validate-bill-selection` (`--payload`; runs the same supplier, line-item, and quotation-coverage checks as the web flow; `alreadyPaid` never bypasses them), `stage-bill-attachment` (securely uploads invoice/payment-proof files before creation and returns attachment JSON; ownership and one-hour expiry are enforced by a server-side staged-upload record rather than encoded in the object key), `cleanup-staged-bill-attachments`, `create-bill` (`--payload`; set `isClaimable=false` for a bill, `isClaimable=true` for a claim; supplier bills require positive `extractedAmount` and `amount`, with `amount <= extractedAmount`; an already-paid supplier bill sets `alreadyPaid=true` and requires `paymentReference` plus a staged PDF in `paymentProofAttachments`; admin creation automatically queues QBO finalization while other roles remain pending approval; non-legacy supplier bills from 1 Jul 2026 00:00 SGT require approved quotation coverage even when already paid), `update-bill` (`--payload`), `update-bill-payment-evidence` (`--payload`; replaces the payment reference and payment-proof PDFs for an already-paid bill), `delete-bill`, `create-bill-approval` (also sends approval request emails), `update-bill-status` (`PAID` requires `--paymentReference`; pass `--paymentProof <receipt.pdf>` to stage and submit a PDF up to 20MB atomically, or omit it only when BB already has payment proof; moving to `PAID` runs the server's paid-bill notification workflow), `patch-bill-payment` (PAID bills: `--paymentTrackingUrl`, `--paymentReference`, `--quickbooksBillId`, `--paymentDate` ISO; clearing a paid bill's QuickBooks link is not allowed), `patch-bill-invoice-number`, `get-bill-attachments`, `upload-bill-attachment` (`<billId>` + local path), `get-bill-details` |
|
|
91
180
|
| **Quotations** | `list-quotations` (supports project, budget, supplier, status, requester, and text-search filters), `get-quotation`, `upload-quotation-attachment` (`<projectId>` + PDF/JPEG/PNG path up to 20MB; returns attachment JSON for payload use), `cleanup-staged-quotation-attachments`, `create-quotation` (`--payload` for `quotation.createDraft`; include `amountWithoutGst` and `gstAmount`), `update-quotation` (`--payload`; updates a `DRAFT` or `REJECTED` quotation), `delete-quotation`, `submit-quotation`, `approve-quotation`, `reject-quotation`, `download-quotation-pdf` (`original`, `staff`, or `final`) |
|
|
92
|
-
| **Customer invoices** | `check-customer-invoice-readiness`, `list-customer-invoices`, `get-customer-invoice`, `create-customer-invoice`, `discard-customer-invoice`, `delete-customer-invoice`, `void-customer-invoice`, `approve-customer-invoice
|
|
181
|
+
| **Customer invoices** | `check-customer-invoice-readiness`, `list-eligible-customer-invoice-budgets`, `list-customer-invoices` (global/project/budget filters plus summary metrics), `get-customer-invoice`, `get-customer-invoice-email-context`, `create-customer-invoice`, `discard-customer-invoice`, `delete-customer-invoice`, `void-customer-invoice`, `approve-customer-invoice` (admin), `reject-customer-invoice` (admin), `send-customer-invoice-to-contact-person`, `mark-customer-invoice-paid` (admin; high-level proof upload + QBO Payment workflow), `download-customer-invoice-payment-proof`, `download-customer-invoice-pdf`, `sync-customer-invoice` |
|
|
93
182
|
| **Approvals** | `list-approvals` / `get-pending-approvals` (`--type budget\|supplier\|bill\|quotation\|customer_invoice\|all`), `approve-bill` / `reject-bill` (send reply email), `approve-budget` / `reject-budget` (send reply email), `approve-supplier` / `reject-supplier` (send reply email), `approve-quotation` / `reject-quotation`, `approve-customer-invoice` / `reject-customer-invoice` |
|
|
94
183
|
| **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), `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`) |
|
|
95
184
|
| **Contacts** | `list-contacts`, `create-contact-person` (`--payload`), `update-contact-person` (`--payload`) |
|
|
96
|
-
| **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
|
|
97
|
-
| **Dashboard & users** | `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` (
|
|
98
|
-
| **Errors** | `get-recent-errors`, `get-error-metrics` |
|
|
185
|
+
| **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`, `create-item` (`--payload`), `update-item` (`--payload`), `delete-item`, `get-item`, `list-item-categories`, `create-item-category` / `update-item-category` / `delete-item-categories` (admin; `--ids` CSV for delete) |
|
|
186
|
+
| **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) |
|
|
187
|
+
| **Errors (admin)** | `get-recent-errors`, `get-error-metrics` |
|
|
99
188
|
| **Automation (admin)** | `list-integration-operations`, `retry-integration-operation` |
|
|
100
189
|
| **Historical / benchmarks** | `get-approved-budgets`, `get-budget-category-benchmarks`, `get-item-pricing-history`, `get-supplier-pricing-history` |
|
|
101
190
|
|
|
@@ -103,10 +192,11 @@ The CLI intentionally wraps low-level upload-request/confirm procedures into fil
|
|
|
103
192
|
|
|
104
193
|
## Output
|
|
105
194
|
|
|
106
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **
|
|
109
|
-
- **
|
|
195
|
+
- **Canonical stdout:** a pretty-printed `{ "ok": true, "data": ..., "meta": ... }` JSON envelope
|
|
196
|
+
- **Canonical stderr:** a structured `{ "ok": false, "error": { "code", "message", ... }, "meta": ... }` JSON envelope on failure
|
|
197
|
+
- **Diagnostics:** off by default for canonical commands; use `--debug` for sanitized stderr tracing and `--quiet`, `-q`, or `BB_CLI_QUIET=1` to suppress diagnostics
|
|
198
|
+
- **Legacy compatibility:** flat aliases keep their raw success JSON, `{ "error": "..." }` failures, and default action tracing during the transition
|
|
199
|
+
- **Exit codes:** `0` success, `2` usage/validation/confirmation failure, `1` API/auth/network/internal failure, `130` interruption
|
|
110
200
|
|
|
111
201
|
A `.env` file in the **current working directory** is loaded automatically (for `BB_API_KEY`, etc.).
|
|
112
202
|
|
|
@@ -116,15 +206,15 @@ From the monorepo root (after `bun install`):
|
|
|
116
206
|
|
|
117
207
|
```bash
|
|
118
208
|
export BB_API_KEY=...
|
|
119
|
-
bun run
|
|
209
|
+
bun run golabs -- bb budget list
|
|
120
210
|
```
|
|
121
211
|
|
|
122
|
-
Or from `packages/cli`:
|
|
212
|
+
Or from `packages/budget-builder/cli`:
|
|
123
213
|
|
|
124
214
|
```bash
|
|
125
215
|
bun run build # emit dist/ via tsc
|
|
126
216
|
bun run typecheck # tsc --noEmit
|
|
127
|
-
bun run src/index.ts list
|
|
217
|
+
bun run src/index.ts budget list
|
|
128
218
|
```
|
|
129
219
|
|
|
130
220
|
### Layout
|
|
@@ -134,4 +224,13 @@ bun run src/index.ts list-budgets
|
|
|
134
224
|
|
|
135
225
|
### Publish
|
|
136
226
|
|
|
137
|
-
|
|
227
|
+
Build the package first, then create its publishable archive with Bun:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
bun run build
|
|
231
|
+
bun run pack:artifact
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
`pack:artifact` copies only the publish allowlist into a temporary staging directory and writes a sanitized publish manifest there. It never edits the source `package.json`, and the staged archive contains no workspace-only development dependencies. The release workflow packs once, validates the resulting archive, tests that exact tarball under Node and Bun, then publishes that exact tarball. Types from `@go-labs/budget-builder-api` are compile-time only (`import type`). Prisma enum **values** used at runtime live in `src/prisma-enums.ts` (kept in sync with `packages/budget-builder/db` generated enums) so npm installs do not need `@go-labs/budget-builder-db`.
|
|
235
|
+
|
|
236
|
+
The generated `command-reference.md` and `command-manifest.json` are release artifacts. Regenerate them whenever the command registry changes; the release workflow rejects a tarball that does not include both files.
|