jaz-clio 5.1.0 → 5.1.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 +1 -1
- package/assets/skills/api/SKILL.md +1 -1
- package/assets/skills/cli/SKILL.md +3 -3
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +1 -1
- package/assets/skills/transaction-recipes/SKILL.md +1 -1
- package/cli.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ clio reports pdf profit-loss # Download P&L as PDF
|
|
|
42
42
|
clio calc lease --payment 5000 --term 36 --rate 5 # IFRS 16 (offline, instant)
|
|
43
43
|
clio jobs month-end --period 2026-03 # Step-by-step close playbook
|
|
44
44
|
clio magic create --file receipt.pdf # AI extracts → draft transaction
|
|
45
|
-
clio search
|
|
45
|
+
clio invoices search --query 'status:unpaid AND $500+' # Structured per-entity search
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
53 command groups. 16 report types. 13 calculators. 12 job playbooks. Every command supports `--json`. Run `clio --help` for the full list.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jaz-cli
|
|
3
|
-
version: 5.1.
|
|
3
|
+
version: 5.1.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,
|
|
@@ -14,7 +14,7 @@ compatibility: Requires Node.js >= 18.0.0. Install via npm install -g jaz-clio.
|
|
|
14
14
|
|
|
15
15
|
# Clio CLI Skill
|
|
16
16
|
|
|
17
|
-
You are working with **Clio** (`jaz-clio`) — the CLI for the Jaz accounting platform. 53 command groups, 13 calculators, 12 job blueprints,
|
|
17
|
+
You are working with **Clio** (`jaz-clio`) — the CLI for the Jaz accounting platform. 53 command groups, 13 calculators, 12 job blueprints, 265 agent tools. Also fully compatible with Juan Accounting (same API, same endpoints).
|
|
18
18
|
|
|
19
19
|
## When to Use This Skill
|
|
20
20
|
|
|
@@ -252,7 +252,7 @@ Sending `lineItems[]` to the FLAT endpoint silently ignores them and creates a $
|
|
|
252
252
|
|
|
253
253
|
**Reports & Exports**: `reports` (16 report types), `exports`
|
|
254
254
|
|
|
255
|
-
**AI & Automation**: `magic` (create, status, search, split), `
|
|
255
|
+
**AI & Automation**: `magic` (create, status, search, split), `quick-fix`, `capsules`, `capsule-transaction` (alias: `ct`, 13 recipe types)
|
|
256
256
|
|
|
257
257
|
**Calculators**: `calc` (loan, lease, depreciation, prepaid-expense, deferred-revenue, fx-reval, ecl, provision, fixed-deposit, asset-disposal, accrued-expense, leave-accrual, dividend)
|
|
258
258
|
|
package/cli.mjs
CHANGED
|
@@ -842,9 +842,9 @@ Response: { updated: string[], failed: [{ resourceId, error, errorCode }] }. On
|
|
|
842
842
|
`)[0]}`.toLowerCase(),u=n.filter(l=>c.includes(l)).length;return{tool:a,score:u}}).sort((a,c)=>c.score-a.score);return{namespace:o.name,description:o.description,tools:s.map(a=>({name:a.tool.name,description:a.tool.description.split(`
|
|
843
843
|
`)[0],...a.tool.searchHint?{searchHint:a.tool.searchHint}:{}}))}}),hint:"Call describe_tools with the tool names you need, then execute_tool to run them."}}var Rve={name:"search_tools",description:"Search for available Jaz accounting tools by keyword. Returns matching tool namespaces with tool names and descriptions. Call with empty query to list all namespaces. ALWAYS call this first to discover what tools are available.",inputSchema:Za({query:{type:"string",description:'Search keyword (e.g. "invoice", "bank recon", "depreciation"). Empty string lists all namespaces.'}},[])};function bJ(e){if(!Array.isArray(e)||!e.every(n=>typeof n=="string"))return{error:"Invalid `tools` parameter. Expected string[]."};if(e.length===0)return{error:"Provide at least one tool name. Use search_tools first to discover tool names."};let t=[],r=[];for(let n of e){let o=aE(n);if(!o){r.push(n);continue}t.push({...yJ(o),readOnly:o.readOnly,isDestructive:o.isDestructive??!1,isConcurrencySafe:o.isConcurrencySafe??!1,destructiveHint:!o.readOnly&&Nve(o),group:o.group})}return{tools:t,...r.length>0?{notFound:r,hint:`Tools not found: ${r.join(", ")}. Use search_tools to find correct names.`}:{}}}var kve={name:"describe_tools",description:"Get full JSON Schema (parameters, types, required fields) for specific tools. Call this after search_tools to get the exact input format before calling execute_tool.",inputSchema:Za({tools:{type:"array",items:{type:"string"},description:'Tool names to describe (e.g. ["create_invoice", "search_contacts"])'}},["tools"])},Fve={name:"execute_tool",description:"Execute a Jaz accounting tool. Call describe_tools first to get the required parameters. Pass the tool name and its arguments.",inputSchema:Za({tool:{type:"string",description:'Tool name (e.g. "create_invoice")'},arguments:{type:"object",description:"Tool arguments (see describe_tools for schema)"},org_id:{type:"string",description:"Organization ID (UUID). Required in multi-org mode (PAT or multiple API keys). Call list_organizations to get available IDs."}},["tool"])},vJ={name:"list_organizations",description:"List organizations available to the current authentication. Returns org names and resource IDs for use as org_id in execute_tool calls.",inputSchema:Za({},[])},M$=[Rve,kve,Fve];Mc();Zi();var Pve=new Set(["close_jobs","operational_jobs"]);function B$(e,t){return!!(Pve.has(e)||e==="recipes"&&t==="plan_recipe")}function Lve(e,t){return new qr({mode:"pat",token:e,orgId:t})}async function SJ(e,t=5e3){let r=new Map,n=[],o=a=>Promise.race([a,new Promise(c=>setTimeout(()=>c(null),t))]),i=e.map(a=>({auth:a,client:new qr(a)})),s=i[0]?.client??null;return await Promise.all(i.map(async({auth:a,client:c})=>{try{let u=await o(Ln(c));if(u)r.set(u.resourceId,{name:u.name,resourceId:u.resourceId,currency:u.currency,client:c});else{let l=a.mode==="direct"?"api-key":a.mode;n.push(`Org lookup returned empty (${l}).`)}}catch(u){let l=a.mode==="direct"?"api-key":a.mode;n.push(`Org lookup failed (${l}): ${u instanceof Error?u.message:"unknown"}`)}})),{orgMap:r,primaryClient:s,errors:n}}function EJ(e){e.command("mcp").description("Start MCP stdio server for Claude Code / Cowork").option("--api-key <key>","API key, PAT, or comma-separated keys (overrides stored/env)").action(async t=>{let r;try{r=yC(t.apiKey)}catch(b){process.stderr.write(`jaz-ai: ${b instanceof Error?b.message:b}
|
|
844
844
|
`),process.exit(1)}let n=e.version()??"0.0.0",o=new Map,i=null,s=r.length>1||r[0]?.mode==="pat";if(r.length>0){let b=await SJ(r);o=b.orgMap,i=b.primaryClient;for(let S of b.errors)process.stderr.write(`warning: ${S}
|
|
845
|
-
`)}let a="",c="";if(o.size>1){let b=[...o.values()].map(S=>`${S.name} (${S.currency})`);a=`Connected to ${o.size} organizations: ${b.join(", ")}.`,c=`${o.size} orgs`}else if(o.size===1){let b=[...o.values()][0];a=`Connected to: ${b.name} (${b.currency}).`,c=b.name}else if(i){let b=ed();if(b){let S=Qn(b);S?.orgName&&(a=`Connected to: ${S.orgName} (${S.currency}).`,c=`${S.orgName} (${b})`)}}let u=rl.map(b=>b.name).join(", "),l=i?"All API tools hit api.getjaz.com using the configured credentials.":"No API key configured
|
|
845
|
+
`)}let a="",c="";if(o.size>1){let b=[...o.values()].map(S=>`${S.name} (${S.currency})`);a=`Connected to ${o.size} organizations: ${b.join(", ")}.`,c=`${o.size} orgs`}else if(o.size===1){let b=[...o.values()][0];a=`Connected to: ${b.name} (${b.currency}).`,c=b.name}else if(i){let b=ed();if(b){let S=Qn(b);S?.orgName&&(a=`Connected to: ${S.orgName} (${S.currency}).`,c=`${S.orgName} (${b})`)}}let u=rl.map(b=>b.name).join(", "),l=i?"All API tools hit api.getjaz.com using the configured credentials.":"No API key configured. Only offline tools (calculators, job blueprints) are available. Set JAZ_API_KEY in connector settings or env var, or run `clio auth add` for full access.",d=s&&o.size>0?["","MULTI-ORG MODE:",`You have access to ${o.size} organization(s):`,...[...o.values()].map(b=>` - ${b.name} (org_id: ${b.resourceId}, ${b.currency})`),"","RULES:","1. Every execute_tool call for API tools MUST include org_id.","2. If the user mentions an org by name, match it to the org_id above.",`3. If the user hasn't specified an org, ask: "Which organization?"`,"4. Once the user picks an org, use it for all subsequent calls until they say otherwise.",'5. If the user says "switch to [org]", update the active org for subsequent calls.','6. Always confirm the org on the first tool call: "Using [Org Name]."','7. For cross-org queries (e.g. "compare Acme and Beta"), make separate execute_tool calls with different org_ids.',"8. Call list_organizations to refresh the org list if needed."]:[],f=[`Jaz accounting platform \u2014 ${el.length} tools across ${rl.length} namespaces.`,a,"","WORKFLOW: search_tools \u2192 describe_tools \u2192 execute_tool.","1. Call search_tools with a keyword to find relevant tools.","2. Call describe_tools with tool names to get full parameter schemas.","3. Call execute_tool with the tool name and arguments to run it.","",`Namespaces: ${u}.`,"","Key API rules (apply to all tools):","- All IDs are `resourceId` (never `id`).","- All transaction dates are `valueDate` (not issueDate/invoiceDate/date). Format: YYYY-MM-DD.","- Line item text field is `name` (not `description`).","- `saveAsDraft` defaults to false \u2014 omitting it finalizes the transaction.","- Response dates are epoch milliseconds (convert with new Date(ms)).","- Pagination: use `limit`/`offset` (not page/size). Search sort is required when offset present.","- Create responses return only `{ resourceId }` \u2014 GET the full entity after creation.","","Offline tools (no auth needed): 12 job blueprints (close_procedures, operational_jobs namespaces) and plan_recipe calculator.",l,...d].filter(b=>b!==void 0).join(`
|
|
846
846
|
`),p=new nS({name:"jaz-ai",version:n},{capabilities:{tools:{}},instructions:f}),m=s&&o.size>0?[...M$,vJ]:M$;p.setRequestHandler(F1,async()=>({tools:m.map(b=>({name:b.name,description:b.description,inputSchema:b.inputSchema,annotations:{readOnlyHint:b.name!=="execute_tool",openWorldHint:!0}}))})),p.setRequestHandler(Bf,async b=>{let S=b.params.name,I=b.params.arguments??{};if(S==="search_tools"){let O=I.query;if(O!==void 0&&typeof O!="string")return{content:[{type:"text",text:JSON.stringify({error:"Invalid `query` parameter. Expected string."})}],isError:!0};let N=DJ(O??"");return{content:[{type:"text",text:JSON.stringify(N,null,2)}]}}if(S==="describe_tools"){let O=bJ(I.tools);return{content:[{type:"text",text:JSON.stringify(O,null,2)}]}}if(S==="list_organizations"){if(!s||o.size===0)return{content:[{type:"text",text:JSON.stringify({error:"list_organizations is only available in multi-org mode (PAT or multiple API keys)."})}],isError:!0};if(r[0]?.mode==="pat")try{o=(await SJ(r,5e3)).orgMap}catch(O){process.stderr.write(`warning: org refresh failed, using cached list: ${O instanceof Error?O.message:"unknown"}
|
|
847
|
-
`)}return{content:[{type:"text",text:JSON.stringify({organizations:[...o.values()].map(({name:O,resourceId:N,currency:k})=>({name:O,resourceId:N,currency:k}))},null,2)}]}}if(S==="execute_tool"){let O=I.tool,N=I.arguments??{},k=I.org_id;if(!O)return{content:[{type:"text",text:JSON.stringify({error:"Missing `tool` parameter.",hint:'Call search_tools first, then describe_tools, then execute_tool with { tool: "tool_name", arguments: {...} }.'})}],isError:!0};let F=aE(O);if(!F)throw new Ce(ke.MethodNotFound,`Unknown tool: ${O}. Use search_tools to find available tools.`);if(!i&&!B$(F.group,F.name))return{content:[{type:"text",text:JSON.stringify({error:"No API key configured.",hint:"Set JAZ_API_KEY env var, run `clio auth add`, or pass --api-key. Offline tools (calculators, job blueprints) work without a key."})}],isError:!0};let J=i;if(s&&o.size>0&&!B$(F.group,F.name)){if(!k)return{content:[{type:"text",text:JSON.stringify({error:"Missing org_id. Multi-org mode requires an explicit organization for API tools.",hint:"Call list_organizations to see available orgs, then include org_id in execute_tool.",organizations:[...o.values()].map(({name:X,resourceId:W})=>({name:X,resourceId:W}))})}],isError:!0};let z=o.get(k);if(!z)return{content:[{type:"text",text:JSON.stringify({error:`Unknown org_id: "${k}".`,hint:"Call list_organizations to refresh the org list.",available:[...o.values()].map(({name:X,resourceId:W})=>({name:X,resourceId:W}))})}],isError:!0};let Y=r[0];J=Y?.mode==="pat"?Lve(Y.token,k):z.client}let Z=hJ(F,N);if(!Z.valid)return{content:[{type:"text",text:JSON.stringify({error:`Validation: ${Z.errors.join("; ")}`,hint:"Check required fields and types via describe_tools."})}],isError:!0};try{if(!J&&!B$(F.group,F.name))return{content:[{type:"text",text:JSON.stringify({error:"No API client available.",hint:"Set JAZ_API_KEY or pass --api-key."})}],isError:!0};let z={client:J},Y=await F.execute(z,N);return{content:[{type:"text",text:typeof Y=="string"?Y:JSON.stringify(Y,null,2)}]}}catch(z){return{content:[{type:"text",text:JSON.stringify(mJ(z))}],isError:!0}}}let _=s&&o.size>0?"search_tools, describe_tools, execute_tool, list_organizations":"search_tools, describe_tools, execute_tool";throw new Ce(ke.MethodNotFound,`Unknown tool: ${S}. Available tools: ${_}.`)});let h=new iS;await p.connect(h);let g=async()=>{await p.close(),process.exit(0)};process.on("SIGINT",g),process.on("SIGTERM",g),process.stdin.on("end",g);let D=c?` \u2014 ${c}`:"",v=i?"":" [offline mode \u2014 no API key]",y=m.length;process.stderr.write(`jaz-ai MCP server v${n} started (${el.length} tools, ${y} meta-tools, dynamic toolset)${D}${v}
|
|
847
|
+
`)}return{content:[{type:"text",text:JSON.stringify({organizations:[...o.values()].map(({name:O,resourceId:N,currency:k})=>({name:O,resourceId:N,currency:k}))},null,2)}]}}if(S==="execute_tool"){let O=I.tool,N=I.arguments??{},k=I.org_id;if(!O)return{content:[{type:"text",text:JSON.stringify({error:"Missing `tool` parameter.",hint:'Call search_tools first, then describe_tools, then execute_tool with { tool: "tool_name", arguments: {...} }.'})}],isError:!0};let F=aE(O);if(!F)throw new Ce(ke.MethodNotFound,`Unknown tool: ${O}. Use search_tools to find available tools.`);if(!i&&!B$(F.group,F.name))return{content:[{type:"text",text:JSON.stringify({error:"No API key configured.",hint:"Set JAZ_API_KEY in connector settings or env var, run `clio auth add`, or pass --api-key. Offline tools (calculators, job blueprints) work without a key."})}],isError:!0};let J=i;if(s&&o.size>0&&!B$(F.group,F.name)){if(!k)return{content:[{type:"text",text:JSON.stringify({error:"Missing org_id. Multi-org mode requires an explicit organization for API tools.",hint:"Call list_organizations to see available orgs, then include org_id in execute_tool.",organizations:[...o.values()].map(({name:X,resourceId:W})=>({name:X,resourceId:W}))})}],isError:!0};let z=o.get(k);if(!z)return{content:[{type:"text",text:JSON.stringify({error:`Unknown org_id: "${k}".`,hint:"Call list_organizations to refresh the org list.",available:[...o.values()].map(({name:X,resourceId:W})=>({name:X,resourceId:W}))})}],isError:!0};let Y=r[0];J=Y?.mode==="pat"?Lve(Y.token,k):z.client}let Z=hJ(F,N);if(!Z.valid)return{content:[{type:"text",text:JSON.stringify({error:`Validation: ${Z.errors.join("; ")}`,hint:"Check required fields and types via describe_tools."})}],isError:!0};try{if(!J&&!B$(F.group,F.name))return{content:[{type:"text",text:JSON.stringify({error:"No API client available.",hint:"Set JAZ_API_KEY or pass --api-key."})}],isError:!0};let z={client:J},Y=await F.execute(z,N);return{content:[{type:"text",text:typeof Y=="string"?Y:JSON.stringify(Y,null,2)}]}}catch(z){return{content:[{type:"text",text:JSON.stringify(mJ(z))}],isError:!0}}}let _=s&&o.size>0?"search_tools, describe_tools, execute_tool, list_organizations":"search_tools, describe_tools, execute_tool";throw new Ce(ke.MethodNotFound,`Unknown tool: ${S}. Available tools: ${_}.`)});let h=new iS;await p.connect(h);let g=async()=>{await p.close(),process.exit(0)};process.on("SIGINT",g),process.on("SIGTERM",g),process.stdin.on("end",g);let D=c?` \u2014 ${c}`:"",v=i?"":" [offline mode \u2014 no API key]",y=m.length;process.stderr.write(`jaz-ai MCP server v${n} started (${el.length} tools, ${y} meta-tools, dynamic toolset)${D}${v}
|
|
848
848
|
`)})}K();Te();He();Me();ut();We();var _J=[{key:"resourceId",header:"ID",format:oe},{key:"name",header:"Name"}];function IJ(e){let t=e.command("bank-rules").description("Manage bank reconciliation rules").addHelpText("after",`
|
|
849
849
|
Dynamic Strings (usable in name, reference \u2014 any free text field):
|
|
850
850
|
{{bankReference}} Bank record reference (e.g., INV-03/01/2025-01)
|