jaz-clio 5.54.0 → 5.55.1
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 +2 -2
- package/assets/skills/api/SKILL.md +4 -4
- package/assets/skills/cli/SKILL.md +15 -5
- package/assets/skills/cli/references/command-catalog.md +19 -1
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jaz-kit/SKILL.md +1 -1
- package/assets/skills/jaz-pseudo-sql/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +1 -1
- package/assets/skills/transaction-recipes/SKILL.md +1 -1
- package/cli.mjs +489 -489
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<p align="center"><b>Jaz accounting on the command line, and inside any AI agent.</b></p>
|
|
11
11
|
|
|
12
|
-
369 tools ·
|
|
12
|
+
369 tools · 72 command groups · 7 skills · 13 calculators · 12 close playbooks · 159 field-tested API rules.
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npm install -g jaz-clio
|
|
@@ -50,7 +50,7 @@ clio magic create --file receipt.pdf # AI extracts, drafts the
|
|
|
50
50
|
clio invoices search --query 'status:unpaid AND $500+' # structured per-entity search
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
72 command groups, 16 report types, 13 calculators, 12 job playbooks. Every command takes `--json`. Run `clio --help` for the full list.
|
|
54
54
|
|
|
55
55
|
### Foreign currency
|
|
56
56
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jaz-api
|
|
3
|
-
version: 5.
|
|
3
|
+
version: 5.55.1
|
|
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, 159 production gotchas, error
|
|
@@ -174,7 +174,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
|
|
|
174
174
|
46. **Known API bugs (500s)**: capsules POST (upstream returns nil), catalogs POST, inventory balances by status GET (`/inventory-balances/:status`, missing `c.Bind`). **Contact groups PUT and custom fields PUT are NO LONGER on this list** — both were re-probed live 2026-09-02 and returned 200 and applied the change. Do not route around them.
|
|
175
175
|
47. **Non-existent endpoints**: `POST /inventory/adjustments` (and `/inventory-adjustments`, `/inventory-items/:id/adjustments`, `/items/:id/inventory-adjustments` — no stock-adjustment write path exists at any spelling), `GET /payments` (list), and `POST /payments/search` return 404 — these endpoints are not implemented. For payments, per-payment CRUD is `GET/PUT/DELETE /payments/:resourceId` and there ARE two payment-scoped searches — see Rule 64. `POST /deposits` also 404s, but for a different reason — see Rule 47a; do not read it as a missing feature.
|
|
176
176
|
47a. **Deposits are not an entity — the 404 on `/deposits` is by design.** A deposit is a **flag on a Chart of Accounts account**, not a document: the account carries `depositContactType` = `CUSTOMER` (advance received, a liability) or `SUPPLIER` (advance paid, an asset). Once flagged, a deposit movement is an **ordinary transaction against that account** — top up with `POST /journals` / `POST /cash-in-entries` / `POST /cash-out-entries` (one leg on the flagged account), draw down with `POST /invoices/:id/payments` or `POST /bills/:id/payments` passing `accountResourceId` = the flagged account **and `paymentMethod` set to something other than BANK_TRANSFER / CASH / CHEQUE** (use `OTHER`) — those three force a bank/cash account and 422 here, see Rule 80, read with `POST /cashflow-transactions/search`. **Flagging the account is a web-app action**: `depositContactType` is on no chart-of-accounts request or response model here, and the platform-backend mutation that sets it (`configureDepositAccounts`) is not proxied — so `POST /chart-of-accounts` cannot create a deposit account. Over the API you can only read and post against an account someone already flagged. Full walkthrough: `references/endpoints.md` → Deposits.
|
|
177
|
-
48. **Attachments — full CRUD**: **Add**: `POST /:type/:id/attachments` (multipart, `file` field, `application/pdf` or `image/*` — NOT `text/plain`). **List**: `GET /:type/:id/attachments`. **Delete**: `DELETE /:type/:id/attachments/:attachmentResourceId` (HTTP 200). CLI: `clio attachments add --file <path>` or `--url <url>`, `clio attachments list`, `clio attachments delete <attachmentResourceId>`. **
|
|
177
|
+
48. **Attachments — full CRUD**: **Add**: `POST /:type/:id/attachments` (multipart, `file` field, `application/pdf` or `image/*` — NOT `text/plain`). **List**: `GET /:type/:id/attachments`. **Delete**: `DELETE /:type/:id/attachments/:attachmentResourceId` (HTTP 200). CLI: `clio attachments add --file <path>` or `--url <url>`, `clio attachments list`, `clio attachments delete <attachmentResourceId>`. **The list response shape depends on the entity** — measured raw 2026-09-07: `/invoices/:id/attachments` returns `{ reference, resourceId, attachments: [{fileName, fileType, fileId, attachmentResourceId}] }`, while `/bills/:id/attachments` and `/journals/:id/attachments` return the conventional `{ data: [...] }`. Both credit-note types were unmeasured (every sampled record was void — see below). `listAttachments` in `core/api/attachments.ts` reads either key, so through the CLI or a tool you get `.data` in all cases; only a raw request sees the split. The attachment ID field is `attachmentResourceId` (not `resourceId`). **A VOIDED record 404s on three of the five types.** Measured 2026-09-07: a voided invoice, customer credit note and supplier credit note each answer `404 not_found` with `"<Entity> is voided"`, while a voided bill and a voided journal return 200 and list normally. The 404 is about the record's status, not its existence — `GET /invoices/:id` on the same id works — so never read this 404 as a bad resourceId. Anything fanning out to attachments alongside other calls must treat that leg as degradable, or one voided record destroys the whole response; `get_transaction_summary` did exactly that until 5.55.1.
|
|
178
178
|
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). **You do not have to do the arithmetic**: `add_currency_rate`, `update_currency_rate` and the `currency` object on the 8 FX create tools (invoice, bill, journal, both credit notes, both cash entries, TTB) accept an optional `rateDirection` (`FUNCTIONAL_TO_SOURCE` | `SOURCE_TO_FUNCTIONAL`) — declare how your figure reads and pass it verbatim. Omitting it always means `FUNCTIONAL_TO_SOURCE`. The two families differ only in where the label is applied: the rate-table tools (plus `bulk_upsert_currency_rates`) send it on the wire and the server applies it, while the 8 FX create tools have no such field, so the client inverts and strips it there. Prefer either to inverting by hand: a wrong inversion is silent and wrong by rate². `clio calc fx-reval` REQUIRES the direction — that calculator historically assumed the opposite convention to the API.
|
|
179
179
|
|
|
180
180
|
### Search & Filter
|
|
@@ -200,7 +200,7 @@ The rest of this skill — field names, gotchas, error catalog, dependency order
|
|
|
200
200
|
63. **Workflow search tracks all magic uploads** — `POST /magic/workflows/search` searches across BT extractions AND bank statement imports. Filter by `resourceId` (eq), `documentType` (SALE, PURCHASE, SALE_CREDIT_NOTE, PURCHASE_CREDIT_NOTE, BANK_STATEMENT), `status` (SUBMITTED, PROCESSING, COMPLETED, FAILED), `fileName` (contains), `fileType`, `createdAt` (date range). Response: paginated `MagicWorkflowItem` with `businessTransactionDetails.businessTransactionResourceId` (the draft BT ID when COMPLETED) or `bankStatementDetails` (for bank imports). Standard search sort: `{ sortBy: ["createdAt"], order: "DESC" }`.
|
|
201
201
|
|
|
202
202
|
### Cashflow & Unified Ledger
|
|
203
|
-
64. **
|
|
203
|
+
64. **Four ways to read payments — pick by scope.** `GET /payments` (list) and `POST /payments/search` do NOT exist and never did. What does exist: (a) **per-payment CRUD** — `GET/PUT/DELETE /payments/:resourceId`; (b) **payment-scoped search** — `POST /sales/payments/search` and `POST /purchases/payments/search` (added 2026-08-13), one side of the ledger each, plus `POST /batch-payments/search` for batches; (c) **cross-entity ledger** — `POST /cashflow-transactions/search`, the unified transaction ledger spanning invoices, bills, credit notes, journals, cash entries and payments. Filter it by `businessTransactionType` (e.g. `SALE`, `PURCHASE`) and `direction` (`PAYIN`, `PAYOUT`). Response dates are epoch milliseconds. **Naming trap**: the `search_payments` tool is a wrapper over `/cashflow-transactions/search`, NOT over the sales/purchases payment searches — its name is narrower than what it calls. Reach the per-side searches with a raw request; they have no tool. (d) **Per-document settlements** — `GET /invoices/:id/payments` and `GET /bills/:id/payments`, and for credit notes `GET /customer-credit-notes/:id/refunds` / `GET /supplier-credit-notes/:id/refunds` (the domain distinguishes a refund from a payment; a journal has neither). This is the right call for **one known document's own settlements** and the one to reach for first — no filter to get wrong. All four answer `{ data: [...] }` (measured raw 2026-09-07). It is listed here because it was missing from this rule while (c) sat one line away, and `get_transaction_summary` consequently filtered the ledger by `businessTransactionResourceId` — a field `TransactionsFilter` does not declare — for its entire life, 400ing on every call behind a silent catch.
|
|
204
204
|
65. **Contacts search uses `name`** — NOT `billingName`. The filter field for searching contacts by name is `name` (maps to `billingName` internally). Sort field is also `name`. Using `billingName` in a search filter returns zero results.
|
|
205
205
|
|
|
206
206
|
### Response Shape Gotchas
|
|
@@ -526,7 +526,7 @@ Supports `--json` for structured output. 186 articles across 20 sections. Automa
|
|
|
526
526
|
|
|
527
527
|
## Dashboard Deep Links (navigation tools)
|
|
528
528
|
|
|
529
|
-
When the user wants to OPEN, SEE, or SHARE something in the Jaz dashboard ("open this invoice", "take me to the P&L"), hand them a real URL via
|
|
529
|
+
When the user wants to OPEN, SEE, or SHARE something in the Jaz dashboard ("open this invoice", "take me to the P&L"), hand them a real URL via `navigate` — one operation, on both surfaces (`clio navigate` on the CLI, offline). Called with no `destination` it discovers destination keys (filter by `query`/`resource`/`kind`; keys are named by product area, not task wording — on zero matches retry broader: "billing", not "card"); called with a `destination` it turns the key into `{ url, kind, label }`. Screens are dotted route paths (`reports.profit-and-loss`); record modals are `<resource>.modal.<type>` (`sales.modal.view-sale`). Record-specific modals (view/edit/duplicate one record) REQUIRE `resourceId` — the same Jaz resourceId from the search/get that found the record; screens and create/"new" modals take none (a resourceId on a screen is rejected). NEVER write a dashboard URL by hand and NEVER guess a destination key — routes are not guessable, and a wrong link is worse than no link; if `navigate` errors, follow its hint (near-matches + discovery pointer) and say the link could not be built rather than improvising one. The org query param is appended automatically when the surface knows the acting org; API-key surfaces open in the user's current org on the app.jaz.ai host. Examples: "open invoice INV-042" → `search_invoices` → `navigate("sales.modal.view-sale", resourceId)`; "take me to the P&L" → `navigate("reports.profit-and-loss")`; "where do I manage users?" → `navigate(query: "user")` → `navigate("settings.modal.user_management")`. (The pre-merge tool names `find_dashboard_destinations` / `get_dashboard_url` still resolve as aliases.)
|
|
530
530
|
|
|
531
531
|
## Recommended Client Patterns
|
|
532
532
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jaz-cli
|
|
3
|
-
version: 5.
|
|
3
|
+
version: 5.55.1
|
|
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,
|
|
@@ -8,7 +8,7 @@ description: >-
|
|
|
8
8
|
precedence, output formats, entity resolution, and common workflow patterns.
|
|
9
9
|
Also use when the user asks how to use clio, what commands are available, or
|
|
10
10
|
how to automate accounting tasks from the command line. Covers all
|
|
11
|
-
|
|
11
|
+
72 command groups and 369 tools, including employee-expense claims.
|
|
12
12
|
license: MIT
|
|
13
13
|
compatibility: Requires Node.js >= 18.0.0. Install via npm install -g jaz-clio.
|
|
14
14
|
---
|
|
@@ -17,7 +17,7 @@ compatibility: Requires Node.js >= 18.0.0. Install via npm install -g jaz-clio.
|
|
|
17
17
|
|
|
18
18
|
> **Audience note:** for power users and CI/automation. Load this skill only when you're scripting from a terminal, building shell pipelines, or debugging from `clio --json` output. For day-to-day accounting inside Claude Desktop / Cowork, the MCP tools cover the common flows without dropping to the CLI.
|
|
19
19
|
|
|
20
|
-
You are working with **Clio** (`jaz-clio`) — the CLI for the Jaz accounting platform.
|
|
20
|
+
You are working with **Clio** (`jaz-clio`) — the CLI for the Jaz accounting platform. 72 command groups, 13 calculators, 12 job blueprints, 369 tools. Also fully compatible with Juan Accounting (same API, same endpoints).
|
|
21
21
|
|
|
22
22
|
## When to Use This Skill
|
|
23
23
|
|
|
@@ -291,9 +291,19 @@ Offline commands (no auth needed): `calc`, `jobs` (blueprints only), `capsule-tr
|
|
|
291
291
|
|
|
292
292
|
Everything else requires authentication (API key).
|
|
293
293
|
|
|
294
|
-
## Dashboard Deep Links
|
|
294
|
+
## Dashboard Deep Links
|
|
295
295
|
|
|
296
|
-
|
|
296
|
+
`clio navigate` (alias `nav`) builds dashboard URLs for the user ("open this invoice", "take me to the P&L"). Offline — no API key, no request.
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
clio navigate --query "profit" # discover the key
|
|
300
|
+
clio navigate reports.profit-and-loss # build the link
|
|
301
|
+
clio navigate sales.modal.view-sale --resource-id <id>
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Only the URL goes to stdout, so `clio nav <key> | pbcopy` copies a link and nothing else. **Never hand-construct a dashboard URL and never guess a key** — routes are not guessable and a wrong link is worse than no link. An unknown key comes back with near-matches; follow them rather than improvising.
|
|
305
|
+
|
|
306
|
+
The same operation is `navigate` on the MCP surface. Full usage rules live in the jaz-api skill under "Dashboard Deep Links"; the flag reference is in `references/command-catalog.md`.
|
|
297
307
|
|
|
298
308
|
## Error Handling
|
|
299
309
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Clio Command Catalog
|
|
2
2
|
|
|
3
|
-
Complete reference for all
|
|
3
|
+
Complete reference for all 72 command groups. Organized by domain.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -399,6 +399,24 @@ What the organization can be billed for. No create/update/delete upstream; maint
|
|
|
399
399
|
|
|
400
400
|
No free-text `--query`: the endpoint rejects it (`The query field is not supported for this entity`). Filters here are **plain strings, not expression objects** — `PurchaseItemFilter` declares them as bare `string`, so there is no `contains`. `purchaseResourceId` and `resourceId` also exist upstream and are reachable via `--filter`.
|
|
401
401
|
|
|
402
|
+
### `clio navigate` (alias: `nav`) — Dashboard deep links (offline, 1 tool)
|
|
403
|
+
```
|
|
404
|
+
clio navigate # discover: all destinations, capped
|
|
405
|
+
clio navigate --query invoice --kind modal # discover: narrow the search
|
|
406
|
+
clio navigate reports.profit-and-loss # build: a screen link
|
|
407
|
+
clio navigate sales.modal.view-sale --resource-id <id> # build: focus one record
|
|
408
|
+
clio navigate reports.profit-and-loss --org-id <orgResourceId>
|
|
409
|
+
```
|
|
410
|
+
**Offline** — no API key, no request. The route manifest is generated in the dashboard and committed here.
|
|
411
|
+
|
|
412
|
+
Omit the destination to SEARCH; give one to BUILD a link. Discovery caps its output and reports the true total, so narrow with `--query`, `--resource` or `--kind` when it says it truncated.
|
|
413
|
+
|
|
414
|
+
The `--query` search bridges accounting vocabulary to dashboard vocabulary: `invoice` finds the `sale` destinations, `bill` finds `purchase`, `credit note` finds `credit`. Without that, the word an accountant would type returns nothing.
|
|
415
|
+
|
|
416
|
+
`--resource-id` attaches a record and is valid only on a record-modal destination (`<resource>.modal.view-*`); a screen rejects it rather than silently dropping it. An unknown key comes back with near-matches.
|
|
417
|
+
|
|
418
|
+
The URL is the only thing on stdout — the label goes to stderr — so `clio nav <key> | pbcopy` copies a link and nothing else. Links carry no `&org=` unless you pass `--org-id`; without it the link opens in whichever organization the reader is already viewing.
|
|
419
|
+
|
|
402
420
|
### `clio modules` — Which features are enabled for the organization (read-only, 2 tools)
|
|
403
421
|
Provisioned upstream; no create/update/delete exists.
|
|
404
422
|
|