@zeyos/client 0.2.0 → 0.4.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/CHANGELOG.md +33 -4
- package/README.md +31 -1
- package/agents/README.md +4 -0
- package/agents/shared/zeyos-entity-map.md +5 -1
- package/agents/shared/zeyos-entity-reference.md +89 -33
- package/agents/zeyos-mail-operations/SKILL.md +7 -1
- package/agents/zeyos-mail-operations/references/workflows.md +19 -2
- package/agents/zeyos-platform-and-schema/SKILL.md +1 -1
- package/agents/zeyos-platform-and-schema/references/workflows.md +21 -5
- package/agents/zeyos-time-tracking/SKILL.md +48 -0
- package/agents/zeyos-time-tracking/references/workflows.md +230 -0
- package/agents/zeyos-work-management/SKILL.md +5 -2
- package/agents/zeyos-work-management/references/workflows.md +54 -4
- package/docs/02-javascript-client/03-making-requests.md +46 -1
- package/docs/03-cli/02-commands.md +63 -1
- package/docs/03-cli/03-configuration.md +37 -5
- package/docs/04-agent-workflows/01-agent-quickstart.md +24 -0
- package/docs/04-agent-workflows/03-cli-coverage-and-escalation.md +3 -2
- package/docs/06-okf/01-overview.md +70 -0
- package/docs/06-okf/02-producing-and-consuming.md +46 -0
- package/docs/06-okf/03-keeping-fresh.md +53 -0
- package/docs/06-okf/04-loops.md +58 -0
- package/docs/06-okf/_category_.json +9 -0
- package/okf/concepts/counting-and-sums.md +10 -0
- package/okf/concepts/dates-unix-seconds.md +12 -0
- package/okf/concepts/enums.md +14 -0
- package/okf/concepts/filters-vs-filter.md +14 -0
- package/okf/concepts/index.md +8 -0
- package/okf/concepts/operationid-vocabulary.md +17 -0
- package/okf/concepts/visibility-column.md +13 -0
- package/okf/entities/accounts.md +82 -0
- package/okf/entities/actionsteps.md +84 -0
- package/okf/entities/addresses.md +50 -0
- package/okf/entities/applicationassets.md +43 -0
- package/okf/entities/applications.md +62 -0
- package/okf/entities/appointments.md +79 -0
- package/okf/entities/associations.md +41 -0
- package/okf/entities/binfiles.md +32 -0
- package/okf/entities/campaigns.md +66 -0
- package/okf/entities/categories.md +55 -0
- package/okf/entities/channels.md +54 -0
- package/okf/entities/comments.md +44 -0
- package/okf/entities/components.md +46 -0
- package/okf/entities/contacts.md +96 -0
- package/okf/entities/contacts2contacts.md +42 -0
- package/okf/entities/contracts.md +83 -0
- package/okf/entities/couponcodes.md +58 -0
- package/okf/entities/coupons.md +69 -0
- package/okf/entities/customfields.md +59 -0
- package/okf/entities/davservers.md +74 -0
- package/okf/entities/devices.md +65 -0
- package/okf/entities/documents.md +76 -0
- package/okf/entities/dunning.md +82 -0
- package/okf/entities/dunning2transactions.md +46 -0
- package/okf/entities/entities2channels.md +42 -0
- package/okf/entities/events.md +57 -0
- package/okf/entities/feedservers.md +67 -0
- package/okf/entities/files.md +50 -0
- package/okf/entities/follows.md +40 -0
- package/okf/entities/forks.md +54 -0
- package/okf/entities/groups.md +48 -0
- package/okf/entities/groups2users.md +44 -0
- package/okf/entities/index.md +93 -0
- package/okf/entities/invitations.md +53 -0
- package/okf/entities/items.md +95 -0
- package/okf/entities/ledgers.md +56 -0
- package/okf/entities/likes.md +40 -0
- package/okf/entities/links.md +70 -0
- package/okf/entities/mailinglists.md +67 -0
- package/okf/entities/mailingrecipients.md +45 -0
- package/okf/entities/mailservers.md +77 -0
- package/okf/entities/messagereads.md +40 -0
- package/okf/entities/messages.md +104 -0
- package/okf/entities/notes.md +73 -0
- package/okf/entities/objects.md +70 -0
- package/okf/entities/opportunities.md +87 -0
- package/okf/entities/participants.md +52 -0
- package/okf/entities/payments.md +76 -0
- package/okf/entities/permissions.md +46 -0
- package/okf/entities/pricelists.md +70 -0
- package/okf/entities/pricelists2accounts.md +46 -0
- package/okf/entities/prices.md +49 -0
- package/okf/entities/projects.md +72 -0
- package/okf/entities/records.md +75 -0
- package/okf/entities/relateditems.md +43 -0
- package/okf/entities/resources.md +55 -0
- package/okf/entities/services.md +64 -0
- package/okf/entities/stocktransactions.md +72 -0
- package/okf/entities/storages.md +56 -0
- package/okf/entities/suppliers.md +51 -0
- package/okf/entities/tasks.md +86 -0
- package/okf/entities/tickets.md +86 -0
- package/okf/entities/transactions.md +118 -0
- package/okf/entities/users.md +66 -0
- package/okf/entities/weblets.md +66 -0
- package/okf/index.md +11 -0
- package/okf/log.md +4 -0
- package/okf/metrics/cash-received.md +10 -0
- package/okf/metrics/index.md +6 -0
- package/okf/metrics/invoiced-net-revenue.md +16 -0
- package/okf/metrics/open-customers.md +14 -0
- package/okf/metrics/overdue-receivables.md +12 -0
- package/okf/playbooks/customer-360.md +12 -0
- package/okf/playbooks/index.md +5 -0
- package/okf/playbooks/revenue-this-year.md +19 -0
- package/okf/playbooks/ticket-work-packet.md +11 -0
- package/package.json +9 -5
- package/scripts/data/okf-curation.mjs +258 -0
- package/scripts/generate-client.mjs +4 -275
- package/scripts/generate-okf.mjs +241 -0
- package/scripts/lib/okf.mjs +272 -0
- package/scripts/lib/spec-model.mjs +325 -0
- package/src/index.js +4 -0
- package/src/runtime/client.js +199 -18
- package/src/runtime/okf.js +237 -0
- package/samples/missioncontrol/README.md +0 -106
- package/samples/missioncontrol/fetch-data.mjs +0 -341
- package/samples/missioncontrol/index.html +0 -419
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Time Tracking Workflows
|
|
2
|
+
|
|
3
|
+
## Resources and operation IDs
|
|
4
|
+
|
|
5
|
+
These are dbref nouns; the REST/client operationIds differ for action steps (compound CamelCase):
|
|
6
|
+
|
|
7
|
+
- `tickets` -> `listTickets` / `getTicket` / `createTicket` / `updateTicket`
|
|
8
|
+
- `tasks` -> `listTasks` / `getTask` / `createTask` / `updateTask`
|
|
9
|
+
- `projects` -> `listProjects` / `getProject`
|
|
10
|
+
- `accounts` -> `listAccounts` / `getAccount`
|
|
11
|
+
- `actionsteps` -> `listActionSteps` / `getActionStep` / `createActionStep` / `updateActionStep` (not `listActionsteps`)
|
|
12
|
+
- current user -> `getUserInfo` (oauth2 service); `zeyos whoami --json` exposes its `sub`
|
|
13
|
+
|
|
14
|
+
See [../../shared/zeyos-entity-reference.md](../../shared/zeyos-entity-reference.md#entity-noun-to-rest-operationid) before calling `@zeyos/client`.
|
|
15
|
+
|
|
16
|
+
## Schema facts this skill relies on
|
|
17
|
+
|
|
18
|
+
- **Time entries are `actionsteps`.** The `effort` field is **minutes** (integer). There is no separate time-entry resource.
|
|
19
|
+
- **Actionstep foreign keys:** `task`, `ticket`, `account`, `transaction` — plus `assigneduser`, `date`, `duedate`, `status`, `effort`. **There is no `project` FK on an actionstep**, so project-level time attaches through a ticket/task in that project, or to the project's `account`.
|
|
20
|
+
- **Actionstep status:** `0` DRAFT · `1` COMPLETED · `2` CANCELLED · `3` BOOKED. Log already-done work as **COMPLETED (1)**; use **BOOKED (3)** only when the instance treats booked effort as the billed/locked record and the user says so.
|
|
21
|
+
- **Ticket/task status:** `0` NOT_STARTED · `1` AWAITING_ACCEPTANCE · `2` ACCEPTED · `3` REJECTED · `4` ACTIVE · `5` INACTIVE · `6` FEEDBACK_REQUIRED · `7` TESTING · `8` CANCELLED · `9` COMPLETED · `10` FAILED · `11` BOOKED. Treat **open/current = status `!IN [8,9,10,11]`** (exclude cancelled/completed/failed/booked). State this definition in the answer; the user can narrow it (e.g. only `4` ACTIVE).
|
|
22
|
+
- **Foreign keys per resource:** `tickets` carry `account`, `project`, `assigneduser`; `tasks` carry `ticket`, `project`, `assigneduser` (no `account` — reach the account through the task's ticket/project); `projects` carry `account`, `assigneduser`; `accounts` carry `lastname`, `firstname`, `customernum` (no `name` field).
|
|
23
|
+
- **Visibility:** `tickets`, `tasks`, `projects`, `accounts` expose `visibility` (use `0` for live records). `transactions` do **not** — never filter `visibility` there.
|
|
24
|
+
- All dates are **Unix timestamps in seconds**.
|
|
25
|
+
|
|
26
|
+
## Filter operators (server-side)
|
|
27
|
+
|
|
28
|
+
`{"field": value}` is equality. Object values take operators: `{">=":3}`, `{"!=":0}`, `{"IN":[1,3]}`, `{"!IN":[8,9,10,11]}`. For name search, `~~*` is case-insensitive LIKE: `{"lastname": {"~~*": "%acme%"}}`. The client accepts `filters` (plural); the CLI flag is `--filter` (it writes `filters` internally).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Pattern: "What are my current tickets / tasks / action steps?"
|
|
33
|
+
|
|
34
|
+
1. Resolve the current user id:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
zeyos whoami --json # read the "sub" field — this is your users.ID
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. List open work assigned to that id. Use `--limit` high enough that nothing is silently truncated, or `zeyos count` first if the user asked "how many".
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# my open tickets, most urgent first
|
|
44
|
+
zeyos list tickets \
|
|
45
|
+
--fields ID,ticketnum,name,status,priority,duedate,account.lastname,project \
|
|
46
|
+
--filter '{"assigneduser":<sub>,"visibility":0,"status":{"!IN":[8,9,10,11]}}' \
|
|
47
|
+
--sort -priority,+duedate \
|
|
48
|
+
--limit 200 --json
|
|
49
|
+
|
|
50
|
+
# my open tasks
|
|
51
|
+
zeyos list tasks \
|
|
52
|
+
--fields ID,tasknum,name,status,priority,duedate,ticket,project,projectedeffort \
|
|
53
|
+
--filter '{"assigneduser":<sub>,"visibility":0,"status":{"!IN":[8,9,10,11]}}' \
|
|
54
|
+
--sort -priority,+duedate --limit 200 --json
|
|
55
|
+
|
|
56
|
+
# my open action steps (follow-ups)
|
|
57
|
+
zeyos list actionsteps \
|
|
58
|
+
--fields ID,actionnum,name,status,date,duedate,effort,ticket,task,account \
|
|
59
|
+
--filter '{"assigneduser":<sub>,"status":0}' \
|
|
60
|
+
--sort +duedate --limit 200 --json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Client form:
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
const me = await client.oauth2.getUserInfo(); // me.sub === users.ID (string)
|
|
67
|
+
const myTickets = await client.api.listTickets({
|
|
68
|
+
fields: ['ID', 'ticketnum', 'name', 'status', 'priority', 'duedate', 'account.lastname', 'project'],
|
|
69
|
+
filters: { assigneduser: me.sub, visibility: 0, status: { '!IN': [8, 9, 10, 11] } },
|
|
70
|
+
limit: 200,
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
3. Report the resolved user and the open-status definition, then the list ordered by priority and due date. Flag overdue items (`duedate < now`).
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Pattern: Interactive time logging — "Log 60 minutes of work for client XYZ"
|
|
79
|
+
|
|
80
|
+
This is the headline interactive flow. Run each step; ask the user only at the marked decision points.
|
|
81
|
+
|
|
82
|
+
### Step 1 — Parse the request
|
|
83
|
+
|
|
84
|
+
- **Duration -> minutes.** "60 minutes" -> `60`; "2 hours" -> `120`; "1.5h"/"an hour and a half" -> `90`; "half an hour" -> `30`. `effort` is integer minutes.
|
|
85
|
+
- **Date.** Default to now (`date` = current Unix seconds). Honor an explicit date if given ("yesterday", "on Monday").
|
|
86
|
+
- **Note.** Use any description the user gave ("call about the renewal") as the actionstep `name`/`description`; otherwise compose a short one and confirm it.
|
|
87
|
+
|
|
88
|
+
### Step 2 — Resolve the account (ask only if ambiguous)
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
zeyos list accounts \
|
|
92
|
+
--fields ID,customernum,lastname,firstname,type \
|
|
93
|
+
--filter '{"visibility":0,"lastname":{"~~*":"%xyz%"}}' \
|
|
94
|
+
--limit 25 --json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- Also try `customernum` and `firstname` if `lastname` yields nothing.
|
|
98
|
+
- **0 matches:** report it and ask for a customer number or exact name — do not create anything.
|
|
99
|
+
- **1 match:** state it ("Logging against ACME Corp (#10042)") and continue.
|
|
100
|
+
- **>1 match (DECISION POINT):** list the candidates with `customernum`, name, and `type`, and ask which one. Do not guess.
|
|
101
|
+
|
|
102
|
+
### Step 3 — Enumerate candidate work items for that account
|
|
103
|
+
|
|
104
|
+
Run these in parallel; you are building the menu of places the time could land. (Tasks have no `account` FK, so reach them through the account's tickets/projects.)
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# open tickets on the account
|
|
108
|
+
zeyos list tickets --fields ID,ticketnum,name,status,priority \
|
|
109
|
+
--filter '{"account":<accountId>,"visibility":0,"status":{"!IN":[8,9,10,11]}}' --limit 50 --json
|
|
110
|
+
|
|
111
|
+
# active projects on the account
|
|
112
|
+
zeyos list projects --fields ID,projectnum,name,status \
|
|
113
|
+
--filter '{"account":<accountId>,"visibility":0,"status":{"!IN":[8,9,10,11]}}' --limit 50 --json
|
|
114
|
+
|
|
115
|
+
# open tasks under those tickets/projects (use the IDs gathered above)
|
|
116
|
+
zeyos list tasks --fields ID,tasknum,name,status,ticket,project \
|
|
117
|
+
--filter '{"visibility":0,"status":{"!IN":[8,9,10,11]},"ticket":{"IN":[<ticketIds>]}}' --limit 50 --json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 4 — Choose the attachment (DECISION POINT)
|
|
121
|
+
|
|
122
|
+
Present the candidates grouped (tickets / tasks / projects) and ask where the time should go. Map the choice to exactly one actionstep FK:
|
|
123
|
+
|
|
124
|
+
- a ticket -> `ticket: <id>`
|
|
125
|
+
- a task -> `task: <id>`
|
|
126
|
+
- a project -> attach to a ticket/task in that project, or fall back to the project's `account` (no `project` FK exists on actionsteps — say so)
|
|
127
|
+
- "just the account / general" or no work items exist -> `account: <accountId>`
|
|
128
|
+
|
|
129
|
+
If there is exactly one obvious candidate (e.g. a single open ticket), propose it as the default and let the user confirm rather than asking open-endedly.
|
|
130
|
+
|
|
131
|
+
### Step 5 — Preview, confirm, then write
|
|
132
|
+
|
|
133
|
+
Preview the exact request without sending it, show it to the user, and create it only after confirmation:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# dry-run preview (no network, no write)
|
|
137
|
+
zeyos create actionstep \
|
|
138
|
+
--name "Call about the renewal" \
|
|
139
|
+
--ticket <ticketId> \
|
|
140
|
+
--account <accountId> \
|
|
141
|
+
--assigneduser <sub> \
|
|
142
|
+
--effort 60 --status 1 --date <nowSeconds> \
|
|
143
|
+
--query
|
|
144
|
+
|
|
145
|
+
# after the user confirms, drop --query to actually create, then read it back
|
|
146
|
+
zeyos create actionstep --name "Call about the renewal" --ticket <ticketId> \
|
|
147
|
+
--assigneduser <sub> --effort 60 --status 1 --date <nowSeconds> --json
|
|
148
|
+
zeyos get actionstep <newId> --json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Client form:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
const now = Math.floor(Date.now() / 1000);
|
|
155
|
+
const created = await client.api.createActionStep({
|
|
156
|
+
name: 'Call about the renewal',
|
|
157
|
+
ticket: ticketId, // or task / account — exactly one work anchor
|
|
158
|
+
assigneduser: me.sub,
|
|
159
|
+
effort: 60, // minutes
|
|
160
|
+
status: 1, // COMPLETED (logged work)
|
|
161
|
+
date: now,
|
|
162
|
+
});
|
|
163
|
+
const verify = await client.api.getActionStep({ ID: created.ID });
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Set **one** of `ticket` / `task` / `account` as the work anchor (a ticket already implies its account, so you do not need both). Report the created id, the anchor, effort minutes, and date.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Pattern: "How much time did I log this week?" (timesheet summary)
|
|
171
|
+
|
|
172
|
+
The read complement to logging — totals the effort the current user already booked over a period, optionally grouped by account/ticket.
|
|
173
|
+
|
|
174
|
+
1. Resolve the current user id (`zeyos whoami --json` → `sub`).
|
|
175
|
+
2. Normalize the window to Unix **seconds**. The actionstep `date` field carries the business date of the entry; filter on it.
|
|
176
|
+
3. List the user's time entries in the window and sum `effort` (minutes). Count only COMPLETED (1) and BOOKED (3) — those are real logged time, not open follow-ups (status 0).
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# my logged minutes between two timestamps
|
|
180
|
+
zeyos list actionsteps \
|
|
181
|
+
--fields ID,name,effort,date,status,account,ticket,task \
|
|
182
|
+
--filter '{"assigneduser":<sub>,"status":{"IN":[1,3]},"date":{">=":<weekStart>,"<=":<weekEnd>}}' \
|
|
183
|
+
--limit 10000 --json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
const me = await client.oauth2.getUserInfo();
|
|
188
|
+
const rows = await client.api.listActionSteps({
|
|
189
|
+
fields: ['ID', 'effort', 'date', 'status', 'account', 'ticket', 'task'],
|
|
190
|
+
filters: { assigneduser: me.sub, status: { IN: [1, 3] }, date: { '>=': weekStart, '<=': weekEnd } },
|
|
191
|
+
limit: 10000,
|
|
192
|
+
});
|
|
193
|
+
const totalMinutes = rows.reduce((sum, r) => sum + (Number(r.effort) || 0), 0);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
4. Sum `effort` as minutes; convert to hours only if asked. To break down "by account/ticket", group the rows by the FK and resolve the account/ticket names with a second query. Report the total and the breakdown, and state the window and status set you used.
|
|
197
|
+
|
|
198
|
+
## Pattern: Adjust or correct a logged entry
|
|
199
|
+
|
|
200
|
+
For "actually that was 90 minutes, not 60" or "move that time to ticket 813" right after logging — or any later correction.
|
|
201
|
+
|
|
202
|
+
1. Get the entry first so you preview the current values: `zeyos get actionstep <id> --json`.
|
|
203
|
+
2. Build a minimal PATCH with only the changed fields. Preview with `--query`, confirm with the user (it is a mutation on an existing record), then update and read back.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
zeyos update actionstep <id> --effort 90 --query # preview the change
|
|
207
|
+
zeyos update actionstep <id> --effort 90 --json # after confirmation
|
|
208
|
+
zeyos get actionstep <id> --json # verify
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
await client.api.updateActionStep({ ID: id, effort: 90 }); // spread form: ID + changed fields
|
|
213
|
+
const verify = await client.api.getActionStep({ ID: id });
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Only correct entries the user pointed to (by id, or one you just created in this turn). Re-anchoring time to a different work item means changing the `ticket`/`task`/`account` FK — set the new anchor and clear the old one if it conflicts. Never bulk-rewrite a category of entries.
|
|
217
|
+
|
|
218
|
+
## Degrading when there is no human (automated / harness runs)
|
|
219
|
+
|
|
220
|
+
- "My work" reads still work: resolve `sub`, run the list, report it.
|
|
221
|
+
- For a **write**, never break ambiguity by guessing. If the account or the work item is ambiguous and nothing can be asked, stop and report the candidates and what was missing. A wrong foreign key on a created time entry is worse than an unanswered request.
|
|
222
|
+
|
|
223
|
+
## Common failure modes
|
|
224
|
+
|
|
225
|
+
- Counting a `list` page instead of the real total — use `zeyos count` for "how many of my …".
|
|
226
|
+
- Filtering `visibility` on `transactions` (no such column -> HTTP 400).
|
|
227
|
+
- Putting effort in hours — `effort` is **minutes**.
|
|
228
|
+
- Trying to set a `project` FK on an actionstep — it does not exist; anchor on a ticket/task/account instead.
|
|
229
|
+
- Treating BOOKED (status 11) tickets as current — they are terminal; the open set excludes `[8,9,10,11]`.
|
|
230
|
+
- Logging time against a user id you guessed — always read `sub` from `whoami`.
|
|
@@ -7,12 +7,15 @@ description: Manage ZeyOS tickets, tasks, projects, action steps, assignees, and
|
|
|
7
7
|
|
|
8
8
|
Read [../shared/zeyos-agent-operating-guide.md](../shared/zeyos-agent-operating-guide.md) and [../shared/zeyos-query-patterns.md](../shared/zeyos-query-patterns.md) first. Read [../shared/zeyos-entity-map.md](../shared/zeyos-entity-map.md) when the request crosses users, accounts, tickets, tasks, and projects. Read [references/workflows.md](references/workflows.md) for the concrete query patterns.
|
|
9
9
|
|
|
10
|
+
For **first-person** requests ("what are *my* current tickets?", "my open tasks") or for **recording new time** ("log 60 minutes for client XYZ"), use [../zeyos-time-tracking/SKILL.md](../zeyos-time-tracking/SKILL.md) instead — it resolves the current user and runs the interactive account → work-item → time-entry flow. This skill stays focused on third-person analytical queues, tracing, and effort *summaries*.
|
|
11
|
+
|
|
10
12
|
Typical prompts:
|
|
11
13
|
|
|
12
14
|
- "On which projects did Max Power work in the last two weeks?"
|
|
13
15
|
- "Show overdue high-priority tickets for customer ACME."
|
|
14
16
|
- "Which open tasks are blocking Project Atlas?"
|
|
15
17
|
- "Which action steps are due this week for ACME?"
|
|
18
|
+
- "How much booked effort did this user log last week?"
|
|
16
19
|
- "Create a follow-up ticket for this billing issue."
|
|
17
20
|
|
|
18
21
|
## Workflow
|
|
@@ -22,10 +25,10 @@ Typical prompts:
|
|
|
22
25
|
3. Start with the narrowest query that can answer the question:
|
|
23
26
|
- use `tickets` for queue, backlog, priority, and account-linked support work
|
|
24
27
|
- use `tasks` for actionable delivery work and short-lived assignments
|
|
25
|
-
- use `actionsteps` for smaller cross-record follow-ups attached to tasks, tickets, accounts, or transactions
|
|
28
|
+
- use `actionsteps` for smaller cross-record follow-ups and effort/time-entry evidence attached to tasks, tickets, accounts, or transactions
|
|
26
29
|
- use `projects` for top-level initiative state
|
|
27
30
|
4. Follow relationships only after the primary record set is clear.
|
|
28
|
-
5. Treat "worked on" as a proxy unless
|
|
31
|
+
5. Treat "worked on" as a proxy unless actionstep effort/date evidence exists. Assignment and timestamps show involvement; `actionsteps.effort` on `COMPLETED` or `BOOKED` records is stronger time-entry evidence.
|
|
29
32
|
6. Distinguish direct project assignment from project inference through linked tickets.
|
|
30
33
|
7. When the question is really about account or transaction follow-up, check `actionsteps` before inventing a new task.
|
|
31
34
|
8. For mutations, preview the affected record first and update with an explicit PATCH body.
|
|
@@ -9,10 +9,20 @@
|
|
|
9
9
|
- `users`: system identities for assignees
|
|
10
10
|
|
|
11
11
|
These are dbref nouns, not operationIds. Note `actionsteps` -> `listActionSteps` /
|
|
12
|
-
`getActionStep` / `createActionStep`
|
|
12
|
+
`getActionStep` / `createActionStep` / `updateActionStep` / `deleteActionStep`
|
|
13
|
+
(compound CamelCase, not `listActionsteps`). See
|
|
13
14
|
[../../shared/zeyos-entity-reference.md](../../shared/zeyos-entity-reference.md#entity-noun-to-rest-operationid)
|
|
14
15
|
before calling `@zeyos/client`.
|
|
15
16
|
|
|
17
|
+
Actionstep status values:
|
|
18
|
+
|
|
19
|
+
- `0` = DRAFT / open follow-up
|
|
20
|
+
- `1` = COMPLETED
|
|
21
|
+
- `2` = CANCELLED
|
|
22
|
+
- `3` = BOOKED
|
|
23
|
+
|
|
24
|
+
Use `effort` as minutes of effort only when the question is about time entries or booked/completed work. Do not infer booked time from task assignment alone.
|
|
25
|
+
|
|
16
26
|
## Resolve Before Querying
|
|
17
27
|
|
|
18
28
|
1. Resolve the user or account first.
|
|
@@ -32,7 +42,7 @@ Recommended approach:
|
|
|
32
42
|
1. Resolve the user from `users.name` or `users.email`.
|
|
33
43
|
2. Query recent tasks assigned to that user with `lastmodified > cutoff`.
|
|
34
44
|
3. Query recent tickets assigned to that user with `lastmodified > cutoff`.
|
|
35
|
-
4.
|
|
45
|
+
4. Query recent `actionsteps` for the same user when you need stronger evidence of follow-up activity or booked effort.
|
|
36
46
|
5. Collect direct `project` links from tasks and tickets.
|
|
37
47
|
6. For tasks that only link to a ticket, fetch the ticket or include `ticket.project` if available in the selected fields.
|
|
38
48
|
7. For action steps linked to tasks or tickets, infer the project through the linked parent only if the user asked for a broad activity summary.
|
|
@@ -67,7 +77,7 @@ const recentTickets = await client.api.listTickets({
|
|
|
67
77
|
|
|
68
78
|
Important caveat:
|
|
69
79
|
|
|
70
|
-
-
|
|
80
|
+
- Assignment-based "worked on" answers are activity proxies. `actionsteps` with `date`, `status` COMPLETED/BOOKED, and `effort` are the better evidence for time-entry summaries.
|
|
71
81
|
|
|
72
82
|
## Pattern: Review A Ticket Queue
|
|
73
83
|
|
|
@@ -87,6 +97,13 @@ zeyos list tickets \
|
|
|
87
97
|
Follow up with `tasks` only if the answer requires execution detail below the ticket level.
|
|
88
98
|
Follow up with `actionsteps` if the queue management style in this instance uses reminders or next steps below the ticket.
|
|
89
99
|
|
|
100
|
+
For ticket work packets, include:
|
|
101
|
+
|
|
102
|
+
- ticket status, priority, due date, account/project links
|
|
103
|
+
- open tasks linked by `task.ticket`
|
|
104
|
+
- open actionsteps linked by `actionstep.ticket` or by task
|
|
105
|
+
- recent messages linked by `message.ticket` if the request asks for customer context
|
|
106
|
+
|
|
90
107
|
## Pattern: Overdue Work For An Account Or Project
|
|
91
108
|
|
|
92
109
|
Use this for prompts like:
|
|
@@ -121,6 +138,39 @@ Recommended approach:
|
|
|
121
138
|
4. Keep due date and status visible in the result.
|
|
122
139
|
5. If the anchor is a transaction and the user also wants broader work context, then check related tickets or account-level tasks second.
|
|
123
140
|
|
|
141
|
+
CLI examples:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
zeyos list actionsteps \
|
|
145
|
+
--fields ID,actionnum,name,status,date,duedate,effort,ticket,task,account,transaction \
|
|
146
|
+
--filter '{"ticket":812}' \
|
|
147
|
+
--sort +duedate \
|
|
148
|
+
--limit 100 \
|
|
149
|
+
--json
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
For counts:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
zeyos count actionsteps --filter '{"ticket":812,"status":0}' --json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Pattern: Time Entry / Effort Summaries
|
|
159
|
+
|
|
160
|
+
Use this for prompts like:
|
|
161
|
+
|
|
162
|
+
- "How many minutes were booked on ticket 812 last week?"
|
|
163
|
+
- "Summarize completed actionstep effort for this account."
|
|
164
|
+
- "Which user logged effort against this project?"
|
|
165
|
+
|
|
166
|
+
Recommended approach:
|
|
167
|
+
|
|
168
|
+
1. Resolve the anchor and the date window.
|
|
169
|
+
2. Query `actionsteps` with fields `ID`, `date`, `status`, `effort`, and the relevant FK (`ticket`, `task`, `account`, or `transaction`).
|
|
170
|
+
3. Include statuses `1` COMPLETED and `3` BOOKED for time-entry totals unless the user asks for drafts/open follow-ups.
|
|
171
|
+
4. Sum `effort` as minutes; convert to hours only if the user asked for hours.
|
|
172
|
+
5. Keep task/ticket assignment separate from effort totals.
|
|
173
|
+
|
|
124
174
|
## Pattern: Create Follow-Up Work
|
|
125
175
|
|
|
126
176
|
For prompts like:
|
|
@@ -136,7 +186,7 @@ Recommended approach:
|
|
|
136
186
|
- use `project` if the follow-up is project-wide
|
|
137
187
|
- use `actionsteps` if the follow-up is small, account-scoped, or transaction-scoped and does not justify a standalone task
|
|
138
188
|
- keep `visibility: 0`
|
|
139
|
-
3. Confirm the new owner, due date, and priority if they are not explicit.
|
|
189
|
+
3. Confirm the new owner, due date, and priority/effort if they are not explicit.
|
|
140
190
|
4. Use explicit PATCH or create bodies and return the created record ID.
|
|
141
191
|
|
|
142
192
|
## Common Failure Modes
|
|
@@ -253,6 +253,26 @@ const page2 = await client.api.listTickets({
|
|
|
253
253
|
Use `count: true` to get the total number of matching records without fetching the full dataset. This is useful for building pagination controls.
|
|
254
254
|
:::
|
|
255
255
|
|
|
256
|
+
### Auto-pagination
|
|
257
|
+
|
|
258
|
+
To iterate an entire result set without managing `offset` yourself, use `client.paginate(operationId, input, opts)` — an async iterator that pages until a short/empty page (or `opts.max`) is reached. It removes the off-by-one and "I only got the first 1000 / 50 rows" mistakes the list caps otherwise invite.
|
|
259
|
+
|
|
260
|
+
```js
|
|
261
|
+
// Stream every matching ticket, one page at a time
|
|
262
|
+
for await (const ticket of client.paginate('listTickets', { filters: { visibility: 0 } }, { pageSize: 1000 })) {
|
|
263
|
+
process(ticket);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Eagerly collect up to a cap
|
|
267
|
+
const recent = await client.collect(
|
|
268
|
+
'listTickets',
|
|
269
|
+
{ filters: { visibility: 0 }, sort: ['-lastmodified'] },
|
|
270
|
+
{ pageSize: 500, max: 2000 }
|
|
271
|
+
);
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
`opts`: `pageSize` (default 1000, clamped to the server max of 10000), `max` (stop after N records), and `requestOptions` (forwarded to each underlying call, e.g. `{ signal, timeoutMs }`). `collect` is the eager array form of `paginate`.
|
|
275
|
+
|
|
256
276
|
## Normalising List Responses
|
|
257
277
|
|
|
258
278
|
List endpoints are not uniform across the full surface area. Depending on the endpoint and response mode, you may see:
|
|
@@ -432,9 +452,32 @@ const noRetry = createZeyosClient({ platform: 'live', instance: 'demo', retry: f
|
|
|
432
452
|
Only `429`/`503` are retried by default -- statuses that clearly mean "try again later". `5xx` codes such as `500`/`502` are **not** retried automatically, to avoid re-applying a non-idempotent write that may have partially succeeded. Add them to `retryOn` only for read-heavy workloads.
|
|
433
453
|
:::
|
|
434
454
|
|
|
455
|
+
### Request timeout
|
|
456
|
+
|
|
457
|
+
A request with no built-in deadline can hang indefinitely if the connection stalls (e.g. an instance restarting). Set `timeoutMs` to bound each attempt; it composes with any `AbortSignal` you pass. The timeout applies **per attempt**, so a retry gets a fresh deadline.
|
|
458
|
+
|
|
459
|
+
```js
|
|
460
|
+
// Per request
|
|
461
|
+
await client.api.listTickets({ filters: { visibility: 0 } }, { timeoutMs: 8000 });
|
|
462
|
+
|
|
463
|
+
// Or a client-wide default
|
|
464
|
+
const client = createZeyosClient({ platform: 'live', instance: 'demo', timeoutMs: 8000 });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
A timeout rejects with an `Error` whose `isTimeout === true` (and `code === 'ETIMEDOUT'`). A timeout is distinct from a caller abort: aborting your own `AbortSignal` always propagates immediately and is never retried.
|
|
468
|
+
|
|
469
|
+
### Network-error retries
|
|
470
|
+
|
|
471
|
+
Network-level failures (a dropped connection, DNS blip, or a timeout) are retried for **read** operations only — `GET`/`HEAD` plus side-effect-free `list`/`count`/`search` queries — using the same retry budget and backoff. Writes (`create`/`update`/`delete`) are **never** auto-retried on a network error, so a dropped connection can't cause a duplicate mutation. Override per request or per client with `retryOnNetworkError: true | false`.
|
|
472
|
+
|
|
473
|
+
```js
|
|
474
|
+
await client.api.listTickets({ filters: {} }, { retryOnNetworkError: true }); // force (already on for reads)
|
|
475
|
+
await client.api.createTicket({ name: 'x' }, { retryOnNetworkError: true }); // opt a write in, at your own risk
|
|
476
|
+
```
|
|
477
|
+
|
|
435
478
|
## Error Handling
|
|
436
479
|
|
|
437
|
-
All API errors are thrown as `ZeyosApiError` instances. This class extends `Error` and includes structured information about the failed request.
|
|
480
|
+
All API errors are thrown as `ZeyosApiError` instances. This class extends `Error` and includes structured information about the failed request. When the server returns an error body with a message, a short snippet of it is folded into `err.message` (e.g. `api.listTickets failed with HTTP 400: unknown filter field: bogus`), so the thrown error says *why*, not just the status code. The full body is always on `err.body`.
|
|
438
481
|
|
|
439
482
|
```js
|
|
440
483
|
import { ZeyosApiError } from '@zeyos/client';
|
|
@@ -535,6 +578,8 @@ All generated methods and `client.request()` accept an optional second argument
|
|
|
535
578
|
| Option | Type | Description |
|
|
536
579
|
|--------|------|-------------|
|
|
537
580
|
| `signal` | `AbortSignal` | An `AbortController` signal to cancel the request |
|
|
581
|
+
| `timeoutMs` | `number` | Abort this attempt after N ms (composes with `signal`); also settable client-wide as `timeoutMs` |
|
|
582
|
+
| `retryOnNetworkError` | `boolean` | Force/disable retrying network errors & timeouts for this call (default: on for reads, off for writes) |
|
|
538
583
|
| `raw` | `boolean` | Return the full response envelope instead of just the data |
|
|
539
584
|
| `auth` | `string \| { mode?: string, accessToken?: string, access_token?: string, refreshToken?: string, refresh_token?: string, clientId?: string, client_id?: string, clientSecret?: string, client_secret?: string }` | Override the authentication mode or credentials for this request |
|
|
540
585
|
| `baseUrl` | `string` | Override the base URL for this request |
|
|
@@ -14,6 +14,7 @@ These options work with any command:
|
|
|
14
14
|
|--------|-------------|
|
|
15
15
|
| `--json` | Output as formatted JSON |
|
|
16
16
|
| `--yaml` | Output as YAML |
|
|
17
|
+
| `--profile <name>` | Use a named credential profile for this command |
|
|
17
18
|
| `--no-color` | Disable ANSI color output |
|
|
18
19
|
| `-h`, `--help` | Show help for a command |
|
|
19
20
|
|
|
@@ -101,6 +102,36 @@ zeyos whoami --show-token --json # explicitly include the current access token
|
|
|
101
102
|
|
|
102
103
|
---
|
|
103
104
|
|
|
105
|
+
## profile
|
|
106
|
+
|
|
107
|
+
Manage named credential profiles and switch between ZeyOS instances. See [Configuration → Profiles](./03-configuration.md#profiles) for the full model.
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
zeyos profile <list|current|use|add|remove> [options]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
| Command | Description |
|
|
114
|
+
|---------|-------------|
|
|
115
|
+
| `profile list` | List all profiles; the active one is marked `*`, with token status |
|
|
116
|
+
| `profile current` | Show which profile resolves right now, and why (flag/env/pin/active) |
|
|
117
|
+
| `profile use <name>` | Make `<name>` the active profile (global) |
|
|
118
|
+
| `profile use <name> --local` | Pin `<name>` to the current project (`.zeyos/profile`) |
|
|
119
|
+
| `profile add <name> [opts]` | Create/update a profile (`--base-url`, `--client-id`, `--secret`, or `--from-current`) |
|
|
120
|
+
| `profile remove <name>` | Delete a profile |
|
|
121
|
+
|
|
122
|
+
**Examples:**
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
zeyos profile add dev --base-url https://zeyos.cms-it.de/dev
|
|
126
|
+
zeyos profile add prod --from-current # snapshot current credentials
|
|
127
|
+
zeyos login --profile prod # authenticate into & activate a profile
|
|
128
|
+
zeyos profile use dev # switch active profile
|
|
129
|
+
zeyos profile use prod --local # pin to this project
|
|
130
|
+
zeyos list tickets --profile dev # one-off override on any command
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
104
135
|
## list
|
|
105
136
|
|
|
106
137
|
Query and list records for a resource with filtering, sorting, and pagination.
|
|
@@ -363,7 +394,10 @@ List all curated CLI resources and their operations. This is the authoritative b
|
|
|
363
394
|
zeyos resources
|
|
364
395
|
```
|
|
365
396
|
|
|
366
|
-
Shows a table of all CLI-supported resource types and available operations.
|
|
397
|
+
Shows a table of all CLI-supported resource types and available operations. Operational
|
|
398
|
+
workflows can use `actionstep` / `actionsteps` / `time-entries` for follow-ups and
|
|
399
|
+
effort records. Read-only platform schema definitions are available as `customfield` /
|
|
400
|
+
`customfields` with `list`, `get`, and therefore `count` support.
|
|
367
401
|
|
|
368
402
|
---
|
|
369
403
|
|
|
@@ -447,6 +481,34 @@ Skills are copied into `<dir>/<name>/`, with the shared reference files installe
|
|
|
447
481
|
|
|
448
482
|
---
|
|
449
483
|
|
|
484
|
+
## okf
|
|
485
|
+
|
|
486
|
+
Work with the [Open Knowledge Format](../06-okf/01-overview.md) bundle that ships with the
|
|
487
|
+
client — a portable Markdown description of the ZeyOS data model (one concept per
|
|
488
|
+
API-backed entity) plus curated metrics, playbooks, and query concepts.
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
zeyos okf list # list concepts (type, id, title); --json for automation
|
|
492
|
+
zeyos okf show tickets # print a concept (bare resource name, or entities/tickets)
|
|
493
|
+
zeyos okf check # validate OKF v0.1 conformance (exit non-zero on error)
|
|
494
|
+
zeyos okf export --out ./okf # copy the shipped bundle into a directory
|
|
495
|
+
zeyos okf build --out ./okf # synthesize a bundle from the client's schema
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
| Subcommand | What it does |
|
|
499
|
+
|-----------|--------------|
|
|
500
|
+
| `list` | List the concepts in the bundle (`--json`/`--yaml` supported). |
|
|
501
|
+
| `show <concept>` | Print one concept doc. Accepts a bare resource (`tickets`) or full id (`entities/tickets`). |
|
|
502
|
+
| `check` | Validate the bundle for OKF v0.1 conformance; exits non-zero on any error (CI-friendly). |
|
|
503
|
+
| `export` | Copy the shipped `okf/` bundle into `--out` (default `./okf`); `--force` to overwrite. |
|
|
504
|
+
| `build` | Synthesize a structural bundle from the client's schema into `--out` (default `./okf`). |
|
|
505
|
+
|
|
506
|
+
Options: `--dir <path>` reads from an explicit bundle directory (`list`/`show`/`check`);
|
|
507
|
+
`--out <path>` is the write target (`build`/`export`); `--force` overwrites an existing
|
|
508
|
+
target. `export` ships the rich curated bundle; `build` is the lighter runtime projection.
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
450
512
|
## Command Aliases
|
|
451
513
|
|
|
452
514
|
| Alias | Equivalent |
|
|
@@ -12,15 +12,47 @@ These settings apply to the CLI's curated resource registry. If you need a resou
|
|
|
12
12
|
|
|
13
13
|
## Credential Cascade
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The CLI first decides **which credential set** is the base, then lets environment credential variables field-override on top. The base is chosen by the first match in this order:
|
|
16
16
|
|
|
17
17
|
| Priority | Source | Location |
|
|
18
18
|
|----------|--------|----------|
|
|
19
|
-
| 1 (highest) |
|
|
20
|
-
| 2 |
|
|
21
|
-
| 3
|
|
19
|
+
| 1 (highest) | `--profile <name>` flag | named profile (per command) |
|
|
20
|
+
| 2 | `ZEYOS_PROFILE` env var | named profile |
|
|
21
|
+
| 3 | Project pin | `.zeyos/profile` (walks up from CWD) |
|
|
22
|
+
| 4 | Local config file | `.zeyos/auth.json` (walks up from CWD) |
|
|
23
|
+
| 5 | Global active profile | `~/.config/zeyos/profiles.json` (`active`) |
|
|
24
|
+
| 6 (lowest) | Global config file | `~/.config/zeyos/credentials.json` |
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
On top of the chosen base, the credential **environment variables** (`ZEYOS_BASE_URL`, `ZEYOS_TOKEN`, …) always override individual fields — so you can keep `baseUrl` and client credentials in a profile while overriding just the token via `ZEYOS_TOKEN` in CI.
|
|
27
|
+
|
|
28
|
+
If you have never created a profile, nothing changes: the CLI falls through to the legacy local `.zeyos/auth.json` and global `credentials.json` exactly as before.
|
|
29
|
+
|
|
30
|
+
## Profiles
|
|
31
|
+
|
|
32
|
+
Profiles let you store several ZeyOS instances (e.g. `dev`, `prod`, `client-x`) and switch between them without re-running `login`. Each profile is a full credential set (URL, OAuth app, tokens) kept in `~/.config/zeyos/profiles.json`, with one marked **active**.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Create profiles (connection params now; tokens via login)
|
|
36
|
+
zeyos profile add dev --base-url https://zeyos.cms-it.de/dev
|
|
37
|
+
zeyos profile add prod --base-url https://cloud.zeyos.com/acme --client-id app --secret "$SECRET"
|
|
38
|
+
|
|
39
|
+
# Authenticate into a profile (also makes it active)
|
|
40
|
+
zeyos login --profile prod
|
|
41
|
+
|
|
42
|
+
# See and switch profiles
|
|
43
|
+
zeyos profile list # active marked with *, shows token status
|
|
44
|
+
zeyos profile use dev # switch the global active profile
|
|
45
|
+
zeyos profile current # what resolves right now, and why
|
|
46
|
+
|
|
47
|
+
# Per-project: pin a profile so cd-ing into a repo selects its instance
|
|
48
|
+
cd ~/work/acme && zeyos profile use prod --local # writes ./.zeyos/profile
|
|
49
|
+
|
|
50
|
+
# One-off override on any command (beats env, pin, and active)
|
|
51
|
+
zeyos whoami --profile dev
|
|
52
|
+
zeyos list tickets --profile prod
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`zeyos profile add <name> --from-current` snapshots whatever credentials are in effect (including tokens) into a new profile — handy for adopting an existing `.zeyos/auth.json` setup. Add `.zeyos/profile` to `.gitignore` alongside `.zeyos/auth.json`.
|
|
24
56
|
|
|
25
57
|
## Environment Variables
|
|
26
58
|
|
|
@@ -107,6 +107,28 @@ Count matching records:
|
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
109
|
zeyos count tickets --filter '{"visibility":0,"status":4}' --json
|
|
110
|
+
zeyos count customfields --json
|
|
111
|
+
zeyos count actionsteps --filter '{"status":0}' --json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Summarize actionstep effort/time-entry evidence:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
zeyos list actionsteps \
|
|
118
|
+
--fields ID,name,status,date,duedate,effort,ticket,task,account \
|
|
119
|
+
--filter '{"status":3}' \
|
|
120
|
+
--limit 100 \
|
|
121
|
+
--json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Inspect ticket-linked mail without sending anything:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
zeyos list messages \
|
|
128
|
+
--fields ID,date,mailbox,subject,sender_email,to_email,ticket,reference,messageid \
|
|
129
|
+
--filter '{"ticket":42}' \
|
|
130
|
+
--sort +date \
|
|
131
|
+
--json
|
|
110
132
|
```
|
|
111
133
|
|
|
112
134
|
## Write Data
|
|
@@ -145,4 +167,6 @@ zeyos delete ticket 42 --force
|
|
|
145
167
|
- Include `visibility: 0` in filters for normal business views.
|
|
146
168
|
- Prefer `--data '<json>'` over many separate flags in automation.
|
|
147
169
|
- Run `zeyos resources` before assuming a resource is CLI-supported.
|
|
170
|
+
- Use `actionsteps.effort` for time-entry totals; do not infer booked time from task assignment.
|
|
171
|
+
- Draft e-mail text in the response unless the user explicitly asks for a real ZeyOS draft record; never send mail from an agent workflow.
|
|
148
172
|
- Escalate to [`@zeyos/client`](./03-cli-coverage-and-escalation.md) when the CLI resource registry is not enough.
|
|
@@ -13,10 +13,11 @@ The command `zeyos resources` is the source of truth for CLI-supported resource
|
|
|
13
13
|
|
|
14
14
|
| Resource | Operations |
|
|
15
15
|
|----------|------------|
|
|
16
|
-
| `account`, `appointment`, `campaign`, `contact`, `document`, `event`, `file`, `invitation`, `item`, `message`, `note`, `opportunity`, `payment`, `project`, `storage`, `task`, `ticket`, `transaction` | `list`, `get`, `create`, `update`, `delete` |
|
|
16
|
+
| `account`, `actionstep`, `appointment`, `campaign`, `contact`, `document`, `event`, `file`, `invitation`, `item`, `message`, `note`, `opportunity`, `payment`, `project`, `storage`, `task`, `ticket`, `transaction` | `list`, `get`, `create`, `update`, `delete` |
|
|
17
|
+
| `customfield` / `customfields` | `list`, `get` |
|
|
17
18
|
| `group`, `user` | `list`, `get` |
|
|
18
19
|
|
|
19
|
-
Plural names and common aliases such as `tickets`, `docs`, `invoice`, and `crm` are resolved by the CLI, but the underlying coverage boundary is still the registry above.
|
|
20
|
+
Plural names and common aliases such as `tickets`, `actionsteps`, `time-entries`, `docs`, `invoice`, and `crm` are resolved by the CLI, but the underlying coverage boundary is still the registry above.
|
|
20
21
|
|
|
21
22
|
## What the CLI Does Not Try to Cover
|
|
22
23
|
|