@go-labs-sg/bb 2.5.0 → 2.7.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
@@ -148,6 +148,33 @@ Run `bb version` before agent-driven work to record the installed package versio
148
148
 
149
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
150
 
151
+ ### Typeform inbound administration
152
+
153
+ Inbound collection administration requires an API key owned by an `ADMIN`.
154
+ Source and submission lists omit raw Typeform answers; fetching one submission
155
+ returns its complete retained payload, which may contain personal information.
156
+
157
+ ```bash
158
+ bb inbound source list
159
+ bb inbound source get <source-id>
160
+ bb inbound source update <source-id> --name "Website inbound" --allow-state-change
161
+ bb inbound submission list --sourceId <source-id>
162
+ bb inbound submission get <submission-id>
163
+ bb inbound mapping save <source-id> \
164
+ --payload '[{"canonicalField":"COMPANY_NAME","typeformFieldId":"field-id","typeformFieldRef":"company_name","required":true}]' \
165
+ --allow-state-change
166
+ bb inbound automation save <source-id> --payload '<automation-config-json>' --allow-state-change
167
+ bb inbound processing update <source-id> --mode SHADOW --enabled true --allow-state-change
168
+ ```
169
+
170
+ Mapping saves create and activate an immutable version. Automation configuration
171
+ stores Slack, Asana, and Google Calendar destinations without secrets. Processing
172
+ can remain in `SHADOW` to create durable plans without provider writes; use
173
+ `ACTIVE` only after disabling the matching n8n Typeform trigger. These commands
174
+ do not enable company, project, or QuickBooks creation.
175
+ Use `bb inbound source get` to inspect discovered Typeform field IDs and the
176
+ currently active mapping before saving a replacement version.
177
+
151
178
  ### Mutation safety
152
179
 
153
180
  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.
@@ -6459,6 +6459,377 @@
6459
6459
  "effects": ["state-change", "external-write"],
6460
6460
  "legacyTarget": "retry-integration-operation"
6461
6461
  },
6462
+ {
6463
+ "path": ["inbound", "source", "list"],
6464
+ "legacyAliases": ["list-inbound-sources", "list_inbound_sources"],
6465
+ "summary": "List inbound sources.",
6466
+ "globalOptions": [
6467
+ {
6468
+ "name": "--help",
6469
+ "description": "Show help for this command."
6470
+ },
6471
+ {
6472
+ "name": "--quiet",
6473
+ "description": "Suppress non-error diagnostics."
6474
+ },
6475
+ {
6476
+ "name": "--debug",
6477
+ "description": "Emit sanitized diagnostic traces."
6478
+ },
6479
+ {
6480
+ "name": "--api-url",
6481
+ "description": "Override the Budget Builder API base URL."
6482
+ },
6483
+ {
6484
+ "name": "--allow-state-change",
6485
+ "description": "Allow a Budget Builder state change in non-interactive use."
6486
+ },
6487
+ {
6488
+ "name": "--allow-email",
6489
+ "description": "Allow sending email in non-interactive use."
6490
+ },
6491
+ {
6492
+ "name": "--allow-external-write",
6493
+ "description": "Allow writes to external systems in non-interactive use."
6494
+ },
6495
+ {
6496
+ "name": "--allow-delete",
6497
+ "description": "Allow deleting data in non-interactive use."
6498
+ },
6499
+ {
6500
+ "name": "--allow-financial-write",
6501
+ "description": "Allow financial-record changes in non-interactive use."
6502
+ }
6503
+ ],
6504
+ "argumentMode": "legacy-passthrough",
6505
+ "effects": [],
6506
+ "legacyTarget": "list-inbound-sources"
6507
+ },
6508
+ {
6509
+ "path": ["inbound", "source", "get"],
6510
+ "legacyAliases": ["get-inbound-source", "get_inbound_source"],
6511
+ "summary": "Get inbound source.",
6512
+ "globalOptions": [
6513
+ {
6514
+ "name": "--help",
6515
+ "description": "Show help for this command."
6516
+ },
6517
+ {
6518
+ "name": "--quiet",
6519
+ "description": "Suppress non-error diagnostics."
6520
+ },
6521
+ {
6522
+ "name": "--debug",
6523
+ "description": "Emit sanitized diagnostic traces."
6524
+ },
6525
+ {
6526
+ "name": "--api-url",
6527
+ "description": "Override the Budget Builder API base URL."
6528
+ },
6529
+ {
6530
+ "name": "--allow-state-change",
6531
+ "description": "Allow a Budget Builder state change in non-interactive use."
6532
+ },
6533
+ {
6534
+ "name": "--allow-email",
6535
+ "description": "Allow sending email in non-interactive use."
6536
+ },
6537
+ {
6538
+ "name": "--allow-external-write",
6539
+ "description": "Allow writes to external systems in non-interactive use."
6540
+ },
6541
+ {
6542
+ "name": "--allow-delete",
6543
+ "description": "Allow deleting data in non-interactive use."
6544
+ },
6545
+ {
6546
+ "name": "--allow-financial-write",
6547
+ "description": "Allow financial-record changes in non-interactive use."
6548
+ }
6549
+ ],
6550
+ "argumentMode": "legacy-passthrough",
6551
+ "effects": [],
6552
+ "legacyTarget": "get-inbound-source"
6553
+ },
6554
+ {
6555
+ "path": ["inbound", "source", "update"],
6556
+ "legacyAliases": ["update-inbound-source", "update_inbound_source"],
6557
+ "summary": "Update Inbound Source.",
6558
+ "globalOptions": [
6559
+ {
6560
+ "name": "--help",
6561
+ "description": "Show help for this command."
6562
+ },
6563
+ {
6564
+ "name": "--quiet",
6565
+ "description": "Suppress non-error diagnostics."
6566
+ },
6567
+ {
6568
+ "name": "--debug",
6569
+ "description": "Emit sanitized diagnostic traces."
6570
+ },
6571
+ {
6572
+ "name": "--api-url",
6573
+ "description": "Override the Budget Builder API base URL."
6574
+ },
6575
+ {
6576
+ "name": "--allow-state-change",
6577
+ "description": "Allow a Budget Builder state change in non-interactive use."
6578
+ },
6579
+ {
6580
+ "name": "--allow-email",
6581
+ "description": "Allow sending email in non-interactive use."
6582
+ },
6583
+ {
6584
+ "name": "--allow-external-write",
6585
+ "description": "Allow writes to external systems in non-interactive use."
6586
+ },
6587
+ {
6588
+ "name": "--allow-delete",
6589
+ "description": "Allow deleting data in non-interactive use."
6590
+ },
6591
+ {
6592
+ "name": "--allow-financial-write",
6593
+ "description": "Allow financial-record changes in non-interactive use."
6594
+ }
6595
+ ],
6596
+ "argumentMode": "legacy-passthrough",
6597
+ "effects": ["state-change"],
6598
+ "legacyTarget": "update-inbound-source"
6599
+ },
6600
+ {
6601
+ "path": ["inbound", "submission", "list"],
6602
+ "legacyAliases": ["list-inbound-submissions", "list_inbound_submissions"],
6603
+ "summary": "List inbound submissions.",
6604
+ "globalOptions": [
6605
+ {
6606
+ "name": "--help",
6607
+ "description": "Show help for this command."
6608
+ },
6609
+ {
6610
+ "name": "--quiet",
6611
+ "description": "Suppress non-error diagnostics."
6612
+ },
6613
+ {
6614
+ "name": "--debug",
6615
+ "description": "Emit sanitized diagnostic traces."
6616
+ },
6617
+ {
6618
+ "name": "--api-url",
6619
+ "description": "Override the Budget Builder API base URL."
6620
+ },
6621
+ {
6622
+ "name": "--allow-state-change",
6623
+ "description": "Allow a Budget Builder state change in non-interactive use."
6624
+ },
6625
+ {
6626
+ "name": "--allow-email",
6627
+ "description": "Allow sending email in non-interactive use."
6628
+ },
6629
+ {
6630
+ "name": "--allow-external-write",
6631
+ "description": "Allow writes to external systems in non-interactive use."
6632
+ },
6633
+ {
6634
+ "name": "--allow-delete",
6635
+ "description": "Allow deleting data in non-interactive use."
6636
+ },
6637
+ {
6638
+ "name": "--allow-financial-write",
6639
+ "description": "Allow financial-record changes in non-interactive use."
6640
+ }
6641
+ ],
6642
+ "argumentMode": "legacy-passthrough",
6643
+ "effects": [],
6644
+ "legacyTarget": "list-inbound-submissions"
6645
+ },
6646
+ {
6647
+ "path": ["inbound", "submission", "get"],
6648
+ "legacyAliases": ["get-inbound-submission", "get_inbound_submission"],
6649
+ "summary": "Get inbound submission.",
6650
+ "globalOptions": [
6651
+ {
6652
+ "name": "--help",
6653
+ "description": "Show help for this command."
6654
+ },
6655
+ {
6656
+ "name": "--quiet",
6657
+ "description": "Suppress non-error diagnostics."
6658
+ },
6659
+ {
6660
+ "name": "--debug",
6661
+ "description": "Emit sanitized diagnostic traces."
6662
+ },
6663
+ {
6664
+ "name": "--api-url",
6665
+ "description": "Override the Budget Builder API base URL."
6666
+ },
6667
+ {
6668
+ "name": "--allow-state-change",
6669
+ "description": "Allow a Budget Builder state change in non-interactive use."
6670
+ },
6671
+ {
6672
+ "name": "--allow-email",
6673
+ "description": "Allow sending email in non-interactive use."
6674
+ },
6675
+ {
6676
+ "name": "--allow-external-write",
6677
+ "description": "Allow writes to external systems in non-interactive use."
6678
+ },
6679
+ {
6680
+ "name": "--allow-delete",
6681
+ "description": "Allow deleting data in non-interactive use."
6682
+ },
6683
+ {
6684
+ "name": "--allow-financial-write",
6685
+ "description": "Allow financial-record changes in non-interactive use."
6686
+ }
6687
+ ],
6688
+ "argumentMode": "legacy-passthrough",
6689
+ "effects": [],
6690
+ "legacyTarget": "get-inbound-submission"
6691
+ },
6692
+ {
6693
+ "path": ["inbound", "mapping", "save"],
6694
+ "legacyAliases": ["save-inbound-mapping", "save_inbound_mapping"],
6695
+ "summary": "Save Inbound Mapping.",
6696
+ "globalOptions": [
6697
+ {
6698
+ "name": "--help",
6699
+ "description": "Show help for this command."
6700
+ },
6701
+ {
6702
+ "name": "--quiet",
6703
+ "description": "Suppress non-error diagnostics."
6704
+ },
6705
+ {
6706
+ "name": "--debug",
6707
+ "description": "Emit sanitized diagnostic traces."
6708
+ },
6709
+ {
6710
+ "name": "--api-url",
6711
+ "description": "Override the Budget Builder API base URL."
6712
+ },
6713
+ {
6714
+ "name": "--allow-state-change",
6715
+ "description": "Allow a Budget Builder state change in non-interactive use."
6716
+ },
6717
+ {
6718
+ "name": "--allow-email",
6719
+ "description": "Allow sending email in non-interactive use."
6720
+ },
6721
+ {
6722
+ "name": "--allow-external-write",
6723
+ "description": "Allow writes to external systems in non-interactive use."
6724
+ },
6725
+ {
6726
+ "name": "--allow-delete",
6727
+ "description": "Allow deleting data in non-interactive use."
6728
+ },
6729
+ {
6730
+ "name": "--allow-financial-write",
6731
+ "description": "Allow financial-record changes in non-interactive use."
6732
+ }
6733
+ ],
6734
+ "argumentMode": "legacy-passthrough",
6735
+ "effects": ["state-change"],
6736
+ "legacyTarget": "save-inbound-mapping"
6737
+ },
6738
+ {
6739
+ "path": ["inbound", "automation", "save"],
6740
+ "legacyAliases": [
6741
+ "save-inbound-automation-config",
6742
+ "save_inbound_automation_config"
6743
+ ],
6744
+ "summary": "Save Inbound Automation Config.",
6745
+ "globalOptions": [
6746
+ {
6747
+ "name": "--help",
6748
+ "description": "Show help for this command."
6749
+ },
6750
+ {
6751
+ "name": "--quiet",
6752
+ "description": "Suppress non-error diagnostics."
6753
+ },
6754
+ {
6755
+ "name": "--debug",
6756
+ "description": "Emit sanitized diagnostic traces."
6757
+ },
6758
+ {
6759
+ "name": "--api-url",
6760
+ "description": "Override the Budget Builder API base URL."
6761
+ },
6762
+ {
6763
+ "name": "--allow-state-change",
6764
+ "description": "Allow a Budget Builder state change in non-interactive use."
6765
+ },
6766
+ {
6767
+ "name": "--allow-email",
6768
+ "description": "Allow sending email in non-interactive use."
6769
+ },
6770
+ {
6771
+ "name": "--allow-external-write",
6772
+ "description": "Allow writes to external systems in non-interactive use."
6773
+ },
6774
+ {
6775
+ "name": "--allow-delete",
6776
+ "description": "Allow deleting data in non-interactive use."
6777
+ },
6778
+ {
6779
+ "name": "--allow-financial-write",
6780
+ "description": "Allow financial-record changes in non-interactive use."
6781
+ }
6782
+ ],
6783
+ "argumentMode": "legacy-passthrough",
6784
+ "effects": ["state-change"],
6785
+ "legacyTarget": "save-inbound-automation-config"
6786
+ },
6787
+ {
6788
+ "path": ["inbound", "processing", "update"],
6789
+ "legacyAliases": ["update-inbound-processing", "update_inbound_processing"],
6790
+ "summary": "Update Inbound Processing.",
6791
+ "globalOptions": [
6792
+ {
6793
+ "name": "--help",
6794
+ "description": "Show help for this command."
6795
+ },
6796
+ {
6797
+ "name": "--quiet",
6798
+ "description": "Suppress non-error diagnostics."
6799
+ },
6800
+ {
6801
+ "name": "--debug",
6802
+ "description": "Emit sanitized diagnostic traces."
6803
+ },
6804
+ {
6805
+ "name": "--api-url",
6806
+ "description": "Override the Budget Builder API base URL."
6807
+ },
6808
+ {
6809
+ "name": "--allow-state-change",
6810
+ "description": "Allow a Budget Builder state change in non-interactive use."
6811
+ },
6812
+ {
6813
+ "name": "--allow-email",
6814
+ "description": "Allow sending email in non-interactive use."
6815
+ },
6816
+ {
6817
+ "name": "--allow-external-write",
6818
+ "description": "Allow writes to external systems in non-interactive use."
6819
+ },
6820
+ {
6821
+ "name": "--allow-delete",
6822
+ "description": "Allow deleting data in non-interactive use."
6823
+ },
6824
+ {
6825
+ "name": "--allow-financial-write",
6826
+ "description": "Allow financial-record changes in non-interactive use."
6827
+ }
6828
+ ],
6829
+ "argumentMode": "legacy-passthrough",
6830
+ "effects": ["state-change"],
6831
+ "legacyTarget": "update-inbound-processing"
6832
+ },
6462
6833
  {
6463
6834
  "path": ["budget", "approved", "list"],
6464
6835
  "legacyAliases": ["get-approved-budgets", "get_approved_budgets"],
@@ -1128,6 +1128,70 @@ Legacy aliases: `retry-integration-operation`, `retry_integration_operation`.
1128
1128
 
1129
1129
  Effects: state-change, external-write.
1130
1130
 
1131
+ ## `bb inbound source list`
1132
+
1133
+ List inbound sources.
1134
+
1135
+ Legacy aliases: `list-inbound-sources`, `list_inbound_sources`.
1136
+
1137
+ Effects: none.
1138
+
1139
+ ## `bb inbound source get`
1140
+
1141
+ Get inbound source.
1142
+
1143
+ Legacy aliases: `get-inbound-source`, `get_inbound_source`.
1144
+
1145
+ Effects: none.
1146
+
1147
+ ## `bb inbound source update`
1148
+
1149
+ Update Inbound Source.
1150
+
1151
+ Legacy aliases: `update-inbound-source`, `update_inbound_source`.
1152
+
1153
+ Effects: state-change.
1154
+
1155
+ ## `bb inbound submission list`
1156
+
1157
+ List inbound submissions.
1158
+
1159
+ Legacy aliases: `list-inbound-submissions`, `list_inbound_submissions`.
1160
+
1161
+ Effects: none.
1162
+
1163
+ ## `bb inbound submission get`
1164
+
1165
+ Get inbound submission.
1166
+
1167
+ Legacy aliases: `get-inbound-submission`, `get_inbound_submission`.
1168
+
1169
+ Effects: none.
1170
+
1171
+ ## `bb inbound mapping save`
1172
+
1173
+ Save Inbound Mapping.
1174
+
1175
+ Legacy aliases: `save-inbound-mapping`, `save_inbound_mapping`.
1176
+
1177
+ Effects: state-change.
1178
+
1179
+ ## `bb inbound automation save`
1180
+
1181
+ Save Inbound Automation Config.
1182
+
1183
+ Legacy aliases: `save-inbound-automation-config`, `save_inbound_automation_config`.
1184
+
1185
+ Effects: state-change.
1186
+
1187
+ ## `bb inbound processing update`
1188
+
1189
+ Update Inbound Processing.
1190
+
1191
+ Legacy aliases: `update-inbound-processing`, `update_inbound_processing`.
1192
+
1193
+ Effects: state-change.
1194
+
1131
1195
  ## `bb budget approved list`
1132
1196
 
1133
1197
  Get approved budgets.
package/dist/commands.js CHANGED
@@ -2096,6 +2096,44 @@ export const retryIntegrationOperation = async (operationId, confirmExternalStat
2096
2096
  });
2097
2097
  out(result);
2098
2098
  };
2099
+ // --- Typeform inbound administration ---
2100
+ export const listInboundSources = async (input) => {
2101
+ const result = await api.inbound.listSources.query(input);
2102
+ out(result);
2103
+ };
2104
+ export const getInboundSource = async (sourceId) => {
2105
+ const result = await api.inbound.getSource.query({ sourceId });
2106
+ out(result);
2107
+ };
2108
+ export const updateInboundSource = async (sourceId, name) => {
2109
+ const result = await api.inbound.updateSource.mutate({ name, sourceId });
2110
+ out(result);
2111
+ };
2112
+ export const listInboundSubmissions = async (input) => {
2113
+ const result = await api.inbound.listSubmissions.query(input);
2114
+ out(result);
2115
+ };
2116
+ export const getInboundSubmission = async (submissionId) => {
2117
+ const result = await api.inbound.getSubmission.query({ submissionId });
2118
+ out(result);
2119
+ };
2120
+ export const saveInboundMappingVersion = async (sourceId, mappings) => {
2121
+ const source = await api.inbound.getSource.query({ sourceId });
2122
+ const result = await api.inbound.saveMappingVersion.mutate({
2123
+ expectedActiveMappingVersion: source.activeMappingVersion,
2124
+ mappings,
2125
+ sourceId,
2126
+ });
2127
+ out(result);
2128
+ };
2129
+ export const saveInboundAutomationConfig = async (input) => {
2130
+ const result = await api.inbound.saveAutomationConfig.mutate(input);
2131
+ out(result);
2132
+ };
2133
+ export const updateInboundProcessing = async (input) => {
2134
+ const result = await api.inbound.updateProcessing.mutate(input);
2135
+ out(result);
2136
+ };
2099
2137
  // --- Contacts ---
2100
2138
  export async function listContacts(companyId) {
2101
2139
  const contacts = await api.contactPerson.getContactPersonByCompanyId.query({
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { BUDGET_BUILDER_API_BASE_URL, configureBudgetBuilderApiBaseUrl, DEFAULT_BUDGET_BUILDER_API_BASE_URL, requireApiKey, } from "./api-client.js";
7
7
  import { consumeCliQuietFlags, logCliAction, sanitizeFlagsForTrace, setCliQuiet, shouldLogCliActions, } from "./cli-trace.js";
8
- import { addBudgetItems, approveBill, approveBudget, approveCustomerInvoice, approveQuotation, approveSupplier, archiveItemsByIds, checkCustomerInvoiceReadiness, checkProjectReconciliation, cleanupStagedBillAttachments, cleanupStagedQuotationAttachments, completeProject, createApiKeyForUser, createBillApproval, createBillFromPayload, createBudgetApproval, createBudgetCategory, createBudgetFromPayload, createCompany, createContactPersonFromPayload, createCustomerInvoice, createEstimate, createItemCategory, createItemFromPayload, createPlaceholderBillForBudgetItem, createProject, createQuotationFromPayload, createSupplierCertification, createSupplierFromPayload, createSupplierPaymentMethod, createSupplierRoleOption, createSupplierTagOption, createUser, deleteBillById, deleteBudgetById, deleteBudgetCategory, deleteBudgetCommission, deleteBudgetDiscount, deleteCompanyById, deleteCustomerInvoice, deleteItemById, deleteItemCategoriesByIds, deleteProjectById, deleteQuotationById, deleteSuppliersByIds, discardCreatingCustomerInvoice, downloadCustomerInvoicePaymentProof, downloadCustomerInvoicePdf, downloadQuotationPdf, getApprovedBudgets, getBillAttachments, getBillDetails, getBudget, getBudgetCategories, getBudgetCategoryBenchmarks, getBudgetDetails, getBudgetItemsOnly, getBudgetVersions, getCompany, getCustomerInvoice, getCustomerInvoiceEmailContext, getDashboard, getErrorMetrics, getEstimatePerformance, getFinancialOverview, getItem, getItemPricingHistory, getMonthlyMetrics, getProject, getQuotationDetails, getRecentErrors, getSupplierAnalytics, getSupplierDetails, getSupplierPricingHistory, getSystemOverview, getUserPerformance, importQuickBooksProjectId, listApiKeysForUser, listApprovals, listBills, listBudgets, listCompanies, listContacts, listCustomerInvoices, listEligibleCustomerInvoiceBudgets, listIntegrationOperations, listItemCategories, listItems, listProjects, listQuotations, listSuppliers, listUsers, markBudgetWonWithProof, markCustomerInvoicePaidFromPath, patchBillInvoiceNumber, patchBillPayment, reactivateSuppliersByIds, reconcileProject, rejectBill, rejectBudget, rejectCustomerInvoice, rejectQuotation, rejectSupplier, removeBudgetItem, renameBudgetVersion, reorderBudgetItemsCli, restoreBudgetVersion, retryIntegrationOperation, revokeApiKeyForUser, sendCustomerInvoiceToContactPersonFromPayload, sendEstimateToContactPersonFromPayload, setBudgetItemsNotUtilized, stageBillAttachmentsFromPaths, submitQuotation, syncCustomerInvoice, updateBillFromPayload, updateBillPaymentEvidenceFromPayload, updateBillStatus, updateBudgetCategory, updateBudgetCommissionFromPayload, updateBudgetDiscountFromPayload, updateBudgetFromPayload, updateBudgetItem, updateBudgetItemSupplierCli, updateBudgetStatus, updateCompanyFromPayload, updateContactPersonFromPayload, updateItemCategory, updateItemFromPayload, updateProjectFromPayload, updateProjectStatus, updateQuotationFromPayload, updateSupplierFromPayload, uploadBillAttachmentFromPath, uploadBillAttachmentsFromPaths, uploadBillDocumentsFromPaths, uploadBudgetAttachmentFromPath, uploadQuotationAttachmentFromPath, validateBillSelectionFromPayload, voidCustomerInvoice, whoAmI, } from "./commands.js";
8
+ import { addBudgetItems, approveBill, approveBudget, approveCustomerInvoice, approveQuotation, approveSupplier, archiveItemsByIds, checkCustomerInvoiceReadiness, checkProjectReconciliation, cleanupStagedBillAttachments, cleanupStagedQuotationAttachments, completeProject, createApiKeyForUser, createBillApproval, createBillFromPayload, createBudgetApproval, createBudgetCategory, createBudgetFromPayload, createCompany, createContactPersonFromPayload, createCustomerInvoice, createEstimate, createItemCategory, createItemFromPayload, createPlaceholderBillForBudgetItem, createProject, createQuotationFromPayload, createSupplierCertification, createSupplierFromPayload, createSupplierPaymentMethod, createSupplierRoleOption, createSupplierTagOption, createUser, deleteBillById, deleteBudgetById, deleteBudgetCategory, deleteBudgetCommission, deleteBudgetDiscount, deleteCompanyById, deleteCustomerInvoice, deleteItemById, deleteItemCategoriesByIds, deleteProjectById, deleteQuotationById, deleteSuppliersByIds, discardCreatingCustomerInvoice, downloadCustomerInvoicePaymentProof, downloadCustomerInvoicePdf, downloadQuotationPdf, getApprovedBudgets, getBillAttachments, getBillDetails, getBudget, getBudgetCategories, getBudgetCategoryBenchmarks, getBudgetDetails, getBudgetItemsOnly, getBudgetVersions, getCompany, getCustomerInvoice, getCustomerInvoiceEmailContext, getDashboard, getErrorMetrics, getEstimatePerformance, getFinancialOverview, getInboundSource, getInboundSubmission, getItem, getItemPricingHistory, getMonthlyMetrics, getProject, getQuotationDetails, getRecentErrors, getSupplierAnalytics, getSupplierDetails, getSupplierPricingHistory, getSystemOverview, getUserPerformance, importQuickBooksProjectId, listApiKeysForUser, listApprovals, listBills, listBudgets, listCompanies, listContacts, listCustomerInvoices, listEligibleCustomerInvoiceBudgets, listInboundSources, listInboundSubmissions, listIntegrationOperations, listItemCategories, listItems, listProjects, listQuotations, listSuppliers, listUsers, markBudgetWonWithProof, markCustomerInvoicePaidFromPath, patchBillInvoiceNumber, patchBillPayment, reactivateSuppliersByIds, reconcileProject, rejectBill, rejectBudget, rejectCustomerInvoice, rejectQuotation, rejectSupplier, removeBudgetItem, renameBudgetVersion, reorderBudgetItemsCli, restoreBudgetVersion, retryIntegrationOperation, revokeApiKeyForUser, saveInboundAutomationConfig, saveInboundMappingVersion, sendCustomerInvoiceToContactPersonFromPayload, sendEstimateToContactPersonFromPayload, setBudgetItemsNotUtilized, stageBillAttachmentsFromPaths, submitQuotation, syncCustomerInvoice, updateBillFromPayload, updateBillPaymentEvidenceFromPayload, updateBillStatus, updateBudgetCategory, updateBudgetCommissionFromPayload, updateBudgetDiscountFromPayload, updateBudgetFromPayload, updateBudgetItem, updateBudgetItemSupplierCli, updateBudgetStatus, updateCompanyFromPayload, updateContactPersonFromPayload, updateInboundProcessing, updateInboundSource, updateItemCategory, updateItemFromPayload, updateProjectFromPayload, updateProjectStatus, updateQuotationFromPayload, updateSupplierFromPayload, uploadBillAttachmentFromPath, uploadBillAttachmentsFromPaths, uploadBillDocumentsFromPaths, uploadBudgetAttachmentFromPath, uploadQuotationAttachmentFromPath, validateBillSelectionFromPayload, voidCustomerInvoice, whoAmI, } from "./commands.js";
9
9
  import { getFlag, parseArgs } from "./parse-args.js";
10
10
  import { billStatusesForUpdateHelp, budgetStatusesForHelp, isBudgetStatusUpdate, parseApprovalTypeFlag, parseBillStatusForUpdate, parseCommaSeparatedBillStatuses, parseCommaSeparatedBudgetStatuses, parseCommaSeparatedCustomerInvoiceStatuses, parseCommaSeparatedIds, parseCommaSeparatedQuotationStatuses, parseCommaSeparatedSupplierStatuses, parseOptionalBillListSortBy, parseOptionalBillListSortDir, parseOptionalDashboardRole, parseOptionalDeals, parseOptionalErrorSeverity, parseOptionalErrorStatus, parseOptionalExtendedProjectStatus, parseOptionalFinancialRole, parseOptionalSupplierAnalyticsTimeFrame, parseOptionalTimeFrame, parseProjectStatusForUpdate, parseUserRole, projectStatusesForHelp, userRolesForHelp, } from "./parse-cli-enums.js";
11
11
  import { parseJsonFlag, parseOptionalNumber as parseOptNum, } from "./parse-json-flag.js";
@@ -2027,6 +2027,82 @@ export async function runCli(argv = process.argv, runtime = createProcessRuntime
2027
2027
  false);
2028
2028
  break;
2029
2029
  }
2030
+ case "list-inbound-sources": {
2031
+ await listInboundSources({
2032
+ page: parsePositiveIntFlag(getFlag(flags, "page"), "--page") ?? 1,
2033
+ perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage") ?? 25,
2034
+ });
2035
+ break;
2036
+ }
2037
+ case "get-inbound-source": {
2038
+ const sourceId = positional[0];
2039
+ if (!sourceId)
2040
+ throw new Error("get-inbound-source requires <sourceId>");
2041
+ await getInboundSource(sourceId);
2042
+ break;
2043
+ }
2044
+ case "update-inbound-source": {
2045
+ const sourceId = positional[0];
2046
+ const name = getFlag(flags, "name");
2047
+ if (!sourceId || !name) {
2048
+ throw new Error("update-inbound-source requires <sourceId> --name <name>");
2049
+ }
2050
+ await updateInboundSource(sourceId, name);
2051
+ break;
2052
+ }
2053
+ case "list-inbound-submissions": {
2054
+ await listInboundSubmissions({
2055
+ page: parsePositiveIntFlag(getFlag(flags, "page"), "--page") ?? 1,
2056
+ perPage: parsePositiveIntFlag(getFlag(flags, "perPage"), "--perPage") ?? 25,
2057
+ sourceId: getFlag(flags, "sourceId"),
2058
+ });
2059
+ break;
2060
+ }
2061
+ case "get-inbound-submission": {
2062
+ const submissionId = positional[0];
2063
+ if (!submissionId) {
2064
+ throw new Error("get-inbound-submission requires <submissionId>");
2065
+ }
2066
+ await getInboundSubmission(submissionId);
2067
+ break;
2068
+ }
2069
+ case "save-inbound-mapping": {
2070
+ const sourceId = positional[0];
2071
+ const payloadRaw = getFlag(flags, "payload");
2072
+ if (!sourceId || payloadRaw === undefined) {
2073
+ throw new Error("save-inbound-mapping requires <sourceId> --payload <JSON array>");
2074
+ }
2075
+ const mappings = parseJsonFlag(String(payloadRaw), "--payload");
2076
+ await saveInboundMappingVersion(sourceId, mappings);
2077
+ break;
2078
+ }
2079
+ case "save-inbound-automation-config": {
2080
+ const sourceId = positional[0];
2081
+ const payloadRaw = getFlag(flags, "payload");
2082
+ if (!sourceId || payloadRaw === undefined) {
2083
+ throw new Error("save-inbound-automation-config requires <sourceId> --payload <JSON object>");
2084
+ }
2085
+ const config = parseJsonFlag(String(payloadRaw), "--payload");
2086
+ await saveInboundAutomationConfig({ ...config, sourceId });
2087
+ break;
2088
+ }
2089
+ case "update-inbound-processing": {
2090
+ const sourceId = positional[0];
2091
+ const mode = getFlag(flags, "mode");
2092
+ const enabled = parseOptionalBoolFlag(flags, "enabled");
2093
+ if (!sourceId ||
2094
+ !mode ||
2095
+ enabled === undefined ||
2096
+ !["COLLECT_ONLY", "SHADOW", "ACTIVE"].includes(String(mode))) {
2097
+ throw new Error("update-inbound-processing requires <sourceId> --mode COLLECT_ONLY|SHADOW|ACTIVE --enabled true|false");
2098
+ }
2099
+ await updateInboundProcessing({
2100
+ processingEnabled: enabled,
2101
+ processingMode: String(mode),
2102
+ sourceId,
2103
+ });
2104
+ break;
2105
+ }
2030
2106
  case "get-approved-budgets": {
2031
2107
  await getApprovedBudgets({
2032
2108
  projectId: getFlag(flags, "projectId"),
@@ -56,6 +56,7 @@ const mutationPrefixes = [
56
56
  "restore-",
57
57
  "retry-",
58
58
  "revoke-",
59
+ "save-",
59
60
  "send-",
60
61
  "stage-",
61
62
  "submit-",
@@ -447,6 +448,22 @@ const registry = [
447
448
  "operation",
448
449
  "retry",
449
450
  ]),
451
+ legacyCommand("list-inbound-sources", ["inbound", "source", "list"]),
452
+ legacyCommand("get-inbound-source", ["inbound", "source", "get"]),
453
+ legacyCommand("update-inbound-source", ["inbound", "source", "update"]),
454
+ legacyCommand("list-inbound-submissions", ["inbound", "submission", "list"]),
455
+ legacyCommand("get-inbound-submission", ["inbound", "submission", "get"]),
456
+ legacyCommand("save-inbound-mapping", ["inbound", "mapping", "save"]),
457
+ legacyCommand("save-inbound-automation-config", [
458
+ "inbound",
459
+ "automation",
460
+ "save",
461
+ ]),
462
+ legacyCommand("update-inbound-processing", [
463
+ "inbound",
464
+ "processing",
465
+ "update",
466
+ ]),
450
467
  legacyCommand("get-approved-budgets", ["budget", "approved", "list"]),
451
468
  legacyCommand("get-budget-category-benchmarks", [
452
469
  "budget",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@go-labs-sg/bb",
3
- "version": "2.5.0",
3
+ "version": "2.7.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",