@go-labs-sg/bb 2.44.0 → 2.45.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
@@ -508,6 +508,8 @@ Project and budget query payloads keep the Asana identities explicit: `asanaTask
508
508
 
509
509
  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.
510
510
 
511
+ Admin/Lead users can run `bb supplier approve <supplierId>` to directly re-approve a `REJECTED` supplier even when no pending approval request exists. This appends a new approval record and activity entry with the current responder/time, retains earlier approval and rejection history unchanged, and synchronizes QuickBooks; it does not send a requester reply email. Non-interactive direct re-approval requires `--allow-state-change --allow-external-write`, without `--allow-email`. An archived supplier remains archived and also needs Admin reactivation (`bb supplier reactivate --ids <supplierId>`) before new use. Reactivating alone does not change approval status. For a pending supplier, the command still resolves the current user's assigned request and queues the existing reply email.
512
+
511
513
  | Area | Legacy handler labels (reference only; non-exhaustive) |
512
514
  | --- | --- |
513
515
  | **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`) |
@@ -4795,7 +4795,7 @@
4795
4795
  {
4796
4796
  "path": ["supplier", "approve"],
4797
4797
  "legacyAliases": ["approve-supplier", "approve_supplier"],
4798
- "summary": "Approve Supplier.",
4798
+ "summary": "Approve a pending supplier request and send a requester reply email, or directly re-approve a rejected supplier as Admin/Lead without a pending request or email. QuickBooks is synchronized; archived suppliers remain archived. Argument: <supplierId>.",
4799
4799
  "globalOptions": [
4800
4800
  {
4801
4801
  "name": "--help",
@@ -833,7 +833,7 @@ Effects: state-change, email.
833
833
 
834
834
  ## `bb supplier approve`
835
835
 
836
- Approve Supplier.
836
+ Approve a pending supplier request and send a requester reply email, or directly re-approve a rejected supplier as Admin/Lead without a pending request or email. QuickBooks is synchronized; archived suppliers remain archived. Argument: <supplierId>.
837
837
 
838
838
  Legacy aliases: `approve-supplier`, `approve_supplier`.
839
839
 
package/dist/index.js CHANGED
@@ -8504,7 +8504,8 @@ var assertSensitiveWorkflowConfirmed = async (input) => {
8504
8504
  await confirmCurrentCommand({
8505
8505
  action: input.action,
8506
8506
  target: input.entity,
8507
- details: input.details
8507
+ details: input.details,
8508
+ effects: input.effects
8508
8509
  });
8509
8510
  return;
8510
8511
  }
@@ -9953,6 +9954,17 @@ async function getSupplierDetails(supplierId) {
9953
9954
  });
9954
9955
  }
9955
9956
  async function approveSupplier(supplierId) {
9957
+ const supplier = await api2.supplier.getSupplierById.query({ id: supplierId });
9958
+ if (supplier.status === ExtendedApprovalStatus.REJECTED) {
9959
+ await assertSensitiveWorkflowConfirmed({
9960
+ action: "Re-approve supplier",
9961
+ entity: `supplier ${supplierId}`,
9962
+ effects: ["state-change", "external-write"],
9963
+ details: supplier.active ? "and sync its details with QuickBooks; append a new approval and retain earlier history; no requester reply email is sent" : "and sync its details with QuickBooks; append a new approval and retain earlier history; it remains archived and no requester reply email is sent"
9964
+ });
9965
+ out(await api2.supplier.reapproveSupplier.mutate({ supplierId }));
9966
+ return;
9967
+ }
9956
9968
  await assertSensitiveWorkflowConfirmed({
9957
9969
  action: "Approve supplier",
9958
9970
  entity: `supplier ${supplierId}`,
@@ -10894,6 +10906,8 @@ var effectsFor = (legacyTarget) => {
10894
10906
  };
10895
10907
  var titleCase = (value) => value.split("-").map((word) => `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`).join(" ");
10896
10908
  var summaryFor = (legacyTarget) => {
10909
+ if (legacyTarget === "approve-supplier")
10910
+ return "Approve a pending supplier request and send a requester reply email, or directly re-approve a rejected supplier as Admin/Lead without a pending request or email. QuickBooks is synchronized; archived suppliers remain archived. Argument: <supplierId>.";
10897
10911
  if (legacyTarget === "search-existing-companies")
10898
10912
  return "Search BB and QuickBooks companies without writes. --query <name> [--page <number>].";
10899
10913
  if (legacyTarget === "use-existing-company")
@@ -11823,7 +11837,7 @@ Approvals
11823
11837
  reject-bill <billId> --reason <text> (also sends requester reply email)
11824
11838
  approve-budget <budgetId> (also sends requester reply email)
11825
11839
  reject-budget <budgetId> --reason <text> (also sends requester reply email)
11826
- approve-supplier <supplierId> (also sends requester reply email)
11840
+ approve-supplier <supplierId> (approve a pending request, or Admin/Lead re-approve a rejected supplier)
11827
11841
  reject-supplier <supplierId> --reason <text> (also sends requester reply email)
11828
11842
 
11829
11843
  Companies & projects
@@ -12258,7 +12272,7 @@ Waiting for approval\u2026
12258
12272
  }
12259
12273
  configureAccessToken(accessToken);
12260
12274
  }
12261
- if (!resolvedCommand.isLegacyAlias && cmd !== "create-bill" && cmd !== "import-qbo-customer-invoice" && resolvedCommand.command.effects.length > 0) {
12275
+ if (!resolvedCommand.isLegacyAlias && cmd !== "create-bill" && cmd !== "import-qbo-customer-invoice" && cmd !== "approve-supplier" && resolvedCommand.command.effects.length > 0) {
12262
12276
  await confirmCurrentCommand({
12263
12277
  action: resolvedCommand.command.path.join(" "),
12264
12278
  target: commandConfirmationTarget(resolvedCommand),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-labs-sg/bb",
3
- "version": "2.44.0",
3
+ "version": "2.45.0",
4
4
  "description": "Budget Builder CLI for AI agents — manage budgets, bills, claims, quotations, and customer invoices with explicit workflow previews for sensitive changes.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,7 +25,7 @@ The Budget Builder API, not the CLI, makes the final decision. A request may nee
25
25
  2. A sufficient current database role: `USER`, `INSIDE_SALES`, `LEAD`, `ACCOUNTING_TEAM`, or `ADMIN`. Pending approval assignment does not preserve decision authority after a role change.
26
26
  3. Access to the specific resource, commonly through creator ownership or project assignment as Business Development, Inside Sales, or Project Manager.
27
27
  4. A compatible resource state, such as a bill being `DRAFT` or `REJECTED` before editing.
28
- 5. A pending approval record assigned to the current user for approval decisions.
28
+ 5. A pending approval record assigned to the current user for request decisions. Direct Admin/Lead re-approval of a rejected supplier does not require a pending request.
29
29
  6. Required evidence and consistent related records, such as payment proof, approved quotation coverage, or matching project/budget IDs.
30
30
 
31
31
  Therefore, two users with the same role can receive different results for the same command and different resource IDs.
@@ -95,7 +95,8 @@ This table highlights the role-sensitive command groups an agent is most likely
95
95
  | `bb project hub status`, `bb project hub setup`, and `bb project hub sync` | `ADMIN`, project creator, or project assignment as Business Development, Inside Sales, or Project Manager. Setup and sync also enforce Project Hub lifecycle/readiness checks. |
96
96
  | `bb supplier update`, `bb item update`, `bb item category update` | Any active authenticated role. Normal-user supplier edits are submitted for approval by the shared API; item/category edits apply immediately. Human review and provider synchronization can temporarily block further supplier edits/new usage. |
97
97
  | Edit/delete a bill or quotation | Usually creator or `ADMIN`, with a supported status. |
98
- | `bb budget approve`, `bb budget reject`, `bb supplier approve`, and `bb supplier reject` | Current user must be the pending approver and currently have role `LEAD` or `ADMIN`. |
98
+ | `bb budget approve`, `bb budget reject`, and `bb supplier reject` | Current user must be the pending approver and currently have role `LEAD` or `ADMIN`. |
99
+ | `bb supplier approve` | `LEAD` or `ADMIN`. Pending suppliers require an assigned pending request; rejected suppliers can be directly re-approved without one. Re-approval preserves archive state and does not send a requester email. |
99
100
  | `bb bill approve` and `bb bill reject` | Current user must be the pending approver and currently have role `ACCOUNTING_TEAM` for the finance/check stage or `ADMIN` for the final approval stage. |
100
101
  | `bb quotation approve` and `bb quotation reject` | Current user must be the pending approver and currently have role `ADMIN`; a normal submitter cannot decide the quotation. |
101
102
  | `bb bill status update ... CHECKED` | `ACCOUNTING_TEAM` or `ADMIN`. |