@go-labs-sg/bb 3.1.0 → 3.2.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/command-manifest.json +28 -4
- package/command-reference.md +4 -4
- package/dist/index.js +47 -12
- package/package.json +1 -1
package/command-manifest.json
CHANGED
|
@@ -2317,7 +2317,7 @@
|
|
|
2317
2317
|
{
|
|
2318
2318
|
"path": ["bill", "create"],
|
|
2319
2319
|
"legacyAliases": ["create-bill", "create_bill"],
|
|
2320
|
-
"summary": "Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.",
|
|
2320
|
+
"summary": "Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.",
|
|
2321
2321
|
"globalOptions": [
|
|
2322
2322
|
{
|
|
2323
2323
|
"name": "--help",
|
|
@@ -2375,7 +2375,7 @@
|
|
|
2375
2375
|
{
|
|
2376
2376
|
"path": ["bill", "selection", "validate"],
|
|
2377
2377
|
"legacyAliases": ["validate-bill-selection", "validate_bill_selection"],
|
|
2378
|
-
"summary": "Validate the approved supplier and selected bill line items.",
|
|
2378
|
+
"summary": "Validate the approved supplier and selected bill line items. Supplier bills need approved quotation sources (quotationIds, legacy quotationId, or quotationAllocations with lineAmounts) for every line that is not quotation-exempt (Go Internal lines, or projects/budgets created before the quotation cutoff). With billId, lines already on the bill keep their stored sources unless new sources are supplied. Exemption is decided by the server, so there is no --quotation-exempt flag here. Amounts (amount, lineAmounts, quotationAllocations) are ex-GST dollars with at most 2 decimal places.",
|
|
2379
2379
|
"globalOptions": [
|
|
2380
2380
|
{
|
|
2381
2381
|
"name": "--help",
|
|
@@ -2491,7 +2491,7 @@
|
|
|
2491
2491
|
{
|
|
2492
2492
|
"path": ["bill", "update"],
|
|
2493
2493
|
"legacyAliases": ["update-bill", "update_bill"],
|
|
2494
|
-
"summary": "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.",
|
|
2494
|
+
"summary": "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.",
|
|
2495
2495
|
"globalOptions": [
|
|
2496
2496
|
{
|
|
2497
2497
|
"name": "--help",
|
|
@@ -10255,7 +10255,7 @@
|
|
|
10255
10255
|
{
|
|
10256
10256
|
"path": ["webhook", "delivery", "list"],
|
|
10257
10257
|
"legacyAliases": ["list-webhook-deliveries", "list_webhook_deliveries"],
|
|
10258
|
-
"summary": "
|
|
10258
|
+
"summary": "Admin-only: list webhook deliveries newest first. Returns { items, pageInfo }; follow pageInfo.nextCursor (or previousCursor with --direction backward). Cursors are opaque and filter-bound; raw delivery ids are rejected.",
|
|
10259
10259
|
"globalOptions": [
|
|
10260
10260
|
{
|
|
10261
10261
|
"name": "--help",
|
|
@@ -10296,6 +10296,30 @@
|
|
|
10296
10296
|
{
|
|
10297
10297
|
"name": "--allow-financial-write",
|
|
10298
10298
|
"description": "Allow financial-record changes in non-interactive use."
|
|
10299
|
+
},
|
|
10300
|
+
{
|
|
10301
|
+
"name": "--endpointId <id>",
|
|
10302
|
+
"description": "Only deliveries to this endpoint."
|
|
10303
|
+
},
|
|
10304
|
+
{
|
|
10305
|
+
"name": "--status <PENDING|SUCCEEDED|FAILED,...>",
|
|
10306
|
+
"description": "Comma-separated delivery statuses."
|
|
10307
|
+
},
|
|
10308
|
+
{
|
|
10309
|
+
"name": "--eventType <type>",
|
|
10310
|
+
"description": "Exact event type, e.g. bill.approved."
|
|
10311
|
+
},
|
|
10312
|
+
{
|
|
10313
|
+
"name": "--limit <n>",
|
|
10314
|
+
"description": "Rows per cursor page (1..100; default 20)."
|
|
10315
|
+
},
|
|
10316
|
+
{
|
|
10317
|
+
"name": "--cursor <token>",
|
|
10318
|
+
"description": "Opaque token from pageInfo.nextCursor or pageInfo.previousCursor; bound to the same filters."
|
|
10319
|
+
},
|
|
10320
|
+
{
|
|
10321
|
+
"name": "--direction <value>",
|
|
10322
|
+
"description": "forward or backward (default forward; backward requires cursor)."
|
|
10299
10323
|
}
|
|
10300
10324
|
],
|
|
10301
10325
|
"argumentMode": "legacy-passthrough",
|
package/command-reference.md
CHANGED
|
@@ -396,7 +396,7 @@ Effects: state-change, email.
|
|
|
396
396
|
|
|
397
397
|
## `bb bill create`
|
|
398
398
|
|
|
399
|
-
Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.
|
|
399
|
+
Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.
|
|
400
400
|
|
|
401
401
|
Legacy aliases: `create-bill`, `create_bill`.
|
|
402
402
|
|
|
@@ -409,7 +409,7 @@ Payload fields (--payload JSON)
|
|
|
409
409
|
|
|
410
410
|
## `bb bill selection validate`
|
|
411
411
|
|
|
412
|
-
Validate the approved supplier and selected bill line items.
|
|
412
|
+
Validate the approved supplier and selected bill line items. Supplier bills need approved quotation sources (quotationIds, legacy quotationId, or quotationAllocations with lineAmounts) for every line that is not quotation-exempt (Go Internal lines, or projects/budgets created before the quotation cutoff). With billId, lines already on the bill keep their stored sources unless new sources are supplied. Exemption is decided by the server, so there is no --quotation-exempt flag here. Amounts (amount, lineAmounts, quotationAllocations) are ex-GST dollars with at most 2 decimal places.
|
|
413
413
|
|
|
414
414
|
Legacy aliases: `validate-bill-selection`, `validate_bill_selection`.
|
|
415
415
|
|
|
@@ -435,7 +435,7 @@ Payload fields (--payload JSON)
|
|
|
435
435
|
|
|
436
436
|
## `bb bill update`
|
|
437
437
|
|
|
438
|
-
Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.
|
|
438
|
+
Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.
|
|
439
439
|
|
|
440
440
|
Legacy aliases: `update-bill`, `update_bill`.
|
|
441
441
|
|
|
@@ -1657,7 +1657,7 @@ Effects: state-change.
|
|
|
1657
1657
|
|
|
1658
1658
|
## `bb webhook delivery list`
|
|
1659
1659
|
|
|
1660
|
-
|
|
1660
|
+
Admin-only: list webhook deliveries newest first. Returns { items, pageInfo }; follow pageInfo.nextCursor (or previousCursor with --direction backward). Cursors are opaque and filter-bound; raw delivery ids are rejected.
|
|
1661
1661
|
|
|
1662
1662
|
Legacy aliases: `list-webhook-deliveries`, `list_webhook_deliveries`.
|
|
1663
1663
|
|
package/dist/index.js
CHANGED
|
@@ -7723,7 +7723,7 @@ var parseQuotationReferences = (input, commandName) => {
|
|
|
7723
7723
|
const allocation = requireObject(raw, label);
|
|
7724
7724
|
const amount = Number(allocation.amount);
|
|
7725
7725
|
if (!Number.isFinite(amount) || amount < 0 || !Number.isInteger(amount * 100)) {
|
|
7726
|
-
throw validationError(`${label}.amount must be a non-negative
|
|
7726
|
+
throw validationError(`${label}.amount must be a non-negative dollar amount (ex-GST) with at most 2 decimal places.`);
|
|
7727
7727
|
}
|
|
7728
7728
|
return {
|
|
7729
7729
|
budgetItemId: requiredString(allocation.budgetItemId, `${label}.budgetItemId`),
|
|
@@ -7776,7 +7776,7 @@ var parseBillLineAmounts = (input, commandName) => {
|
|
|
7776
7776
|
const line = requireObject(raw, label);
|
|
7777
7777
|
const amount = Number(line.amount);
|
|
7778
7778
|
if (!Number.isFinite(amount) || amount < 0 || !Number.isInteger(amount * 100)) {
|
|
7779
|
-
throw validationError(`${label}.amount must be a non-negative
|
|
7779
|
+
throw validationError(`${label}.amount must be a non-negative dollar amount (ex-GST) with at most 2 decimal places.`);
|
|
7780
7780
|
}
|
|
7781
7781
|
return {
|
|
7782
7782
|
budgetItemId: requiredString(line.budgetItemId, `${label}.budgetItemId`),
|
|
@@ -11473,6 +11473,8 @@ var summaryFor = (legacyTarget) => {
|
|
|
11473
11473
|
return "List one cursor page of active item categories ({ items, pageInfo }; --limit/--cursor/--direction, optional --name/--sortBy/--sortDir). --page/--perPage are rejected.";
|
|
11474
11474
|
if (legacyTarget === "count-item-categories")
|
|
11475
11475
|
return "Count active item categories matching --name: { totalCount }.";
|
|
11476
|
+
if (legacyTarget === "list-webhook-deliveries")
|
|
11477
|
+
return "Admin-only: list webhook deliveries newest first. Returns { items, pageInfo }; follow pageInfo.nextCursor (or previousCursor with --direction backward). Cursors are opaque and filter-bound; raw delivery ids are rejected.";
|
|
11476
11478
|
if (legacyTarget === "list-integration-operations")
|
|
11477
11479
|
return "List one cursor page of integration operations, newest first ({ items, pageInfo }; --limit/--cursor/--direction). --page/--perPage are rejected. Admin only.";
|
|
11478
11480
|
if (legacyTarget === "count-integration-operations")
|
|
@@ -11491,17 +11493,17 @@ var summaryFor = (legacyTarget) => {
|
|
|
11491
11493
|
return "Get budget details. Omit --includeInactive for active budgets only; --includeInactive is an Admin-only historical read.";
|
|
11492
11494
|
}
|
|
11493
11495
|
if (legacyTarget === "create-bill") {
|
|
11494
|
-
return "Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.";
|
|
11496
|
+
return "Create a bill or claim with an approved supplier. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. --draft-only guarantees DRAFT without email or external writes; otherwise unpaid creation skips email permission but keeps external-write permission.";
|
|
11495
11497
|
}
|
|
11496
11498
|
if (legacyTarget === "record-external-bill-payment")
|
|
11497
11499
|
return "Record an already-made payment on an APPROVED bill or claim, with no email and no money transfer. Requires <billId> --paymentReference --paymentDate YYYY-MM-DD --paymentAccount <QBO account ID> [--paymentProof receipt.pdf]. Reuses settled QBO payment links or queues one dated payment from the selected account. Exact retries are safe; do not pay again while reconciliation is pending.";
|
|
11498
11500
|
if (legacyTarget === "list-external-payment-accounts")
|
|
11499
11501
|
return "List active QuickBooks bank and credit-card account IDs for recording external payments (admin only).";
|
|
11500
11502
|
if (legacyTarget === "update-bill") {
|
|
11501
|
-
return "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.";
|
|
11503
|
+
return "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. If the selected quotations cannot split the bill amount across every selected line (a line without a quoted amount that cannot be derived from the quotation total), pass lineAmounts; updates that keep the same amount and lines reuse the existing line amounts. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.";
|
|
11502
11504
|
}
|
|
11503
11505
|
if (legacyTarget === "validate-bill-selection") {
|
|
11504
|
-
return "Validate the approved supplier and selected bill line items.";
|
|
11506
|
+
return "Validate the approved supplier and selected bill line items. Supplier bills need approved quotation sources (quotationIds, legacy quotationId, or quotationAllocations with lineAmounts) for every line that is not quotation-exempt (Go Internal lines, or projects/budgets created before the quotation cutoff). With billId, lines already on the bill keep their stored sources unless new sources are supplied. Exemption is decided by the server, so there is no --quotation-exempt flag here. Amounts (amount, lineAmounts, quotationAllocations) are ex-GST dollars with at most 2 decimal places.";
|
|
11505
11507
|
}
|
|
11506
11508
|
if (legacyTarget === "create-quotation") {
|
|
11507
11509
|
return 'Create a quotation with an approved supplier using --payload JSON. Include projectId, budgetId, supplierId, budgetItemIds, amountWithoutGst, gstAmount, and one uploaded attachment in attachments. Multiple budget items require lineAmounts: [{"budgetItemId":"<first-id>","amount":750},{"budgetItemId":"<second-id>","amount":450}], covering every selected budget-item ID exactly once and summing to amountWithoutGst. Amounts exclude GST; use gstAmount: 0 for no GST. Example: amountWithoutGst: 1200 with line amounts 750 and 450.';
|
|
@@ -12490,7 +12492,32 @@ var registry2 = [
|
|
|
12490
12492
|
legacyCommand("delete-webhook-endpoint", ["webhook", "endpoint", "delete"]),
|
|
12491
12493
|
legacyCommand("rotate-webhook-secret", ["webhook", "secret", "rotate"]),
|
|
12492
12494
|
legacyCommand("send-webhook-test-event", ["webhook", "endpoint", "test"]),
|
|
12493
|
-
legacyCommand("list-webhook-deliveries", ["webhook", "delivery", "list"]
|
|
12495
|
+
legacyCommand("list-webhook-deliveries", ["webhook", "delivery", "list"], [], [
|
|
12496
|
+
{
|
|
12497
|
+
name: "--endpointId <id>",
|
|
12498
|
+
description: "Only deliveries to this endpoint."
|
|
12499
|
+
},
|
|
12500
|
+
{
|
|
12501
|
+
name: "--status <PENDING|SUCCEEDED|FAILED,...>",
|
|
12502
|
+
description: "Comma-separated delivery statuses."
|
|
12503
|
+
},
|
|
12504
|
+
{
|
|
12505
|
+
name: "--eventType <type>",
|
|
12506
|
+
description: "Exact event type, e.g. bill.approved."
|
|
12507
|
+
},
|
|
12508
|
+
{
|
|
12509
|
+
name: "--limit <n>",
|
|
12510
|
+
description: "Rows per cursor page (1..100; default 20)."
|
|
12511
|
+
},
|
|
12512
|
+
{
|
|
12513
|
+
name: "--cursor <token>",
|
|
12514
|
+
description: "Opaque token from pageInfo.nextCursor or pageInfo.previousCursor; bound to the same filters."
|
|
12515
|
+
},
|
|
12516
|
+
{
|
|
12517
|
+
name: "--direction <value>",
|
|
12518
|
+
description: "forward or backward (default forward; backward requires cursor)."
|
|
12519
|
+
}
|
|
12520
|
+
]),
|
|
12494
12521
|
legacyCommand("get-webhook-delivery", ["webhook", "delivery", "get"]),
|
|
12495
12522
|
legacyCommand("replay-webhook-delivery", ["webhook", "delivery", "replay"]),
|
|
12496
12523
|
legacyCommand("list-inbound-sources", ["inbound", "source", "list"], [], [
|
|
@@ -13544,7 +13571,7 @@ Webhooks (admin)
|
|
|
13544
13571
|
delete-webhook-endpoint <endpointId>
|
|
13545
13572
|
rotate-webhook-secret <endpointId> [--previousSecretTtlHours <0-168>] (prints the new secret once)
|
|
13546
13573
|
send-webhook-test-event <endpointId>
|
|
13547
|
-
list-webhook-deliveries [--endpointId] [--status PENDING|SUCCEEDED|FAILED] [--eventType] [--cursor] [--
|
|
13574
|
+
list-webhook-deliveries [--endpointId] [--status <PENDING|SUCCEEDED|FAILED,...>] [--eventType] [--limit 1-100] [--cursor <token>] [--direction forward|backward] (newest first; prints items + pageInfo)
|
|
13548
13575
|
get-webhook-delivery <deliveryId> (attempts with response codes)
|
|
13549
13576
|
replay-webhook-delivery <deliveryId> (same eventId, new attempt chain)
|
|
13550
13577
|
|
|
@@ -15922,14 +15949,22 @@ Waiting for approval\u2026
|
|
|
15922
15949
|
break;
|
|
15923
15950
|
}
|
|
15924
15951
|
case "list-webhook-deliveries": {
|
|
15925
|
-
const
|
|
15926
|
-
|
|
15927
|
-
|
|
15952
|
+
const statuses = (getFlag(flags, "status") ?? "").split(",").map((value) => value.trim()).filter(Boolean);
|
|
15953
|
+
for (const status of statuses)
|
|
15954
|
+
if (status !== "PENDING" && status !== "SUCCEEDED" && status !== "FAILED")
|
|
15955
|
+
throw new Error("--status must be PENDING, SUCCEEDED or FAILED (comma-separated)");
|
|
15956
|
+
const cursor = getFlag(flags, "cursor");
|
|
15957
|
+
const direction = parseProjectDirection(getFlag(flags, "direction"));
|
|
15958
|
+
if (direction === "backward" && !cursor)
|
|
15959
|
+
throw new Error("--direction backward requires --cursor <token>.");
|
|
15928
15960
|
await listWebhookDeliveries({
|
|
15929
15961
|
endpointId: getFlag(flags, "endpointId"),
|
|
15930
|
-
|
|
15962
|
+
...statuses.length ? {
|
|
15963
|
+
status: statuses
|
|
15964
|
+
} : {},
|
|
15931
15965
|
eventType: getFlag(flags, "eventType"),
|
|
15932
|
-
cursor
|
|
15966
|
+
cursor,
|
|
15967
|
+
direction,
|
|
15933
15968
|
limit: parsePositiveIntFlag(getFlag(flags, "limit"), "--limit")
|
|
15934
15969
|
});
|
|
15935
15970
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@go-labs-sg/bb",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.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",
|