jaz-clio 5.4.32 → 5.4.33

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-api
3
- version: 5.4.32
3
+ version: 5.4.33
4
4
  description: >-
5
5
  Use this skill whenever you call, debug, or review code that touches the Jaz
6
6
  REST API. Covers field names, response shapes, 141 production gotchas, error
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-cli
3
- version: 5.4.32
3
+ version: 5.4.33
4
4
  description: >-
5
5
  Use this skill when running Clio CLI commands, building shell scripts with
6
6
  Clio, debugging auth issues, understanding --json output, paginating results,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-conversion
3
- version: 5.4.32
3
+ version: 5.4.33
4
4
  description: >-
5
5
  Use this skill when migrating accounting data into Jaz — importing from Xero,
6
6
  QuickBooks, Sage, MYOB, or Excel exports. Covers the full conversion pipeline:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-jobs
3
- version: 5.4.32
3
+ version: 5.4.33
4
4
  description: >-
5
5
  Use this skill for recurring accounting workflows — month/quarter/year-end
6
6
  close, bank reconciliation, GST/VAT filing, payment runs, credit control,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-practice
3
- version: 5.4.32
3
+ version: 5.4.33
4
4
  description: >-
5
5
  Use this skill whenever an accounting practitioner is doing client work in
6
6
  Jaz — closing the books, filing GST, year-end statutory, onboarding a new
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-recipes
3
- version: 5.4.32
3
+ version: 5.4.33
4
4
  description: >-
5
5
  Use this skill when modeling complex multi-step accounting transactions —
6
6
  anything that spans multiple periods, involves changing amounts, or requires
package/cli.mjs CHANGED
@@ -699,14 +699,14 @@ Steps: 1) search_customer_credit_notes with status UNAPPLIED for the same contac
699
699
  - Skips lock date validation (opening balances are special).
700
700
  - Uses journalEntries (NOT lines \u2014 this is a journal type).`,params:{valueDate:{type:"string",description:"Opening balance date (YYYY-MM-DD)"},journalEntries:tc,currency:ec},required:["valueDate","journalEntries"],group:"journals",readOnly:!1,searchHint:"create transfer trial balance between periods",execute:async(e,t)=>W0(e.client,t)},{name:"delete_journal",description:"Delete a draft journal entry.",params:{resourceId:th},required:["resourceId"],group:"journals",readOnly:!1,searchHint:"permanently delete a draft journal entry",isDestructive:!0,execute:async(e,t)=>V0(e.client,t.resourceId)},{name:"generate_trial_balance",description:"Generate a trial balance report.",params:{endDate:{type:"string",description:"Snapshot date (YYYY-MM-DD)"},currencyCode:{type:"string",description:"Currency override"}},required:["endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate trial balance report for period",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>db(e.client,t)},{name:"generate_balance_sheet",description:"Generate a balance sheet report.",params:{snapshotDate:{type:"string",description:"Snapshot date (YYYY-MM-DD). Defaults to today if omitted."},currencyCode:MJ},required:[],group:"financial_reports",readOnly:!0,searchHint:"generate balance sheet report as at date",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t.snapshotDate??new Date().toISOString().slice(0,10);return pb(e.client,{primarySnapshotDate:r,currencyCode:t.currencyCode})}},{name:"generate_profit_and_loss",description:"Generate a profit & loss (income statement) report.",params:{startDate:{type:"string",description:"Period start (YYYY-MM-DD)"},endDate:{type:"string",description:"Period end (YYYY-MM-DD)"},currencyCode:MJ},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate profit and loss income statement report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>fb(e.client,t)},{name:"generate_cashflow",description:"Generate a cashflow report.",params:{startDate:SSe,endDate:p$},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate cashflow statement report for period",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>mb(e.client,t)},{name:"generate_aged_ar",description:"Generate aged accounts receivable summary.",params:{endDate:p$},required:["endDate"],group:"operational_reports",readOnly:!0,searchHint:"generate aged accounts receivable summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>hb(e.client,t)},{name:"generate_aged_ap",description:"Generate aged accounts payable summary.",params:{endDate:p$},required:["endDate"],group:"operational_reports",readOnly:!0,searchHint:"generate aged accounts payable summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>gb(e.client,t)},{name:"generate_cash_balance",description:"Generate a cash balance report showing cash position at a specific date. PREFERRED for cash position questions \u2014 use this (NOT balance sheet) when asked about total cash, cash on hand, available cash, or cash position across all bank accounts.",params:{endDate:{type:"string",description:"Snapshot date (YYYY-MM-DD)"}},required:["endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate cash balance report across accounts",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>yb(e.client,t)},{name:"generate_general_ledger",description:"Generate a general ledger report.",params:{startDate:{type:"string",description:"Period start (YYYY-MM-DD)"},endDate:{type:"string",description:"Period end (YYYY-MM-DD)"},groupBy:{type:"string",description:"Group by: ACCOUNT (default), TRANSACTION, or CAPSULE"}},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate general ledger report for account period",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t;return Db(e.client,{...r,groupBy:r.groupBy??"ACCOUNT"})}},{name:"list_bank_accounts",description:"List bank accounts connected to the organization.",params:{},required:[],group:"bank",readOnly:!0,searchHint:"list bank and cash accounts with balances",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>zc(e.client)},gt("list_items","List items (products & services). Returns internalName, itemCode, appliesToSale/Purchase. Paginated \u2014 response includes totalElements. Use limit/offset to page.","items",(e,t,r)=>HD(e,{limit:r,offset:t}),"list products services items with pagination"),Rt({name:"search_items",description:"Search items. Use list_items to search by name (internalName is not a filter field).",group:"items",fields:Wp,defaults:Zp,fetcher:lu,searchHint:"find items products services by status category sale purchase type internalName via list_items"}),{name:"get_item",description:"Get full item details by resourceId.",params:{resourceId:{type:"string",description:"Item resourceId (UUID)"}},required:["resourceId"],group:"items",readOnly:!0,searchHint:"get item product service details by id",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>fp(e.client,t.resourceId)},{name:"create_item",description:`Create a new item. Auto-checks for duplicates by itemCode \u2014 returns existing item if found.
701
701
  - saleItemName/purchaseItemName are auto-set from internalName if not provided.
702
- - Set appliesToSale and/or appliesToPurchase to control where the item can be used.`,params:{itemCode:{type:"string",description:"Unique item code"},internalName:{type:"string",description:"Item name"},appliesToSale:{type:"boolean",description:"Can be used on invoices"},appliesToPurchase:{type:"boolean",description:"Can be used on bills"},salePrice:{type:"number",description:"Default sale price"},purchasePrice:{type:"number",description:"Default purchase price"},saleAccountResourceId:{type:"string",description:"Revenue account for sales"},purchaseAccountResourceId:{type:"string",description:"Expense account for purchases"},customFields:dn},required:["itemCode","internalName"],group:"items",readOnly:!1,searchHint:"create new product or service item for invoicing",execute:async(e,t)=>{let r=t.itemCode,n=await l0(e.client,r);if(n)return{_guard:"duplicate_skipped",message:`Item with code "${r}" already exists.`,existing:n};let{purchasePrice:o,...i}=t,s={...i,...o!==void 0&&{purchaseItemPrice:o}};return mp(e.client,s)}},{name:"update_item",description:"Update an existing item. Only send fields you want to change \u2014 required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Item resourceId"},internalName:{type:"string",description:"New name"},itemCode:{type:"string",description:"New code"},salePrice:{type:"number"},purchasePrice:{type:"number"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Status (ACTIVE or INACTIVE)"},customFields:dn},required:["resourceId"],group:"items",readOnly:!1,searchHint:"update existing item name price account details",execute:async(e,t)=>{let{resourceId:r,purchasePrice:n,...o}=t,i={...o,...n!==void 0&&{purchaseItemPrice:n}};return WD(e.client,r,i)}},{name:"delete_item",description:"Delete an item.",params:{resourceId:{type:"string",description:"Item resourceId"}},required:["resourceId"],group:"items",readOnly:!1,searchHint:"permanently delete an item product service",isDestructive:!0,execute:async(e,t)=>ZD(e.client,t.resourceId)},{name:"bulk_upsert_items",description:"Create or update items in bulk (max 500 per call). Provide resourceId per item to update (partial \u2014 only changed fields needed, server preserves existing values). Omit resourceId to create (defaults: status=ACTIVE, itemCategory=NON_INVENTORY).",params:{items:{type:"array",description:"Array of items to create or update",items:{type:"object",properties:{resourceId:{type:"string",description:"Item resourceId (omit for create, provide for update)"},itemCode:{type:"string",description:"Unique item code (required for create)"},internalName:{type:"string",description:"Internal name (required for create)"},unit:{type:"string",description:"Unit of measure"},status:{type:"string",description:"Record status",enum:["ACTIVE","INACTIVE"]},appliesToSale:{type:"boolean",description:"Whether item applies to sales"},saleItemName:{type:"string",description:"Sale display name"},salePrice:{type:"number",description:"Sale price"},saleAccountResourceId:{type:"string",description:"Sale account resourceId"},saleTaxProfileResourceId:{type:"string",description:"Sale tax profile resourceId"},appliesToPurchase:{type:"boolean",description:"Whether item applies to purchases"},purchaseItemName:{type:"string",description:"Purchase display name"},purchasePrice:{type:"number",description:"Purchase price"},purchaseAccountResourceId:{type:"string",description:"Purchase account resourceId"},purchaseTaxProfileResourceId:{type:"string",description:"Purchase tax profile resourceId"},inventory:{type:"boolean",description:"Whether this is an inventory item"},cogsResourceId:{type:"string",description:"COGS account resourceId"},costingMethod:{type:"string",description:"Costing method",enum:["FIXED","WAC"]},itemCategory:{type:"string",description:"Item category",enum:["INVENTORY","NON_INVENTORY"]},blockInsufficientDeductions:{type:"boolean",description:"Block insufficient stock deductions"}}}}},required:["items"],group:"items",readOnly:!1,searchHint:"bulk create or update multiple items at once",execute:async(e,t)=>{let r=t.items.map(({purchasePrice:o,...i})=>({...i,...o!==void 0&&{purchaseItemPrice:o}}));return(await KD(e.client,r)).data}},gt("list_tags","List tags used for transaction categorization. Paginated \u2014 response includes totalElements. Use limit/offset to page.","tags",(e,t,r)=>hu(e,{limit:r,offset:t}),"list all tags for categorization tracking"),Rt({name:"search_tags",description:"Search tags.",group:"tags",fields:sf,defaults:af,fetcher:a0,searchHint:"find tags labels categorization by name"}),{name:"create_tag",description:"Create a new tag. Automatically reuses existing tag if one with the same name exists.",params:{name:{type:"string",description:"Tag name"}},required:["name"],group:"tags",readOnly:!1,searchHint:"create new tag for transaction categorization",execute:async(e,t)=>{let r=t.name,n=await f0(e.client,r);return n?{data:n,_note:`Tag "${r}" already exists \u2014 reusing.`}:yp(e.client,{name:r})}},Yn("get_tag","Get a tag by resourceId.","tags",(e,t)=>s0(e,t),"get tag details by resource id"),{name:"update_tag",description:"Rename a tag.",params:{resourceId:{type:"string",description:"Tag resourceId"},name:{type:"string",description:"New tag name"}},required:["resourceId","name"],group:"tags",readOnly:!1,searchHint:"update rename existing tag name",execute:async(e,t)=>c0(e.client,t.resourceId,{name:t.name})},{name:"delete_tag",description:"Delete a tag.",params:{resourceId:{type:"string",description:"Tag resourceId"}},required:["resourceId"],group:"tags",readOnly:!1,searchHint:"permanently delete a tag",isDestructive:!0,execute:async(e,t)=>u0(e.client,t.resourceId)},{name:"list_capsule_types",description:"List capsule types (e.g., PREPAID_EXPENSE, DEFERRED_REVENUE). Use to get capsuleTypeResourceId before creating capsules.",params:{},required:[],group:"capsules",readOnly:!0,searchHint:"list capsule types for transaction grouping",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>du(e.client)},gt("list_capsules","List capsules (transaction groupings for amortization, deferred revenue, etc.). Paginated \u2014 response includes totalElements. Use limit/offset to page.","capsules",(e,t,r)=>XD(e,{limit:r,offset:t}),"list capsules grouped transactions with pagination"),Rt({name:"search_capsules",description:"Search capsules.",group:"capsules",fields:lf,defaults:df,fetcher:pu,searchHint:"find capsules workflow groups by title status type capsuleType"}),{name:"get_capsule",description:"Get full capsule details by resourceId.",params:{resourceId:{type:"string",description:"Capsule resourceId (UUID)"}},required:["resourceId"],group:"capsules",readOnly:!0,searchHint:"get capsule details grouped transactions",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>gp(e.client,t.resourceId)},{name:"create_capsule",description:"Create a new capsule. List capsule types first to get the capsuleTypeResourceId.",params:{capsuleTypeResourceId:{type:"string",description:"Capsule type resourceId (from list_capsule_types)"},title:{type:"string",description:"Capsule title"},description:{type:"string",description:"Capsule description"}},required:["capsuleTypeResourceId","title"],group:"capsules",readOnly:!1,searchHint:"create new capsule to group related transactions",execute:async(e,t)=>{let r=t.title,n=await qz(e.client,r);return n?{_guard:"duplicate_skipped",message:`Capsule "${r}" already exists.`,existing:n}:Oa(e.client,{capsuleTypeResourceId:t.capsuleTypeResourceId,title:r,description:t.description})}},{name:"update_capsule",description:"Update a capsule title or description. Required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Capsule resourceId"},title:{type:"string",description:"New title"},description:{type:"string",description:"New description"}},required:["resourceId"],group:"capsules",readOnly:!1,searchHint:"update capsule title description details",execute:async(e,t)=>{let{resourceId:r,...n}=t;return QD(e.client,r,n)}},{name:"delete_capsule",description:"Delete a capsule.",params:{resourceId:{type:"string",description:"Capsule resourceId"}},required:["resourceId"],group:"capsules",readOnly:!1,searchHint:"permanently delete a capsule group",isDestructive:!0,execute:async(e,t)=>e0(e.client,t.resourceId)},gt("list_customer_credit_notes","List customer credit notes (AR adjustments/refunds). Paginated \u2014 response includes totalElements. Use limit/offset to page.","customer_credit_notes",(e,t,r)=>Tb(e,{limit:r,offset:t}),"list customer credit notes with status pagination"),Rt({name:"search_customer_credit_notes",description:"Search customer credit notes. Status: DRAFT, UNAPPLIED, PARTIALLY_APPLIED, APPLIED, VOID.",group:"customer_credit_notes",fields:vs,defaults:Ou,fetcher:Tf,searchHint:"find customer credit notes refunds CN by reference status contact tag"}),{name:"get_customer_credit_note",description:"Get full customer credit note details including line items.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!0,searchHint:"get customer credit note details line items",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Ro(e.client,t.resourceId)},{name:"create_customer_credit_note",description:`Create a customer credit note. Saves as draft by default.
702
+ - Set appliesToSale and/or appliesToPurchase to control where the item can be used.`,params:{itemCode:{type:"string",description:"Unique item code"},internalName:{type:"string",description:"Item name"},appliesToSale:{type:"boolean",description:"Can be used on invoices"},appliesToPurchase:{type:"boolean",description:"Can be used on bills"},salePrice:{type:"number",description:"Default sale price"},purchasePrice:{type:"number",description:"Default purchase price"},saleAccountResourceId:{type:"string",description:"Revenue account for sales"},purchaseAccountResourceId:{type:"string",description:"Expense account for purchases"},customFields:dn},required:["itemCode","internalName"],group:"items",readOnly:!1,searchHint:"create new product or service item for invoicing",execute:async(e,t)=>{let r=t.itemCode,n=await l0(e.client,r);if(n)return{_guard:"duplicate_skipped",message:`Item with code "${r}" already exists.`,existing:n};let{purchasePrice:o,...i}=t,s={...i,...o!==void 0&&{purchaseItemPrice:o}};return mp(e.client,s)}},{name:"update_item",description:"Update an existing item. Only send fields you want to change \u2014 required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Item resourceId"},internalName:{type:"string",description:"New name"},itemCode:{type:"string",description:"New code"},salePrice:{type:"number"},purchasePrice:{type:"number"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Status (ACTIVE or INACTIVE)"},customFields:dn},required:["resourceId"],group:"items",readOnly:!1,searchHint:"update existing item name price account details",execute:async(e,t)=>{let{resourceId:r,purchasePrice:n,...o}=t,i={...o,...n!==void 0&&{purchaseItemPrice:n}};return WD(e.client,r,i)}},{name:"delete_item",description:"Delete an item.",params:{resourceId:{type:"string",description:"Item resourceId"}},required:["resourceId"],group:"items",readOnly:!1,searchHint:"permanently delete an item product service",isDestructive:!0,execute:async(e,t)=>ZD(e.client,t.resourceId)},{name:"bulk_upsert_items",description:"Max 500 items per call. Provide resourceId per item to update (partial \u2014 only changed fields needed, server preserves existing values). Omit resourceId to create (defaults: status=ACTIVE, itemCategory=NON_INVENTORY).",params:{items:{type:"array",description:"Array of items to create or update",items:{type:"object",properties:{resourceId:{type:"string",description:"Item resourceId (omit for create, provide for update)"},itemCode:{type:"string",description:"Unique item code (required for create)"},internalName:{type:"string",description:"Internal name (required for create)"},unit:{type:"string",description:"Unit of measure"},status:{type:"string",description:"Record status",enum:["ACTIVE","INACTIVE"]},appliesToSale:{type:"boolean",description:"Whether item applies to sales"},saleItemName:{type:"string",description:"Sale display name"},salePrice:{type:"number",description:"Sale price"},saleAccountResourceId:{type:"string",description:"Sale account resourceId"},saleTaxProfileResourceId:{type:"string",description:"Sale tax profile resourceId"},appliesToPurchase:{type:"boolean",description:"Whether item applies to purchases"},purchaseItemName:{type:"string",description:"Purchase display name"},purchasePrice:{type:"number",description:"Purchase price"},purchaseAccountResourceId:{type:"string",description:"Purchase account resourceId"},purchaseTaxProfileResourceId:{type:"string",description:"Purchase tax profile resourceId"},inventory:{type:"boolean",description:"Whether this is an inventory item"},cogsResourceId:{type:"string",description:"COGS account resourceId"},costingMethod:{type:"string",description:"Costing method",enum:["FIXED","WAC"]},itemCategory:{type:"string",description:"Item category",enum:["INVENTORY","NON_INVENTORY"]},blockInsufficientDeductions:{type:"boolean",description:"Block insufficient stock deductions"}}}}},required:["items"],group:"items",readOnly:!1,searchHint:"bulk create or update multiple items at once",execute:async(e,t)=>{let r=t.items.map(({purchasePrice:o,...i})=>({...i,...o!==void 0&&{purchaseItemPrice:o}}));return(await KD(e.client,r)).data}},gt("list_tags","List tags used for transaction categorization. Paginated \u2014 response includes totalElements. Use limit/offset to page.","tags",(e,t,r)=>hu(e,{limit:r,offset:t}),"list all tags for categorization tracking"),Rt({name:"search_tags",description:"Search tags.",group:"tags",fields:sf,defaults:af,fetcher:a0,searchHint:"find tags labels categorization by name"}),{name:"create_tag",description:"Create a new tag. Automatically reuses existing tag if one with the same name exists.",params:{name:{type:"string",description:"Tag name"}},required:["name"],group:"tags",readOnly:!1,searchHint:"create new tag for transaction categorization",execute:async(e,t)=>{let r=t.name,n=await f0(e.client,r);return n?{data:n,_note:`Tag "${r}" already exists \u2014 reusing.`}:yp(e.client,{name:r})}},Yn("get_tag","Get a tag by resourceId.","tags",(e,t)=>s0(e,t),"get tag details by resource id"),{name:"update_tag",description:"Rename a tag.",params:{resourceId:{type:"string",description:"Tag resourceId"},name:{type:"string",description:"New tag name"}},required:["resourceId","name"],group:"tags",readOnly:!1,searchHint:"update rename existing tag name",execute:async(e,t)=>c0(e.client,t.resourceId,{name:t.name})},{name:"delete_tag",description:"Delete a tag.",params:{resourceId:{type:"string",description:"Tag resourceId"}},required:["resourceId"],group:"tags",readOnly:!1,searchHint:"permanently delete a tag",isDestructive:!0,execute:async(e,t)=>u0(e.client,t.resourceId)},{name:"list_capsule_types",description:"List capsule types (e.g., PREPAID_EXPENSE, DEFERRED_REVENUE). Use to get capsuleTypeResourceId before creating capsules.",params:{},required:[],group:"capsules",readOnly:!0,searchHint:"list capsule types for transaction grouping",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>du(e.client)},gt("list_capsules","List capsules (transaction groupings for amortization, deferred revenue, etc.). Paginated \u2014 response includes totalElements. Use limit/offset to page.","capsules",(e,t,r)=>XD(e,{limit:r,offset:t}),"list capsules grouped transactions with pagination"),Rt({name:"search_capsules",description:"Search capsules.",group:"capsules",fields:lf,defaults:df,fetcher:pu,searchHint:"find capsules workflow groups by title status type capsuleType"}),{name:"get_capsule",description:"Get full capsule details by resourceId.",params:{resourceId:{type:"string",description:"Capsule resourceId (UUID)"}},required:["resourceId"],group:"capsules",readOnly:!0,searchHint:"get capsule details grouped transactions",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>gp(e.client,t.resourceId)},{name:"create_capsule",description:"Create a new capsule. List capsule types first to get the capsuleTypeResourceId.",params:{capsuleTypeResourceId:{type:"string",description:"Capsule type resourceId (from list_capsule_types)"},title:{type:"string",description:"Capsule title"},description:{type:"string",description:"Capsule description"}},required:["capsuleTypeResourceId","title"],group:"capsules",readOnly:!1,searchHint:"create new capsule to group related transactions",execute:async(e,t)=>{let r=t.title,n=await qz(e.client,r);return n?{_guard:"duplicate_skipped",message:`Capsule "${r}" already exists.`,existing:n}:Oa(e.client,{capsuleTypeResourceId:t.capsuleTypeResourceId,title:r,description:t.description})}},{name:"update_capsule",description:"Update a capsule title or description. Required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Capsule resourceId"},title:{type:"string",description:"New title"},description:{type:"string",description:"New description"}},required:["resourceId"],group:"capsules",readOnly:!1,searchHint:"update capsule title description details",execute:async(e,t)=>{let{resourceId:r,...n}=t;return QD(e.client,r,n)}},{name:"delete_capsule",description:"Delete a capsule.",params:{resourceId:{type:"string",description:"Capsule resourceId"}},required:["resourceId"],group:"capsules",readOnly:!1,searchHint:"permanently delete a capsule group",isDestructive:!0,execute:async(e,t)=>e0(e.client,t.resourceId)},gt("list_customer_credit_notes","List customer credit notes (AR adjustments/refunds). Paginated \u2014 response includes totalElements. Use limit/offset to page.","customer_credit_notes",(e,t,r)=>Tb(e,{limit:r,offset:t}),"list customer credit notes with status pagination"),Rt({name:"search_customer_credit_notes",description:"Search customer credit notes. Status: DRAFT, UNAPPLIED, PARTIALLY_APPLIED, APPLIED, VOID.",group:"customer_credit_notes",fields:vs,defaults:Ou,fetcher:Tf,searchHint:"find customer credit notes refunds CN by reference status contact tag"}),{name:"get_customer_credit_note",description:"Get full customer credit note details including line items.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!0,searchHint:"get customer credit note details line items",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Ro(e.client,t.resourceId)},{name:"create_customer_credit_note",description:`Create a customer credit note. Saves as draft by default.
703
703
  - Status when finalized is UNAPPLIED (not APPROVED).
704
704
  - Line items use "name" for item description.
705
705
  - contactResourceId required \u2014 search contacts first.
706
706
  - reference MUST be unique \u2014 generate one with a timestamp if user doesn't specify.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Customer contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:rc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:ec,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:Dr,tag:dl,customFields:dn},required:["valueDate","contactResourceId","lineItems"],group:"customer_credit_notes",readOnly:!1,searchHint:"create new customer credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`CCN-${Date.now()}`),Of(e.client,i)}},{name:"delete_customer_credit_note",description:"Delete a draft customer credit note.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"permanently delete draft customer credit note",isDestructive:!0,execute:async(e,t)=>$b(e.client,t.resourceId)},{name:"update_customer_credit_note",description:'Update a draft customer credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Customer credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr,tag:dl,customFields:dn},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"update customer credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return Ob(e.client,r,s)}},{name:"finalize_customer_credit_note",description:"Finalize a draft customer credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"approve finalize customer credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await eh(e.client,"customer_credit_note",r,i);return $f(e.client,r,s)}},{name:"create_customer_credit_note_refund",description:"Record a refund payment against a customer credit note.",params:{creditNoteId:{type:"string",description:"Customer credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Qm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"customer_credit_notes",readOnly:!1,searchHint:"refund customer credit note to bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Rf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_customer_credit_note_refunds",description:"List refund payments for a customer credit note.",params:{creditNoteId:{type:"string",description:"Customer credit note resourceId"}},required:["creditNoteId"],group:"customer_credit_notes",readOnly:!0,searchHint:"list refunds on a customer credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Rb(e.client,t.creditNoteId)},gt("list_supplier_credit_notes","List supplier credit notes (AP adjustments/refunds). Paginated \u2014 response includes totalElements. Use limit/offset to page.","supplier_credit_notes",(e,t,r)=>Fb(e,{limit:r,offset:t}),"list supplier credit notes with status pagination"),Rt({name:"search_supplier_credit_notes",description:"Search supplier credit notes. Status: DRAFT, UNAPPLIED, PARTIALLY_APPLIED, APPLIED, VOID.",group:"supplier_credit_notes",fields:vs,defaults:Bp,fetcher:Nf,searchHint:"find supplier credit notes refunds CN by reference status contact tag"}),{name:"get_supplier_credit_note",description:"Get full supplier credit note details including line items.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"get supplier credit note details line items",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>No(e.client,t.resourceId)},{name:"create_supplier_credit_note",description:`Create a supplier credit note. Saves as draft by default.
707
707
  - Status when finalized is UNAPPLIED (not APPROVED).
708
708
  - Line items use "name" for item description.
709
- - contactResourceId required \u2014 search contacts first.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Supplier contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:rc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:ec,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:Dr,tag:dl,customFields:dn},required:["valueDate","contactResourceId","lineItems"],group:"supplier_credit_notes",readOnly:!1,searchHint:"create new supplier credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`SCN-${Date.now()}`),kf(e.client,i)}},{name:"delete_supplier_credit_note",description:"Delete a draft supplier credit note.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"permanently delete draft supplier credit note",isDestructive:!0,execute:async(e,t)=>Lb(e.client,t.resourceId)},{name:"update_supplier_credit_note",description:'Update a draft supplier credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr,tag:dl,customFields:dn},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"update supplier credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return Pb(e.client,r,s)}},{name:"finalize_supplier_credit_note",description:"Finalize a draft supplier credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"approve finalize supplier credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await eh(e.client,"supplier_credit_note",r,i);return Ff(e.client,r,s)}},{name:"create_supplier_credit_note_refund",description:"Record a refund payment against a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Qm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"supplier_credit_notes",readOnly:!1,searchHint:"refund supplier credit note from bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Pf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_supplier_credit_note_refunds",description:"List refund payments for a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"}},required:["creditNoteId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"list refunds on a supplier credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>jb(e.client,t.creditNoteId)},{name:"list_currencies",description:"List currencies enabled for the organization. Returns code, name, symbol, isBaseCurrency.",params:{},required:[],group:"currencies",readOnly:!0,searchHint:"list currencies enabled active organization base currency code symbol",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>Lf(e.client)},{name:"add_currency",description:"Enable one or more currencies for the organization.",params:{currencies:{type:"array",items:{type:"string"},description:'Currency codes to add (e.g., ["USD", "EUR"])'}},required:["currencies"],group:"currencies",readOnly:!1,searchHint:"add new currency to organization",execute:async(e,t)=>{let r=t.currencies,n=await Lf(e.client),o=new Set(n.data.map(c=>c.currencyCode.toUpperCase())),i=r.filter(c=>o.has(c.toUpperCase())),s=r.filter(c=>!o.has(c.toUpperCase()));if(s.length===0)return{_guard:"duplicate_skipped",message:`All currencies already enabled: ${r.join(", ")}.`,existing:i};let a=await Bb(e.client,s);return i.length>0?{...a,_note:`Skipped already-enabled: ${i.join(", ")}`}:a}},{name:"list_currency_rates",description:"List exchange rates for a specific currency. IMPORTANT: You MUST call list_currencies first to discover which currencies the org has enabled \u2014 never guess or assume currency codes.",params:{currencyCode:{type:"string",description:'Currency code (e.g., "USD")'},...h$},required:["currencyCode"],group:"currencies",readOnly:!0,searchHint:"list exchange rates for a currency pair",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let{limit:r,offset:n}=GJ(t),o=t.currencyCode;return Lp((i,s)=>Ub(e.client,o,{limit:s,offset:i}),r,n,100)}},{name:"add_currency_rate",description:'Add or set an exchange rate for a currency. ALWAYS use this tool even when the user says "update rate" \u2014 it handles both new and existing rates. Rate is relative to the base currency. Call list_currencies first to get valid currency codes.',params:{currencyCode:{type:"string",description:"Currency code"},rate:{type:"number",description:"Exchange rate (e.g., 1.35 for 1 USD = 1.35 SGD)"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"add new exchange rate for currency pair",execute:async(e,t)=>qb(e.client,t.currencyCode,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"update_currency_rate",description:'Update an EXISTING exchange rate record by its resourceId. Requires the rate resourceId from list_currency_rates. WARNING: If the user says "update the rate" or "set the rate", they almost always mean add_currency_rate (which creates/overwrites for a date). Only use this tool when explicitly modifying an existing rate record by ID.',params:{currencyCode:{type:"string",description:"Currency code"},resourceId:{type:"string",description:"Rate resourceId"},rate:{type:"number",description:"New exchange rate"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","resourceId","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"update existing exchange rate value",execute:async(e,t)=>zb(e.client,t.currencyCode,t.resourceId,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"start_currency_rates_import_job",description:"Start an async job to import currency rates from a CSV file URL.",params:{currencyCode:{type:"string",description:"Currency code"},csvUrl:{type:"string",description:"URL of the CSV file to import"}},required:["currencyCode","csvUrl"],group:"currencies",readOnly:!1,searchHint:"import exchange rates from external source",execute:async(e,t)=>Yb(e.client,t.currencyCode,t.csvUrl)},{name:"get_currency_rates_import_job_status",description:"Check the status of a currency rates import job.",params:{jobId:{type:"string",description:"Job ID from start_currency_rates_import_job"}},required:["jobId"],group:"currencies",readOnly:!0,searchHint:"check status of currency rates import job",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Jb(e.client,t.jobId)},{name:"bulk_upsert_currency_rates",description:"Create exchange rates in bulk (max 500 per call). Auto-enables currencies not yet enabled in the org \u2014 no need to call add_currency first. Requires rateDirection per rate. Response surfaces per-row failures: `failedRows[]` (each with rowIndex, columnName, columnValue, errorCode, errorMessage) + `failedCount` alongside `resourceIds[]` for successful inserts. Omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (no temporal gap).",params:{rates:{type:"array",description:"Array of exchange rates to create",items:{type:"object",properties:{sourceCurrencyCode:{type:"string",description:"Source currency code (ISO 4217, e.g. USD, EUR)"},rate:{type:"number",description:"Exchange rate value (must be > 0)"},rateDirection:{type:"string",description:"Rate direction",enum:["FUNCTIONAL_TO_SOURCE","SOURCE_TO_FUNCTIONAL"]},rateApplicableFrom:{type:"string",description:"Rate start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"Rate end date (YYYY-MM-DD, optional)"}},required:["sourceCurrencyCode","rate","rateDirection","rateApplicableFrom"]}}},required:["rates"],group:"currencies",readOnly:!1,searchHint:"bulk create or update multiple currency rates",execute:async(e,t)=>(await Gb(e.client,t.rates)).data},gt("list_tax_profiles","List tax profiles (GST, VAT, etc.). Returns name, rate, tax type.","tax_profiles",(e,t,r)=>fu(e,{limit:r,offset:t}),"list tax profiles GST VAT rates"),gt("list_tax_types","List available tax types. Use the tax type code when creating tax profiles.","tax_profiles",(e,t,r)=>t0(e,{limit:r,offset:t}),"list available tax types for profile creation"),{name:"create_tax_profile",description:"Create a new tax profile. List tax types first to get the taxTypeCode. Automatically checks for duplicates by name \u2014 returns existing profile if found.",params:{name:{type:"string",description:'Tax profile name (e.g., "GST 9%")'},taxRate:{type:"number",description:"Tax rate as percentage (e.g., 9 for 9%)"},taxTypeCode:{type:"string",description:"Tax type code (from list_tax_types)"}},required:["name","taxRate","taxTypeCode"],group:"tax_profiles",readOnly:!1,searchHint:"create new tax profile GST VAT rate",execute:async(e,t)=>{let r=t.name,n=await p0(e.client,r);return n?{_guard:"duplicate_skipped",message:`Tax profile "${r}" already exists.`,existing:n}:r0(e.client,{name:r,taxRate:t.taxRate,taxTypeCode:t.taxTypeCode})}},gt("list_cash_in","List cash-in entries (direct cash receipts). Paginated.","cash_entries",(e,t,r)=>Q0(e,{limit:r,offset:t}),"list cash in receipt entries with pagination"),{name:"create_cash_in",description:`Record money received INTO a bank account from an EXTERNAL source (customer payment, refund received, deposit). For inter-account moves use create_cash_transfer.
709
+ - contactResourceId required \u2014 search contacts first.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Supplier contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:rc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:ec,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:Dr,tag:dl,customFields:dn},required:["valueDate","contactResourceId","lineItems"],group:"supplier_credit_notes",readOnly:!1,searchHint:"create new supplier credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`SCN-${Date.now()}`),kf(e.client,i)}},{name:"delete_supplier_credit_note",description:"Delete a draft supplier credit note.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"permanently delete draft supplier credit note",isDestructive:!0,execute:async(e,t)=>Lb(e.client,t.resourceId)},{name:"update_supplier_credit_note",description:'Update a draft supplier credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr,tag:dl,customFields:dn},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"update supplier credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return Pb(e.client,r,s)}},{name:"finalize_supplier_credit_note",description:"Finalize a draft supplier credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"approve finalize supplier credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await eh(e.client,"supplier_credit_note",r,i);return Ff(e.client,r,s)}},{name:"create_supplier_credit_note_refund",description:"Record a refund payment against a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Qm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"supplier_credit_notes",readOnly:!1,searchHint:"refund supplier credit note from bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Pf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_supplier_credit_note_refunds",description:"List refund payments for a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"}},required:["creditNoteId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"list refunds on a supplier credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>jb(e.client,t.creditNoteId)},{name:"list_currencies",description:"List currencies enabled for the organization. Returns code, name, symbol, isBaseCurrency.",params:{},required:[],group:"currencies",readOnly:!0,searchHint:"list currencies enabled active organization base currency code symbol",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>Lf(e.client)},{name:"add_currency",description:"Enable one or more currencies for the organization.",params:{currencies:{type:"array",items:{type:"string"},description:'Currency codes to add (e.g., ["USD", "EUR"])'}},required:["currencies"],group:"currencies",readOnly:!1,searchHint:"add new currency to organization",execute:async(e,t)=>{let r=t.currencies,n=await Lf(e.client),o=new Set(n.data.map(c=>c.currencyCode.toUpperCase())),i=r.filter(c=>o.has(c.toUpperCase())),s=r.filter(c=>!o.has(c.toUpperCase()));if(s.length===0)return{_guard:"duplicate_skipped",message:`All currencies already enabled: ${r.join(", ")}.`,existing:i};let a=await Bb(e.client,s);return i.length>0?{...a,_note:`Skipped already-enabled: ${i.join(", ")}`}:a}},{name:"list_currency_rates",description:"List exchange rates for a specific currency. IMPORTANT: You MUST call list_currencies first to discover which currencies the org has enabled \u2014 never guess or assume currency codes.",params:{currencyCode:{type:"string",description:'Currency code (e.g., "USD")'},...h$},required:["currencyCode"],group:"currencies",readOnly:!0,searchHint:"list exchange rates for a currency pair",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let{limit:r,offset:n}=GJ(t),o=t.currencyCode;return Lp((i,s)=>Ub(e.client,o,{limit:s,offset:i}),r,n,100)}},{name:"add_currency_rate",description:'Add or set an exchange rate for a currency. ALWAYS use this tool even when the user says "update rate" \u2014 it handles both new and existing rates. Rate is relative to the base currency. Call list_currencies first to get valid currency codes.',params:{currencyCode:{type:"string",description:"Currency code"},rate:{type:"number",description:"Exchange rate (e.g., 1.35 for 1 USD = 1.35 SGD)"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"add new exchange rate for currency pair",execute:async(e,t)=>qb(e.client,t.currencyCode,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"update_currency_rate",description:'Update an EXISTING exchange rate record by its resourceId. Requires the rate resourceId from list_currency_rates. WARNING: If the user says "update the rate" or "set the rate", they almost always mean add_currency_rate (which creates/overwrites for a date). Only use this tool when explicitly modifying an existing rate record by ID.',params:{currencyCode:{type:"string",description:"Currency code"},resourceId:{type:"string",description:"Rate resourceId"},rate:{type:"number",description:"New exchange rate"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","resourceId","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"update existing exchange rate value",execute:async(e,t)=>zb(e.client,t.currencyCode,t.resourceId,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"start_currency_rates_import_job",description:"Start an async job to import currency rates from a CSV file URL.",params:{currencyCode:{type:"string",description:"Currency code"},csvUrl:{type:"string",description:"URL of the CSV file to import"}},required:["currencyCode","csvUrl"],group:"currencies",readOnly:!1,searchHint:"import exchange rates from external source",execute:async(e,t)=>Yb(e.client,t.currencyCode,t.csvUrl)},{name:"get_currency_rates_import_job_status",description:"Check the status of a currency rates import job.",params:{jobId:{type:"string",description:"Job ID from start_currency_rates_import_job"}},required:["jobId"],group:"currencies",readOnly:!0,searchHint:"check status of currency rates import job",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Jb(e.client,t.jobId)},{name:"bulk_upsert_currency_rates",description:"Max 500 exchange rates per call. Auto-enables currencies not yet enabled in the org \u2014 no need to call add_currency first. Requires rateDirection per rate. Response surfaces per-row failures: `failedRows[]` (each with rowIndex, columnName, columnValue, errorCode, errorMessage) + `failedCount` alongside `resourceIds[]` for successful inserts. Omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (no temporal gap).",params:{rates:{type:"array",description:"Array of exchange rates to create",items:{type:"object",properties:{sourceCurrencyCode:{type:"string",description:"Source currency code (ISO 4217, e.g. USD, EUR)"},rate:{type:"number",description:"Exchange rate value (must be > 0)"},rateDirection:{type:"string",description:"Rate direction",enum:["FUNCTIONAL_TO_SOURCE","SOURCE_TO_FUNCTIONAL"]},rateApplicableFrom:{type:"string",description:"Rate start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"Rate end date (YYYY-MM-DD, optional)"}},required:["sourceCurrencyCode","rate","rateDirection","rateApplicableFrom"]}}},required:["rates"],group:"currencies",readOnly:!1,searchHint:"bulk create or update multiple currency rates",execute:async(e,t)=>(await Gb(e.client,t.rates)).data},gt("list_tax_profiles","List tax profiles (GST, VAT, etc.). Returns name, rate, tax type.","tax_profiles",(e,t,r)=>fu(e,{limit:r,offset:t}),"list tax profiles GST VAT rates"),gt("list_tax_types","List available tax types. Use the tax type code when creating tax profiles.","tax_profiles",(e,t,r)=>t0(e,{limit:r,offset:t}),"list available tax types for profile creation"),{name:"create_tax_profile",description:"Create a new tax profile. List tax types first to get the taxTypeCode. Automatically checks for duplicates by name \u2014 returns existing profile if found.",params:{name:{type:"string",description:'Tax profile name (e.g., "GST 9%")'},taxRate:{type:"number",description:"Tax rate as percentage (e.g., 9 for 9%)"},taxTypeCode:{type:"string",description:"Tax type code (from list_tax_types)"}},required:["name","taxRate","taxTypeCode"],group:"tax_profiles",readOnly:!1,searchHint:"create new tax profile GST VAT rate",execute:async(e,t)=>{let r=t.name,n=await p0(e.client,r);return n?{_guard:"duplicate_skipped",message:`Tax profile "${r}" already exists.`,existing:n}:r0(e.client,{name:r,taxRate:t.taxRate,taxTypeCode:t.taxTypeCode})}},gt("list_cash_in","List cash-in entries (direct cash receipts). Paginated.","cash_entries",(e,t,r)=>Q0(e,{limit:r,offset:t}),"list cash in receipt entries with pagination"),{name:"create_cash_in",description:`Record money received INTO a bank account from an EXTERNAL source (customer payment, refund received, deposit). For inter-account moves use create_cash_transfer.
710
710
 
711
711
  accountResourceId MUST be a Bank/Cash account (from list_bank_accounts) \u2014 any other type fails. Cannot appear in lines (API enforces separation).
712
712
 
@@ -807,11 +807,11 @@ Response: { updated, failed: [{resourceId, error, errorCode}] }. HTTP 207 = part
807
807
 
808
808
  DO NOT use this for analytical / audit reports, financial statements, aging, summary reports, or statement-of-account \u2014 those go through download_export.`,params:{entityType:m$,query:BJ,filter:UJ,columns:qJ,sort:zJ},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"export records download xlsx file url",execute:async(e,t)=>E_(e.client,{entityType:t.entityType,outputFormat:"XLSX",query:t.query,filter:t.filter,columns:t.columns,sort:t.sort})},Rt({name:"search_background_jobs",description:"Search and poll background jobs. ANY operation that returns a jobId (bulk_upsert_contacts, bulk_upsert_items, bank statement import, magic file processing, etc.) can be tracked here. Filter by resourceId (the jobId value) to poll a specific job. Poll until status is SUCCESS, FAILED, or PARTIAL_SUCCESS. Use processedCount/failedCount/totalRecords for progress. IMPORTANT: filter by resourceId field, NOT jobId \u2014 they differ.",group:"background_jobs",fields:tf,defaults:rf,fetcher:Zm,searchHint:"poll background job status by jobId type status"}),{name:"bulk_upsert_contacts",description:`Bulk create/update contacts (max 500). resourceId per row \u2192 update (partial; omitted fields preserve existing). Omit resourceId \u2192 create. ${Bo} Per-row failures in errorDetails (NOT failedRows \u2014 that's the sync pattern). On PARTIAL_SUCCESS: succeeded rows are committed; re-submit only failed rowIndex entries.
809
809
 
810
- Whole-batch 422 (validate before submit): (1) each contact must have at least one of customer:true OR supplier:true (after defaults + backfill); (2) emailList unique within a contact (case-insensitive after trim); (3) paymentTerms.value must be positive integer when paymentTerms.name != "CUSTOM"; (4) no duplicate names within batch (after whitespace+case normalize); (5) billingAddress / shippingAddress: addressLine1 required when address object provided.`,params:{contacts:{type:"array",description:"Array of contacts to create or update (max 500)",items:{type:"object",properties:{resourceId:{type:"string",description:"Contact resourceId (omit for create, provide UUID for update)"},billingName:{type:"string",description:"Billing name (required for create)"},name:{type:"string",description:"Display name (defaults to billingName)"},emails:{type:"array",items:{type:"string"},description:"Email addresses"},customer:{type:"boolean",description:"Mark as customer"},supplier:{type:"boolean",description:"Mark as supplier"},taxId:{type:"string",description:"Tax ID / GST registration number"},taxIdType:{type:"string",description:"Tax ID type (e.g., GST, VAT)"},registrationNumber:{type:"string",description:"Business registration number"},currencyCode:{type:"string",description:"Default currency code (e.g., SGD)"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Contact status"},paymentTerms:{type:"number",description:"Payment terms in days (e.g., 30 for Net 30)"},notes:{type:"string",description:"Internal notes"},billingAddress:{type:"object",description:"Billing address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}},shippingAddress:{type:"object",description:"Shipping address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}}}}}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create update contacts upsert",execute:async(e,t)=>(er(t.contacts,"contacts"),Ly(e.client,t.contacts))},{name:"bulk_upsert_invoices",description:`Bulk create/update invoices (max 500). FLAT shape \u2014 ONE line per invoice via itemDescription + totalAmount + invoiceAccountResourceId at row level. For multi-line, use bulk_upsert_invoice_line_items (nested lineItems[]).
810
+ Whole-batch 422 (validate before submit): (1) each contact must have at least one of customer:true OR supplier:true (after defaults + backfill); (2) emailList unique within a contact (case-insensitive after trim); (3) paymentTerms.value must be positive integer when paymentTerms.name != "CUSTOM"; (4) no duplicate names within batch (after whitespace+case normalize); (5) billingAddress / shippingAddress: addressLine1 required when address object provided.`,params:{contacts:{type:"array",description:"Array of contacts to create or update (max 500)",items:{type:"object",properties:{resourceId:{type:"string",description:"Contact resourceId (omit for create, provide UUID for update)"},billingName:{type:"string",description:"Billing name (required for create)"},name:{type:"string",description:"Display name (defaults to billingName)"},emails:{type:"array",items:{type:"string"},description:"Email addresses"},customer:{type:"boolean",description:"Mark as customer"},supplier:{type:"boolean",description:"Mark as supplier"},taxId:{type:"string",description:"Tax ID / GST registration number"},taxIdType:{type:"string",description:"Tax ID type (e.g., GST, VAT)"},registrationNumber:{type:"string",description:"Business registration number"},currencyCode:{type:"string",description:"Default currency code (e.g., SGD)"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Contact status"},paymentTerms:{type:"number",description:"Payment terms in days (e.g., 30 for Net 30)"},notes:{type:"string",description:"Internal notes"},billingAddress:{type:"object",description:"Billing address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}},shippingAddress:{type:"object",description:"Shipping address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}}}}}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create update contacts upsert",execute:async(e,t)=>(er(t.contacts,"contacts"),Ly(e.client,t.contacts))},{name:"bulk_upsert_invoices",description:`Max 500 invoices per call. FLAT shape \u2014 ONE line per invoice via itemDescription + totalAmount + invoiceAccountResourceId at row level. For multi-line, use bulk_upsert_invoice_line_items (nested lineItems[]).
811
811
 
812
812
  Natural key: invoiceReference (rows sharing one within a batch are MERGED \u2014 last wins). resourceId per row \u2192 update by UUID; omit \u2192 upsert by invoiceReference.
813
813
 
814
- ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}); PARTIAL_SUCCESS \u2192 data[0].errorDetails. Dates ISO 8601 (YYYY-MM-DD); dateFormat field removed.`,params:{invoices:{type:"array",description:"Array of invoices to create or update (max 500). Each row needs at least: invoiceReference, contactResourceId, valueDate, totalAmount, invoiceAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string",description:"Optional caller-supplied row index for error reporting"},resourceId:{type:"string",description:"Invoice resourceId (UUID) \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key (e.g., INV-2025-001) \u2014 required"},contactResourceId:{type:"string",description:"Customer contact UUID \u2014 required"},valueDate:{type:"string",description:"Invoice date YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"Due date YYYY-MM-DD"},totalAmount:{type:"number",description:"Total amount (BigDecimal)"},currencyCode:{type:"string",description:"Currency (e.g., SGD)"},invoiceAccountResourceId:{type:"string",description:"Revenue account UUID"},itemDescription:{type:"string",description:"Single-line item description"},internalNotes:{type:"string",description:"Internal notes"},tags:{type:"array",items:{type:"string"},description:"Tag resourceIds"}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk create update invoices upsert import migrate",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),B0(e.client,r)}},{name:"bulk_upsert_invoice_line_items",description:`Create or update invoices with nested line items in bulk (max 500 invoices per call). Each row carries lineItems[] under its parent invoice (scoped by invoiceReference). ${Bo} Dates are ISO 8601 only.`,params:{invoices:{type:"array",description:"Array of invoices with line items (max 500). Each invoice row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string",description:"Invoice resourceId \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"YYYY-MM-DD"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",description:"Line items belonging to this invoice",items:{type:"object",properties:{itemDescription:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string",description:"Unit of measure (pcs, kg, etc.)"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Revenue account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk invoices line items multi-line upsert import",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),U0(e.client,r)}},{name:"bulk_upsert_bills",description:`Create or update bills in bulk (max 500 per call). FLAT shape: ONE line per bill via \`itemDescription\` + \`totalAmount\` + \`billAccountResourceId\` at row level. For multi-line bills use \`bulk_upsert_bill_line_items\` instead \u2014 that variant takes nested \`lineItems[]\`. Natural key: \`billReference\` (rows sharing one within a batch are MERGED \u2014 last wins). ${Bo} Dates are ISO 8601 only \u2014 dateFormat field was removed.`,params:{bills:{type:"array",description:"Array of bills to create or update (max 500). Each row needs at least: billReference, contactResourceId, valueDate, totalAmount, billAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},totalAmount:{type:"number"},currencyCode:{type:"string"},billAccountResourceId:{type:"string",description:"Expense account UUID"},itemDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk create update bills upsert import migrate",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),Ny(e.client,r)}},{name:"bulk_upsert_bill_line_items",description:`Create or update bills with nested line items in bulk (max 500 bills per call). Each row carries lineItems[] under its parent bill (scoped by billReference). ${Bo}`,params:{bills:{type:"array",description:"Array of bills with line items (max 500). Each bill row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Expense account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk bills line items multi-line upsert import",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),ky(e.client,r)}},{name:"bulk_upsert_customer_credit_notes",description:`Create or update customer credit notes in bulk (max 500 per call). Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{customerCreditNotes:{type:"array",description:"Array of customer credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["customerCreditNotes"],group:"customer_credit_notes",readOnly:!1,searchHint:"bulk customer credit notes refund upsert import",execute:async(e,t)=>{er(t.customerCreditNotes,"customerCreditNotes",500,"customer credit notes");let r=t.customerCreditNotes;return eo(r,["valueDate"]),kb(e.client,r)}},{name:"bulk_upsert_supplier_credit_notes",description:`Create or update supplier credit notes in bulk (max 500 per call). Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{supplierCreditNotes:{type:"array",description:"Array of supplier credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["supplierCreditNotes"],group:"supplier_credit_notes",readOnly:!1,searchHint:"bulk supplier credit notes refund upsert import",execute:async(e,t)=>{er(t.supplierCreditNotes,"supplierCreditNotes",500,"supplier credit notes");let r=t.supplierCreditNotes;return eo(r,["valueDate"]),Mb(e.client,r)}},{name:"bulk_upsert_journals",description:`Create or update manual journals in bulk (max 500 per call). NATURAL KEY: \`journalReference\` (NOT \`reference\` \u2014 every other bulk-upsert uses entityReference, this one is asymmetric). LEGS field: \`journalEntries[]\` (NOT \`entries[]\` \u2014 different from \`clio journals create\` which uses entries). Each leg has \`accountResourceId\` + \`debitAmount\` + \`creditAmount\` (debit + credit must balance per row). ${Bo} Dates are ISO 8601 (YYYY-MM-DD) only \u2014 dateFormat field was removed.`,params:{journals:{type:"array",description:"Array of journals to create or update (max 500). Each row has entries[] (debit/credit legs).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},journalReference:{type:"string",description:"Natural key \u2014 required (NOTE: field is `journalReference`, not `reference`)"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},journalEntries:{type:"array",description:"Journal legs (debit + credit amounts must balance) \u2014 field is `journalEntries`, NOT `entries`",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Required"},description:{type:"string"},debitAmount:{type:"number"},creditAmount:{type:"number"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["journals"],group:"journals",readOnly:!1,searchHint:"bulk manual journals upsert import migration",execute:async(e,t)=>{er(t.journals,"journals");let r=t.journals;return eo(r,["valueDate"]),H0(e.client,r)}},{name:"bulk_upsert_fixed_assets",description:`Bulk create/update fixed assets (max 500). Natural key: reference.
814
+ ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}); PARTIAL_SUCCESS \u2192 data[0].errorDetails. Dates ISO 8601 (YYYY-MM-DD); dateFormat field removed.`,params:{invoices:{type:"array",description:"Array of invoices to create or update (max 500). Each row needs at least: invoiceReference, contactResourceId, valueDate, totalAmount, invoiceAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string",description:"Optional caller-supplied row index for error reporting"},resourceId:{type:"string",description:"Invoice resourceId (UUID) \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key (e.g., INV-2025-001) \u2014 required"},contactResourceId:{type:"string",description:"Customer contact UUID \u2014 required"},valueDate:{type:"string",description:"Invoice date YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"Due date YYYY-MM-DD"},totalAmount:{type:"number",description:"Total amount (BigDecimal)"},currencyCode:{type:"string",description:"Currency (e.g., SGD)"},invoiceAccountResourceId:{type:"string",description:"Revenue account UUID"},itemDescription:{type:"string",description:"Single-line item description"},internalNotes:{type:"string",description:"Internal notes"},tags:{type:"array",items:{type:"string"},description:"Tag resourceIds"}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk create update invoices upsert import migrate",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),B0(e.client,r)}},{name:"bulk_upsert_invoice_line_items",description:`Nested line items per invoice (max 500 invoices per call). Each row carries lineItems[] under its parent invoice (scoped by invoiceReference). ${Bo} Dates are ISO 8601 only.`,params:{invoices:{type:"array",description:"Array of invoices with line items (max 500). Each invoice row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string",description:"Invoice resourceId \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"YYYY-MM-DD"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",description:"Line items belonging to this invoice",items:{type:"object",properties:{itemDescription:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string",description:"Unit of measure (pcs, kg, etc.)"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Revenue account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk invoices line items multi-line upsert import",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),U0(e.client,r)}},{name:"bulk_upsert_bills",description:`Max 500 bills per call. FLAT shape: ONE line per bill via \`itemDescription\` + \`totalAmount\` + \`billAccountResourceId\` at row level. For multi-line bills use \`bulk_upsert_bill_line_items\` instead \u2014 that variant takes nested \`lineItems[]\`. Natural key: \`billReference\` (rows sharing one within a batch are MERGED \u2014 last wins). ${Bo} Dates are ISO 8601 only \u2014 dateFormat field was removed.`,params:{bills:{type:"array",description:"Array of bills to create or update (max 500). Each row needs at least: billReference, contactResourceId, valueDate, totalAmount, billAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},totalAmount:{type:"number"},currencyCode:{type:"string"},billAccountResourceId:{type:"string",description:"Expense account UUID"},itemDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk create update bills upsert import migrate",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),Ny(e.client,r)}},{name:"bulk_upsert_bill_line_items",description:`Nested line items per bill (max 500 bills per call). Each row carries lineItems[] under its parent bill (scoped by billReference). ${Bo}`,params:{bills:{type:"array",description:"Array of bills with line items (max 500). Each bill row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Expense account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk bills line items multi-line upsert import",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),ky(e.client,r)}},{name:"bulk_upsert_customer_credit_notes",description:`Max 500 customer credit notes per call. Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{customerCreditNotes:{type:"array",description:"Array of customer credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["customerCreditNotes"],group:"customer_credit_notes",readOnly:!1,searchHint:"bulk customer credit notes refund upsert import",execute:async(e,t)=>{er(t.customerCreditNotes,"customerCreditNotes",500,"customer credit notes");let r=t.customerCreditNotes;return eo(r,["valueDate"]),kb(e.client,r)}},{name:"bulk_upsert_supplier_credit_notes",description:`Max 500 supplier credit notes per call. Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{supplierCreditNotes:{type:"array",description:"Array of supplier credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["supplierCreditNotes"],group:"supplier_credit_notes",readOnly:!1,searchHint:"bulk supplier credit notes refund upsert import",execute:async(e,t)=>{er(t.supplierCreditNotes,"supplierCreditNotes",500,"supplier credit notes");let r=t.supplierCreditNotes;return eo(r,["valueDate"]),Mb(e.client,r)}},{name:"bulk_upsert_journals",description:`Max 500 manual journals per call. NATURAL KEY: \`journalReference\` (NOT \`reference\` \u2014 every other bulk-upsert uses entityReference, this one is asymmetric). LEGS field: \`journalEntries[]\` (NOT \`entries[]\` \u2014 different from \`clio journals create\` which uses entries). Each leg has \`accountResourceId\` + \`debitAmount\` + \`creditAmount\` (debit + credit must balance per row). ${Bo} Dates are ISO 8601 (YYYY-MM-DD) only \u2014 dateFormat field was removed.`,params:{journals:{type:"array",description:"Array of journals to create or update (max 500). Each row has entries[] (debit/credit legs).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},journalReference:{type:"string",description:"Natural key \u2014 required (NOTE: field is `journalReference`, not `reference`)"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},journalEntries:{type:"array",description:"Journal legs (debit + credit amounts must balance) \u2014 field is `journalEntries`, NOT `entries`",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Required"},description:{type:"string"},debitAmount:{type:"number"},creditAmount:{type:"number"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["journals"],group:"journals",readOnly:!1,searchHint:"bulk manual journals upsert import migration",execute:async(e,t)=>{er(t.journals,"journals");let r=t.journals;return eo(r,["valueDate"]),H0(e.client,r)}},{name:"bulk_upsert_fixed_assets",description:`Bulk create/update fixed assets (max 500). Natural key: reference.
815
815
 
816
816
  \u26A0\uFE0F DATE FIELD MISMATCH: REQUEST uses valueDate (NOT purchaseDate); GET response uses purchaseDate. Sending purchaseDate \u2192 cryptic 400 "Invalid request body".
817
817
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jaz-clio",
3
- "version": "5.4.32",
3
+ "version": "5.4.33",
4
4
  "description": "Clio: Command Line Interface Operator for Jaz AI.",
5
5
  "type": "module",
6
6
  "bin": {