jaz-clio 5.10.0 → 5.11.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
@@ -3,11 +3,11 @@
3
3
  <p align="center">
4
4
  <a href="https://www.npmjs.com/package/jaz-clio"><img src="https://img.shields.io/npm/v/jaz-clio?style=for-the-badge&logo=npm" alt="npm"></a>
5
5
  <a href="https://www.npmjs.com/package/jaz-clio"><img src="https://img.shields.io/npm/dm/jaz-clio?style=for-the-badge&label=downloads" alt="npm downloads"></a>
6
- <img src="https://img.shields.io/badge/tools-265-blue?style=for-the-badge" alt="265 Tools">
6
+ <img src="https://img.shields.io/badge/tools-297-blue?style=for-the-badge" alt="297 Tools">
7
7
  <a href="https://github.com/teamtinvio/jaz-ai/blob/main/LICENSE"><img src="https://img.shields.io/github/license/teamtinvio/jaz-ai?style=for-the-badge&color=green" alt="License"></a>
8
8
  </p>
9
9
 
10
- 265 tools. 13 financial calculators. 12 job playbooks. 130 API rules. 16 IFRS recipes.
10
+ 297 tools. 13 financial calculators. 12 job playbooks. 130 API rules. 16 IFRS recipes.
11
11
 
12
12
  ```bash
13
13
  npm install -g jaz-clio
@@ -19,7 +19,7 @@ Requires **Node.js 18+** ([nodejs.org](https://nodejs.org)). Also fully compatib
19
19
 
20
20
  - [Three Ways In](#three-ways-in) — CLI, MCP, Skills
21
21
  - [CLI](#cli) — 55 command groups
22
- - [MCP Server](#mcp-server) — 288 tools for AI agents
22
+ - [MCP Server](#mcp-server) — 297 tools for AI agents
23
23
  - [Skills](#skills) — Teach any AI the Jaz API
24
24
  - [Setup](#setup) — Auth, multi-org, automation
25
25
 
@@ -27,7 +27,7 @@ Requires **Node.js 18+** ([nodejs.org](https://nodejs.org)). Also fully compatib
27
27
 
28
28
  | | What happens | Try it |
29
29
  |---|---|---|
30
- | **CLI** | 55 command groups, every accounting operation | `clio invoices list` |
30
+ | **CLI** | 57 command groups, every accounting operation | `clio invoices list` |
31
31
  | **MCP** | Plug into Claude Code, Cursor, Codex, Copilot | `clio mcp` |
32
32
  | **Skills** | Teach any AI tool the Jaz API | `clio init` |
33
33
 
@@ -54,7 +54,7 @@ clio practice create-engagement acme-pte-ltd --type monthly-close --period 2026-
54
54
 
55
55
  ## MCP Server
56
56
 
57
- 288 CLI tools, available to any AI agent that speaks MCP. Runs locally — no cloud, no ports. Includes the v5.2.0 `practice_*` tools (init, onboard_client, list_clients, load_client, create_engagement, load_engagement) so an agent in Claude Desktop or Claude Code can scaffold and load client workspaces conversationally.
57
+ 297 CLI tools, available to any AI agent that speaks MCP. Runs locally — no cloud, no ports. Includes the v5.2.0 `practice_*` tools (init, onboard_client, list_clients, load_client, create_engagement, load_engagement) so an agent in Claude Desktop or Claude Code can scaffold and load client workspaces conversationally.
58
58
 
59
59
  **Claude Code:**
60
60
  ```bash
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-api
3
- version: 5.10.0
3
+ version: 5.11.0
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
@@ -31,7 +31,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
31
31
 
32
32
  **Practitioner (Claude Desktop / `jaz-practice`)** — priority + engagement type typically hit during (rule numbering preserved; this is a curation overlay): (1) Identifiers & Dates 1–3 — every engagement; (2) Names & Fields 9–13 — monthly-close review; (3) Transaction Creation 14–16 — onboarding opening entries + monthly-close draft finalization; (4) Chart of Accounts 17–22 — onboarding COA setup + monthly-close classification; (5) Payments / Cross-Currency 4–8 — monthly-close payment-run + quarterly-gst AR/AP recon; (6) Journals & Cash 23–26 — monthly-close accruals + annual-statutory year-end true-ups; (7) Credit Notes & Refunds 27–28 — monthly-close AR review + ad-hoc credit issuance; (8) Reports 36–37 — every engagement, TB/BS at start of monthly-close, quarterly-gst, annual-statutory; (9) Tax Profile Scoping 100 — quarterly-gst F5 box mapping; (10) Transaction References 104 — monthly-close period-end + onboarding ref reuse; (11) Draft Finalization Pipeline 81–88 — monthly-close draft queues + onboarding draft promotion; (12) Jaz Magic / PDF-JPG 57–63 — onboarding doc capture + monthly-close document-collection; (13) Currency Rates 39, 49, 105 — monthly-close FX reval + annual-statutory year-end revaluation; (14) Withholding Tax 45, 98 — quarterly-gst + annual-statutory tax computation.
33
33
 
34
- **Integrator (API clients, pipelines, batch jobs, MCP/CLI)** — after the practitioner list: Bulk Upsert (Items/Contacts/Rates); Background Jobs (filter `resourceId` not `jobId`); Export Records; Pagination (38); Search & Filter (50–56); Response Shape Gotchas (66–73); Cash Entry Response Shape (74–77); Entity Resolution (78–80); Bank Rules (89–90c); Fixed Assets (91–92c); Subscriptions & Scheduled (93–94); niche endpoints (95–102); Journals balance (103); Quick Fix (107, 111); TTB (108 — onboarding-relevant); Dynamic Strings (109–110); Sub-Resource Shapes (112); Nano-Classifier (113); Scheduler Asymmetry (114); Payment Record CRUD (115–117); Bulk Upserts transactions (118–122); Reconciliation write-side (123–127); Drafts lifecycle (128–135).
34
+ **Integrator (API clients, pipelines, batch jobs, MCP/CLI)** — after the practitioner list: Bulk Upsert (Items/Contacts/Rates); Background Jobs (filter `resourceId` not `jobId`); Export Records; Pagination (38); Search & Filter (50–56); Response Shape Gotchas (66–73); Cash Entry Response Shape (74–77); Entity Resolution (78–80); Bank Rules (89–90c); Fixed Assets (91–92c); Subscriptions & Scheduled (93–94); niche endpoints (95–102); Journals balance (103); Quick Fix (107, 111); TTB (108 — onboarding-relevant); Dynamic Strings (109–110); Sub-Resource Shapes (112); Nano-Classifier (113); Scheduler Asymmetry (114); Payment Record CRUD (115–117); Bulk Upserts transactions (118–122); Reconciliation write-side (123–127); Drafts lifecycle (128–135); Orders — Sale Quotes / Sale Orders / Purchase Requests / Purchase Orders (`references/orders.md`).
35
35
 
36
36
  ## When to Use This Skill
37
37
 
@@ -177,7 +177,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
177
177
  49. **Currency rate direction: `rate` = functionalToSource (1 base = X foreign)** — POST `rate: 0.74` for a SGD org means 1 SGD = 0.74 USD. **If your data stores rates as "1 USD = 1.35 SGD" (sourceToFunctional), you MUST invert: `rate = 1 / 1.35 = 0.74`.** GET confirms both: `rateFunctionalToSource` (what you POSTed) and `rateSourceToFunctional` (the inverse).
178
178
 
179
179
  ### Search & Filter
180
- 50. **Search endpoint universal pattern** — All 28 `POST /*/search` endpoints share identical structure: `{ filter?, sort: { sortBy: ["field"], order: "ASC"|"DESC" }, limit: 1-1000, offset: 0-65536 }`. `offset` is a 0-indexed page number (not row-skip). Sort is REQUIRED when offset is present (even `offset: 0`). Default limit: 100. `sortBy` is always an array on all endpoints (no exceptions). See `references/search-reference.md` for per-endpoint filter/sort fields.
180
+ 50. **Search endpoint universal pattern** — All 32 `POST /*/search` endpoints share identical structure: `{ filter?, sort: { sortBy: ["field"], order: "ASC"|"DESC" }, limit: 1-1000, offset: 0-65536 }`. `offset` is a 0-indexed page number (not row-skip). Sort is REQUIRED when offset is present (even `offset: 0`). Default limit: 100. `sortBy` is always an array on all endpoints (no exceptions). See `references/search-reference.md` for per-endpoint filter/sort fields.
181
181
  50a. **`query` field — Jaz search operators** — 14 endpoints accept an optional `query` string alongside `filter`: invoices, bills, customer/supplier credit notes, journals, cashflow-transactions, bank-records, contacts, items, capsules, fixed-assets, scheduled-transactions, chart-of-accounts, tax-profiles. Example: `{ "query": "status:unpaid AND $500+", "limit": 50 }`. Key syntax: amounts (`$500+`, `$100-500`, `amount:>2m`, magnitude suffixes `5k`/`2m`/`1b`), negative (`$-500`), absolute value (`abs:1000+`), dates (`date:this month`, `date:-30d`, `due:overdue`, `submitted:last week`, `lastpayment:-7d`), status/enum (`status:unpaid`, `currency:SGD,USD` — comma = OR), string fields (`customer:acme`, `ref:INV-*` wildcard, `=ref:INV-001` exact, `ref:/\d{4}/` regex), blank checks (`ref:blank`, `tag:!blank`), booleans (`hasattachment:yes`, `customer:yes`), negation (`!status:paid` or `NOT status:void` — **never `-`** for negation), logic (`AND`/`OR` with implicit AND on space), grouping, inline sort (`sort:amount:desc`). Full syntax spec (all fields, aliases, entity field lists, examples): **`references/search-syntax.md`**.
182
182
  50b. **`query` + `filter` merge** — When both are present, they are merged at the filter level. Explicit `filter` keys win on conflict. Use `query` for human-readable shorthand, `filter` for programmatic precision, or combine both: `{ "query": "date:this year", "filter": { "currencyCode": { "in": ["SGD"] } } }`.
183
183
  50c. **`query` error handling** — Unknown field name → `query_not_understood` (400). Bad enum value (e.g. `status:BADVALUE`) → **empty results, no error** (silent miss). Unsupported endpoint → `query_not_supported` (400). Parser unavailable → `query_parse_error` (502). Empty/null/whitespace query → passthrough (ignored). In CLI/MCP: use `--query` / `query` param only on supported entities — unsupported entities have no `--query` flag.
@@ -44,6 +44,16 @@ Transaction fees are added to cash spent (not deducted like invoices). RGL = `(C
44
44
 
45
45
  ---
46
46
 
47
+ ## Orders (Quotes, Sale Orders, Purchase Requests, Purchase Orders)
48
+
49
+ Pre-invoice / pre-bill documents. Sales pipeline: **Sale Quote** (estimate/quotation) → **Sale Order** → Invoice. Purchase pipeline: **Purchase Request** (requisition) → **Purchase Order** (PO) → Bill.
50
+
51
+ Key capabilities: a Sale Order links to its source quote via `saleQuoteResourceId` (and a PO to its request via `purchaseRequestResourceId`) — the parent must be **issued** (created with `saveAsDraft:false`, i.e. CREATED/ACTIVE), not a DRAFT. Quotes/requests advance with **accept** (from the issued state), orders with **confirm**. Fulfillment is tracked on the parent via `orderState` (NOT_ORDERED / PARTIALLY_ORDERED / FULLY_ORDERED). There is no convert endpoint and no order→invoice link field yet — raise the invoice/bill separately. Delete is draft-only; use void otherwise.
52
+
53
+ **API**: per entity (`sale-quotes`, `sale-orders`, `purchase-requests`, `purchase-orders`): CRUD `GET/POST/PUT/DELETE`, `POST /…/search`, `POST /…/:id/{accept|confirm}`, `POST /…/:id/void`, `POST /…/:id/fast-fix`, `POST /…/bulk-{accept|confirm|void|delete}`; orders also `POST /…/line-items/bulk-upsert`. Agent surface: `sale_orders` + `purchase_orders` namespaces (create/get/search/update/transition). See `references/orders.md`.
54
+
55
+ ---
56
+
47
57
  ## Customer Credits
48
58
 
49
59
  Credit notes that reduce amounts owed by customers — issued for returns, discounts, or corrections. Can be applied to invoices (same currency only) or refunded to customers. Statuses: draft, credit available, fully applied.
@@ -74,6 +74,27 @@
74
74
  | POST | `/bills/bulk-upsert` | Bulk create/update bills (max 500) — **async**, returns `{ jobId }`. Natural key: `billReference`. ISO 8601 dates only. |
75
75
  | POST | `/bills/line-items/bulk-upsert` | Bulk create/update bills with nested line items (max 500) — **async**, returns `{ jobId }`. |
76
76
 
77
+ ### Orders (Sale Quotes, Sale Orders, Purchase Requests, Purchase Orders)
78
+ Four entities sharing one shape. Replace `{entity}` with `sale-quotes`, `sale-orders`, `purchase-requests`, or `purchase-orders`. Quotes/requests use `accept`; orders use `confirm`. See `references/orders.md`.
79
+
80
+ | Method | Path | Description |
81
+ |--------|------|-------------|
82
+ | GET | `/{entity}` | List |
83
+ | GET | `/{entity}/:resourceId` | Get single |
84
+ | POST | `/{entity}` | Create. Sale Order links via `saleQuoteResourceId`; Purchase Order via `purchaseRequestResourceId` (parent must be issued — saveAsDraft:false — not a draft). |
85
+ | POST | `/{entity}/search` | Advanced search with filters |
86
+ | PUT | `/{entity}/:resourceId` | Update |
87
+ | DELETE | `/{entity}/:resourceId` | Delete (DRAFT only — else use void) |
88
+ | POST | `/{entity}/:resourceId/void` | Void (cancel) |
89
+ | POST | `/sale-quotes\|purchase-requests/:resourceId/accept` | Accept (→ ACCEPTED) |
90
+ | POST | `/sale-orders\|purchase-orders/:resourceId/confirm` | Confirm (→ CONFIRMED) |
91
+ | POST | `/{entity}/:resourceId/fast-fix` | Quick-fix details (`{ attributes }`) |
92
+ | POST | `/{entity}/bulk-void` | Bulk void (`{ resourceIds }`) |
93
+ | POST | `/sale-quotes\|purchase-requests/bulk-accept` | Bulk accept (`{ resourceIds }`) |
94
+ | POST | `/sale-orders\|purchase-orders/bulk-confirm` | Bulk confirm (`{ resourceIds }`) |
95
+ | POST | `/{entity}/bulk-delete` | Bulk delete drafts (`{ resourceIds }`) |
96
+ | POST | `/sale-orders\|purchase-orders/line-items/bulk-upsert` | Bulk line-item upsert |
97
+
77
98
  ### Customer Credit Notes
78
99
  | Method | Path | Description |
79
100
  |--------|------|-------------|
@@ -0,0 +1,92 @@
1
+ # Orders — Sale Quotes, Sale Orders, Purchase Requests, Purchase Orders
2
+
3
+ Pre-invoice / pre-bill documents in the sales and purchase pipelines.
4
+
5
+ ```
6
+ Sales: Sale Quote ──(accept)──► Sale Order ──► Invoice
7
+ Purchases: Purchase Request ──(accept)──► Purchase Order ──► Bill
8
+ ```
9
+
10
+ Two MCP namespaces wrap these: **`sale_orders`** (Sale Quotes + Sale Orders) and **`purchase_orders`** (Purchase Requests + Purchase Orders). Each tool takes a `documentType` discriminator. The full long-tail (list, bulk-*, fast-fix, line-item bulk-upsert) lives in the CLI (`clio sale-orders …`, `clio purchase-orders …`).
11
+
12
+ ## Document types & lifecycle
13
+
14
+ | documentType | Created as | Advance verb | Terminal | saveAsDraft? |
15
+ |--------------|-----------|--------------|----------|--------------|
16
+ | `SALE_QUOTE` | DRAFT (default) / CREATED (saveAsDraft:false) | **accept** (CREATED → ACCEPTED) | VOID | yes (default true) |
17
+ | `SALE_ORDER` | CREATED | **confirm** → CONFIRMED | VOID | **no** (always CREATED) |
18
+ | `PURCHASE_REQUEST` | DRAFT (default) / ACTIVE (saveAsDraft:false) | **accept** (ACTIVE → ACCEPTED) | VOID | yes (default true) |
19
+ | `PURCHASE_ORDER` | DRAFT (default) / ACTIVE (saveAsDraft:false) | **confirm** → CONFIRMED | VOID | yes (default true) |
20
+
21
+ - **Quotes & Requests use `accept`. Orders use `confirm`.** (`transition_*` enforces this via a documentType × action matrix.)
22
+ - **`accept` works on the ISSUED state, not DRAFT** — a Sale Quote must be CREATED, a Purchase Request must be ACTIVE. Accepting a DRAFT returns `422 Invalid status` (verified live). There is no exposed DRAFT→issued verb: **issue a document by creating it with `saveAsDraft:false`** (update with `saveAsDraft:false` does NOT issue an existing DRAFT — verified live).
23
+ - **Sale Orders have no draft state** — `saveAsDraft` is ignored; created directly as `CREATED`.
24
+ - Statuses verified live: SQ create → `DRAFT` (or `CREATED` with `saveAsDraft:false`); SQ accept (from CREATED) → `ACCEPTED`; SO create → `CREATED`; SO confirm → `CONFIRMED`; PR create → `DRAFT` (or `ACTIVE` with `saveAsDraft:false`); PR accept (from ACTIVE) → `ACCEPTED`; PO `saveAsDraft:false` → `ACTIVE`; PO confirm → `CONFIRMED`.
25
+
26
+ ## Linking (this is how "conversion" works today)
27
+
28
+ There is **no convert endpoint** (`/convert-to-invoice` → 404). Linking is a **create-time reference field**:
29
+
30
+ - **Quote → Order**: pass `saleQuoteResourceId` on `create_sale_order` (documentType `SALE_ORDER`).
31
+ - **Request → PO**: pass `purchaseRequestResourceId` on `create_purchase_order` (documentType `PURCHASE_ORDER`).
32
+
33
+ **The parent must be ISSUED (not DRAFT/VOID).** A CREATED/ACCEPTED quote (or ACTIVE/ACCEPTED request) is linkable — accept is **optional** (CREATED already links). Linking to a `DRAFT`/`VOID` parent returns `SALE_QUOTE_STATUS_INVALID_FOR_ORDER_CONVERSION` ("must not be in VOID or DRAFT status to create sale order"). The `create_*` tools pre-flight this: for a DRAFT parent the `repair` hint says to issue it (create with `saveAsDraft:false`) — **not** to accept it (accept fails on DRAFT). So: to order from a quote/request, create the quote/request with `saveAsDraft:false`.
34
+
35
+ Once an order is created from an issued quote, the parent quote's `orderState` advances to `FULLY_ORDERED` (verified live). `orderState` (`NOT_ORDERED` / `PARTIALLY_ORDERED` / `FULLY_ORDERED`) is a **response field**, not a search filter.
36
+
37
+ ### Order → Invoice / Order → Bill
38
+
39
+ **Not exposed by the REST API yet.** There is no `saleOrderResourceId` on invoice-create and no `purchaseOrderResourceId` on bill-create at this layer. To raise an invoice "from" a confirmed Sale Order, call `create_invoice` separately (no order reference is recorded today). Fulfillment back-reference (`invoiceState`/`billState`) is tracked server-side but not surfaced here. Do **not** fabricate an order→invoice link.
40
+
41
+ ## Fields (create)
42
+
43
+ Required: `valueDate`. Recommended: `reference` (auto-generated, timestamped, if omitted — must be unique per org), `contactResourceId`, `lineItems`.
44
+
45
+ - Line items reuse the standard shape: `{ name, quantity, unitPrice, accountResourceId?, taxProfileResourceId?, … }`. `accountResourceId` is **required on each line when the document is not a draft** (i.e. always for Sale Orders; for quotes/requests/POs when `saveAsDraft:false`). The `create_*` tools pre-flight this.
46
+ - Notes field differs by side: **sales** use `invoiceNotes`, **purchases** use `purchaseNotes`. The `notes` tool param maps to the right one automatically.
47
+ - Other optional fields: `dueDate`, `terms` (0/7/15/30/45/60), `tag`, `customFields`, `billTo`, `billFrom`, `capsuleResourceId`, `expectedTotal`.
48
+
49
+ ## Delete vs Void
50
+
51
+ - **DELETE is draft-only** (422 on anything non-draft). `transition_* action:DELETE` pre-flights status and returns a `repair` hint to use `VOID` for non-draft records.
52
+ - **VOID** cancels any non-draft quote/request/order; optional `internalNotes` reason.
53
+
54
+ ## MCP tools
55
+
56
+ `sale_orders`: `create_sale_order`, `get_sale_order`, `search_sale_orders`, `update_sale_order`, `transition_sale_order` (action: ACCEPT | CONFIRM | VOID | DELETE).
57
+ `purchase_orders`: `create_purchase_order`, `get_purchase_order`, `search_purchase_orders`, `update_purchase_order`, `transition_purchase_order`.
58
+
59
+ ## CLI (full surface incl. long-tail)
60
+
61
+ ```
62
+ clio sale-orders list|get|search|create|update|accept|confirm|void|delete|fast-fix \
63
+ |bulk-void|bulk-accept|bulk-confirm|bulk-delete|bulk-upsert-line-items (-t quote|order)
64
+ clio purchase-orders list|get|search|create|update|accept|confirm|void|delete|fast-fix \
65
+ |bulk-void|bulk-accept|bulk-confirm|bulk-delete|bulk-upsert-line-items (-t request|order)
66
+ ```
67
+
68
+ ## Worked example — issued quote → accept → linked order → confirmed
69
+
70
+ ```bash
71
+ # 1. Issue the quote (--finalize → saveAsDraft:false → status CREATED). A plain
72
+ # draft (no --finalize) stays DRAFT and cannot be linked or accepted.
73
+ clio sale-orders create -t quote --finalize --contact <id> --lines '[{"name":"Widget","quantity":2,"unitPrice":50,"accountResourceId":"<acct>"}]' --date 2026-05-30 --json
74
+ # 2. (Optional) accept it (CREATED → ACCEPTED). A CREATED quote is already linkable.
75
+ clio sale-orders accept <quoteId> --json
76
+ # 3. Create the order linked to the issued quote (created as CREATED)
77
+ clio sale-orders create -t order --quote <quoteId> --contact <id> --lines '[…]' --date 2026-05-30 --json
78
+ # 4. Confirm the order (CREATED → CONFIRMED)
79
+ clio sale-orders confirm <orderId> --json
80
+ # 5. The parent quote now shows orderState = FULLY_ORDERED
81
+ clio sale-orders get <quoteId> -t quote --json | jq .orderState
82
+ ```
83
+
84
+ Purchase side is symmetric: `create -t request --finalize` (→ ACTIVE) → (optional) `accept` → `create -t order --request <id> --finalize` → `confirm`.
85
+
86
+ ## Known issues
87
+
88
+ - **Order `/search` currently returns 500 server-side.** As of 2026-05-30, `POST` to `sale-quotes/search`, `sale-orders/search`, `purchase-requests/search`, and `purchase-orders/search` returns `500 Internal Server Error` for any body (even the minimal `{sort, limit, offset}`), while `invoices/search` and `bills/search` work with the identical shape. This is a server-side API defect, not a client bug — `search_sale_orders` / `search_purchase_orders` send a valid request and will work once the backend search resolver is fixed. Until then, use `list` (GET) + `get` to browse orders.
89
+
90
+ ## Search
91
+
92
+ `search_sale_orders` / `search_purchase_orders` take `documentType` plus the standard filter set (reference, status, contact, contactResourceId, currencyCode, date range, amount range, tag). The `status` enum is the per-side union (sales: DRAFT/CREATED/ACCEPTED/CONFIRMED/VOID; purchases: DRAFT/ACTIVE/ACCEPTED/CONFIRMED/VOID). For advanced/nested queries (e.g. filter by `saleQuoteResourceId`), pass the raw `filter` object. See `search-reference.md` §24–25 and `search-enums.md` §25–26.
@@ -381,6 +381,38 @@ No enum fields. Plain string filters (no operators): `currencyCode`, `name`, `pu
381
381
 
382
382
  ---
383
383
 
384
+ ### 25. Sale Orders (`POST /api/v1/sale-orders/search`, `POST /api/v1/sale-quotes/search`)
385
+
386
+ | Field | Valid Values |
387
+ |-------|-------------|
388
+ | `status` | `DRAFT`, `CREATED`, `ACCEPTED`, `CONFIRMED`, `VOID` |
389
+ | `currencyCode` | ISO 4217 (see above) |
390
+ | `terms` | `0`, `7`, `15`, `30`, `45`, `60` (integer — payment terms in days) |
391
+
392
+ **Amount fields**: `totalAmount`, `expectedTotal`
393
+ **Date fields**: `valueDate`, `dueDate`, `createdAt` (DateTime), `updatedAt` (DateTime), `approvedAt`
394
+ **Link field**: `saleQuoteResourceId` (on Sale Orders — the source quote)
395
+
396
+ > The `status` enum is the union across both sale documents: a **Sale Quote** moves `DRAFT → CREATED → ACCEPTED` (then `VOID`); a **Sale Order** is created as `CREATED → CONFIRMED` (then `VOID`). Fulfillment is reported on the parent quote via `orderState` (`NOT_ORDERED`, `PARTIALLY_ORDERED`, `FULLY_ORDERED`) — a response field, not a search filter.
397
+
398
+ ---
399
+
400
+ ### 26. Purchase Orders (`POST /api/v1/purchase-orders/search`, `POST /api/v1/purchase-requests/search`)
401
+
402
+ | Field | Valid Values |
403
+ |-------|-------------|
404
+ | `status` | `DRAFT`, `ACTIVE`, `ACCEPTED`, `CONFIRMED`, `VOID` |
405
+ | `currencyCode` | ISO 4217 |
406
+ | `terms` | `0`, `7`, `15`, `30`, `45`, `60` |
407
+
408
+ **Amount fields**: `totalAmount`, `expectedTotal`
409
+ **Date fields**: `valueDate`, `dueDate`, `createdAt` (DateTime), `updatedAt` (DateTime), `approvedAt`
410
+ **Link field**: `purchaseRequestResourceId` (on Purchase Orders — the source request)
411
+
412
+ > The `status` enum is the union across both purchase documents: a **Purchase Request** moves `DRAFT → ACTIVE → ACCEPTED` (then `VOID`); a **Purchase Order** moves `DRAFT → ACTIVE → CONFIRMED` (then `VOID`). Fulfillment is reported on the parent request via `orderState` (`NOT_ORDERED`, `PARTIALLY_ORDERED`, `FULLY_ORDERED`) — a response field, not a search filter.
413
+
414
+ ---
415
+
384
416
  ## Nested Filter Paths
385
417
 
386
418
  Several endpoints support filtering on nested relationships. The nested object wraps standard operators.
@@ -700,6 +700,70 @@ Standard pattern with limit/offset/filter/sort. Used for managing bank reconcili
700
700
 
701
701
  ---
702
702
 
703
+ ### 24. POST /api/v1/sale-orders/search
704
+
705
+ Also covers `POST /api/v1/sale-quotes/search` — same filter shape (`SaleOrderFilter` / `SaleQuoteFilter`).
706
+
707
+ **Filter fields** (`SaleOrderFilter`):
708
+ | Field | Type | Notes |
709
+ |-------|------|-------|
710
+ | `resourceId` | StringExpression | |
711
+ | `reference` | StringExpression | Order/quote number |
712
+ | `status` | StringExpression | DRAFT, CREATED, ACCEPTED, CONFIRMED, VOID |
713
+ | `contactResourceId` | StringExpression | |
714
+ | `contact` | ContactNestedFilter | Nested: name, resourceId, status |
715
+ | `saleQuoteResourceId` | StringExpression | (Sale Orders) source quote link |
716
+ | `currencyCode` | StringExpression | |
717
+ | `valueDate` | DateExpression | |
718
+ | `dueDate` | DateExpression | |
719
+ | `terms` | IntExpression | Payment terms (days) |
720
+ | `tags` | Nested: `name` (StringExpression) | |
721
+ | `totalAmount` | BigDecimalExpression | |
722
+ | `expectedTotal` | BigDecimalExpression | |
723
+ | `approvedAt` | DateExpression | |
724
+ | `createdAt` | DateTimeExpression | RFC3339 input |
725
+ | `updatedAt` | DateTimeExpression | RFC3339 input |
726
+
727
+ **Logical**: `and`, `or`, `andGroup`, `orGroup`
728
+
729
+ **Sort fields**: `resourceId`, `reference`, `status`, `contactResourceId`, `valueDate`, `dueDate`, `terms`, `currencyCode`, `totalAmount`, `createdAt`, `updatedAt`
730
+
731
+ > `orderState` (NOT_ORDERED / PARTIALLY_ORDERED / FULLY_ORDERED) appears on responses but is **not** a filter field. There is no order→invoice link field — raise the invoice separately.
732
+
733
+ ---
734
+
735
+ ### 25. POST /api/v1/purchase-orders/search
736
+
737
+ Also covers `POST /api/v1/purchase-requests/search` — same filter shape (`PurchaseOrderFilter` / `PurchaseRequestFilter`).
738
+
739
+ **Filter fields** (`PurchaseOrderFilter`):
740
+ | Field | Type | Notes |
741
+ |-------|------|-------|
742
+ | `resourceId` | StringExpression | |
743
+ | `reference` | StringExpression | Order/request number |
744
+ | `status` | StringExpression | DRAFT, ACTIVE, ACCEPTED, CONFIRMED, VOID |
745
+ | `contactResourceId` | StringExpression | Supplier |
746
+ | `contact` | ContactNestedFilter | Nested: name, resourceId, status |
747
+ | `purchaseRequestResourceId` | StringExpression | (Purchase Orders) source request link |
748
+ | `currencyCode` | StringExpression | |
749
+ | `valueDate` | DateExpression | |
750
+ | `dueDate` | DateExpression | |
751
+ | `terms` | IntExpression | Payment terms (days) |
752
+ | `tags` | Nested: `name` (StringExpression) | |
753
+ | `totalAmount` | BigDecimalExpression | |
754
+ | `expectedTotal` | BigDecimalExpression | |
755
+ | `approvedAt` | DateExpression | |
756
+ | `createdAt` | DateTimeExpression | RFC3339 input |
757
+ | `updatedAt` | DateTimeExpression | RFC3339 input |
758
+
759
+ **Logical**: `and`, `or`, `andGroup`, `orGroup`
760
+
761
+ **Sort fields**: `resourceId`, `reference`, `status`, `contactResourceId`, `valueDate`, `dueDate`, `terms`, `currencyCode`, `totalAmount`, `createdAt`, `updatedAt`
762
+
763
+ > `orderState` appears on responses but is **not** a filter field. There is no order→bill link field — raise the bill separately.
764
+
765
+ ---
766
+
703
767
  ## Quick Lookup: Common Search Patterns
704
768
 
705
769
  ### Find all invoices for a contact
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-cli
3
- version: 5.10.0
3
+ version: 5.11.0
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,
@@ -100,8 +100,8 @@ clio currencies add USD
100
100
  # Set the exchange rate for the period
101
101
  clio currency-rates add USD --rate 1.3450 --from 2026-03-01 --to 2026-03-31
102
102
 
103
- # Or import rates automatically from ECB/MAS
104
- clio currency-rates import USD --from 2026-03-01 --to 2026-03-31
103
+ # For bulk updates, prepare a JSON file and use bulk-upsert (max 500 rates/call)
104
+ clio currency-rates bulk-upsert --input rates.json
105
105
 
106
106
  # Create an invoice in USD (org base is SGD)
107
107
  clio invoices create \
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-conversion
3
- version: 5.10.0
3
+ version: 5.11.0
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-pseudo-sql
3
- version: 5.10.0
3
+ version: 5.11.0
4
4
  description: >-
5
5
  Use this skill when answering ad-hoc data questions that aren't covered by
6
6
  download_export (canonical reports — anomaly, audit, aging, P&L, BS, GL,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jaz-jobs
3
- version: 5.10.0
3
+ version: 5.11.0
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.10.0
3
+ version: 5.11.0
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.10.0
3
+ version: 5.11.0
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
@@ -6,7 +6,7 @@ Source of truth lives in the installed skills (`.claude/skills/jaz-*/SKILL.md` o
6
6
 
7
7
  ## Discovery
8
8
 
9
- The Jaz MCP server exposes 288 tools across 34 namespaces via 3 meta-tools. **Use the meta-tool flow — never enumerate tools blindly.**
9
+ The Jaz MCP server exposes 297 tools across 37 namespaces via 3 meta-tools. **Use the meta-tool flow — never enumerate tools blindly.**
10
10
 
11
11
  1. `search_tools(query)` → top-N tool names + namespaces.
12
12
  2. `describe_tools(names)` → full parameter schemas.