@anchrd/colab-sdk 0.0.0-stage → 0.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.
Files changed (94) hide show
  1. package/README.md +65 -2
  2. package/dist/actions/actions.d.ts +810 -0
  3. package/dist/actions/actions.js +177 -0
  4. package/dist/admin-mode.d.ts +2 -0
  5. package/dist/admin-mode.js +5 -0
  6. package/dist/apps/apps.d.ts +108 -0
  7. package/dist/apps/apps.js +73 -0
  8. package/dist/archive/archive.d.ts +25 -0
  9. package/dist/archive/archive.js +27 -0
  10. package/dist/auth/auth.d.ts +27 -0
  11. package/dist/auth/auth.js +22 -0
  12. package/dist/authorization/authorization.d.ts +36 -0
  13. package/dist/authorization/authorization.js +23 -0
  14. package/dist/boards/boards.d.ts +612 -0
  15. package/dist/boards/boards.js +289 -0
  16. package/dist/columns/columns.d.ts +28 -0
  17. package/dist/columns/columns.js +28 -0
  18. package/dist/connections/connections.d.ts +149 -0
  19. package/dist/connections/connections.js +74 -0
  20. package/dist/connectors/connectors.d.ts +148 -0
  21. package/dist/connectors/connectors.js +83 -0
  22. package/dist/dashboards/dashboards.d.ts +221 -0
  23. package/dist/dashboards/dashboards.js +520 -0
  24. package/dist/directory/directory.d.ts +20 -0
  25. package/dist/directory/directory.js +18 -0
  26. package/dist/documents/documents.d.ts +61 -0
  27. package/dist/documents/documents.js +58 -0
  28. package/dist/error/error.d.ts +34 -0
  29. package/dist/error/error.js +30 -0
  30. package/dist/events/events.d.ts +104 -0
  31. package/dist/events/events.js +69 -0
  32. package/dist/files/files.d.ts +60 -0
  33. package/dist/files/files.js +139 -0
  34. package/dist/functions/functions.d.ts +26 -0
  35. package/dist/functions/functions.js +28 -0
  36. package/dist/grammar/grammar.d.ts +62 -0
  37. package/dist/grammar/grammar.js +197 -0
  38. package/dist/grants/grants.d.ts +93 -0
  39. package/dist/grants/grants.js +66 -0
  40. package/dist/ids/ids.d.ts +5 -0
  41. package/dist/ids/ids.js +12 -0
  42. package/dist/instructions/instructions.d.ts +19 -0
  43. package/dist/instructions/instructions.js +35 -0
  44. package/dist/interfaces/interfaces.d.ts +41 -0
  45. package/dist/interfaces/interfaces.js +52 -0
  46. package/dist/invitations/invitations.d.ts +98 -0
  47. package/dist/invitations/invitations.js +58 -0
  48. package/dist/links/links.d.ts +76 -0
  49. package/dist/links/links.js +73 -0
  50. package/dist/list-input.d.ts +3 -0
  51. package/dist/list-input.js +11 -0
  52. package/dist/machines/machines.d.ts +69 -0
  53. package/dist/machines/machines.js +39 -0
  54. package/dist/messages/messages.d.ts +117 -0
  55. package/dist/messages/messages.js +77 -0
  56. package/dist/nodes/nodes.d.ts +673 -0
  57. package/dist/nodes/nodes.js +354 -0
  58. package/dist/operators/operators.d.ts +898 -0
  59. package/dist/operators/operators.js +398 -0
  60. package/dist/pages/pages.d.ts +89 -0
  61. package/dist/pages/pages.js +62 -0
  62. package/dist/primitives/primitives.d.ts +5 -0
  63. package/dist/primitives/primitives.js +19 -0
  64. package/dist/profile/profile.d.ts +37 -0
  65. package/dist/profile/profile.js +43 -0
  66. package/dist/roles/roles.d.ts +135 -0
  67. package/dist/roles/roles.js +87 -0
  68. package/dist/runs/runs.d.ts +244 -0
  69. package/dist/runs/runs.js +137 -0
  70. package/dist/runtime-config.d.ts +12 -0
  71. package/dist/runtime-config.js +18 -0
  72. package/dist/sdk.d.ts +45 -0
  73. package/dist/sdk.js +48 -0
  74. package/dist/secrets/secrets.d.ts +65 -0
  75. package/dist/secrets/secrets.js +57 -0
  76. package/dist/service-client/service-client.d.ts +35 -0
  77. package/dist/service-client/service-client.js +90 -0
  78. package/dist/services/services.d.ts +122 -0
  79. package/dist/services/services.js +89 -0
  80. package/dist/sso/sso.d.ts +70 -0
  81. package/dist/sso/sso.js +54 -0
  82. package/dist/tables/tables.d.ts +133 -0
  83. package/dist/tables/tables.js +131 -0
  84. package/dist/tool.d.ts +31 -0
  85. package/dist/tool.js +4 -0
  86. package/dist/user-settings/user-settings.d.ts +44 -0
  87. package/dist/user-settings/user-settings.js +44 -0
  88. package/dist/users/users.d.ts +254 -0
  89. package/dist/users/users.js +125 -0
  90. package/dist/validation/validation.d.ts +106 -0
  91. package/dist/validation/validation.js +41 -0
  92. package/dist/versions/versions.d.ts +100 -0
  93. package/dist/versions/versions.js +70 -0
  94. package/package.json +27 -4
@@ -0,0 +1,354 @@
1
+ import { z } from "zod";
2
+ import { ColumnType, TaskColumn } from "../columns/columns.js";
3
+ import { idSchema } from "../ids/ids.js";
4
+ import { Instructions } from "../instructions/instructions.js";
5
+ import { Flag, Limit as PageSize } from "../list-input.js";
6
+ import { IdempotencyKey, Rev } from "../primitives/primitives.js";
7
+ import { MessageMachine } from "../users/users.js";
8
+ // Nodes, folders and the three areas of the tree (#36): the inputs of `intelligence_node_list`,
9
+ // `_get`, `_update`, `_move`, `intelligence_folder_create` and `intelligence_user_list`, and the
10
+ // answers the UI draws. Every input field carries its description (trap C004): HTTP, MCP and the
11
+ // types read the same sentence, and `nodes.unit.ts` holds that none is missing.
12
+ export const NodeId = idSchema("node").describe("The node's id, `node_…`.");
13
+ // The password of a secret document or table (#357), the node's one sub-resource `secret`. Here and
14
+ // not in `secrets.ts`, because `NodeDetail` names it and `secrets.ts` imports from this file (C012).
15
+ export const SecretId = idSchema("secret").describe("The id of a secret node's password, `secret_…`, from intelligence_node_get (secretId).");
16
+ // What a secret document or table says about itself (#357, E94), in every answer that names it:
17
+ // `secret` only on a secret node, `locked` whether its content is withheld from this caller. Both are
18
+ // absent on every other node. Every AI and every machine reads a secret node locked.
19
+ const secretFlag = z
20
+ .literal(true)
21
+ .optional()
22
+ .describe("Only on a secret document or table: its content is encrypted and needs its password.");
23
+ const lockedFlag = z
24
+ .boolean()
25
+ .optional()
26
+ .describe("Only on a secret node: true when its content is withheld from you (no AI and no machine ever reads it; a person unlocks it in the browser).");
27
+ export const SecretFields = { secret: secretFlag, locked: lockedFlag };
28
+ // Every kind lives in the one table `nodes` (E55, E64). A task never stands in the tree (E67).
29
+ export const nodeKinds = [
30
+ "folder",
31
+ "document",
32
+ "table",
33
+ "board",
34
+ "task",
35
+ "dashboard",
36
+ "file",
37
+ ];
38
+ export const NodeKind = z.enum(nodeKinds);
39
+ // Only these kinds have a responsible person (E32): the one who answers for the content's validity.
40
+ export const responsibleKinds = [
41
+ "document",
42
+ "table",
43
+ "file",
44
+ ];
45
+ // A system part with a lock (E67): renaming, moving, archiving, deleting and sharing refuse. The one
46
+ // validation board (#47); the board Vorschläge in every root is gone (E88, #355). It lives here, not
47
+ // beside the boards, because the listing carries it too (#52) and `boards.ts` imports from this file.
48
+ export const BoardSystem = z.enum(["validation"]);
49
+ // What a board is as an answer shows it: besides the two a caller makes (`boardKinds` in
50
+ // `boards.ts`), the one validation board of a Colab (#47), which no caller makes or turns into. Here
51
+ // for the same reason as `BoardSystem`: the lists carry it too (#227).
52
+ export const BoardShownKind = z.enum(["board", "process", "validation"]);
53
+ // The three sections of the tree (Funktionen › Seitenbaum, E67).
54
+ export const NodeSection = z.enum(["own", "shared", "users"]);
55
+ export const NodeSort = z.enum(["name", "updated", "kind", "status"]);
56
+ const Limit = PageSize.describe("How many entries one page holds, 1 to 100. Leaving it out gives 50.");
57
+ // The name a person reads. ⚠️ A name starting with a dot hides the node from listings (`.Intern`),
58
+ // which is appearance only: rights, search and links still see it.
59
+ const NodeName = z
60
+ .string()
61
+ .max(200)
62
+ .describe("The name as people read it. A name that starts with a dot (`.Intern`) hides the node from listings until hidden ones are asked for; it is never a permission.");
63
+ // The words a search looks for (#48, E67): searching is `intelligence_node_list` with `query`.
64
+ export const NodeQuery = z
65
+ .string()
66
+ .trim()
67
+ .min(2)
68
+ .max(200)
69
+ .describe("Search instead of listing: words to find in titles, the text of documents, tables, files and tasks and the values of dashboards, at least two characters; each word also finds longer words it begins (preis finds Preisliste). Only what you can read, never archived nodes or chats. parentId narrows it to that folder and everything below it, section to own, shared or users; leaving both out searches own and shared together. The hits come in the order of their rank, grouped by folder; sort, foldersFirst and includeHidden do not apply.");
70
+ export const NodeListInput = z.strictObject({
71
+ parentId: NodeId.optional().describe("List the children of this folder. Give exactly one of parentId, section and nodeIds; with query at most one of parentId and section."),
72
+ section: NodeSection.optional().describe("List a section of the tree instead of a folder: own (what lies in your own root folder), shared (the tops of everything others let you reach) or users (every other person's root folder, only for an admin in admin mode)."),
73
+ query: NodeQuery.optional(),
74
+ includeHidden: Flag.optional().describe("Also list nodes whose name starts with a dot. Leaving it out hides them."),
75
+ sort: NodeSort.optional().describe("The order: name (default, A to Z), updated (most recently changed first), kind, or status (the type of the column the validation ticket stands in: backlog, open, progress, done, discarded, blocked, archive, then nodes without a ticket)."),
76
+ foldersFirst: Flag.optional().describe("Put folders before everything else, each group in the chosen order."),
77
+ cursor: z
78
+ .string()
79
+ .max(1000)
80
+ .optional()
81
+ .describe("The nextCursor of the previous page, unchanged. Leaving it out starts at the top."),
82
+ limit: Limit.optional(),
83
+ archived: Flag.optional().describe("List the archive instead: with section own or shared the archived entries there, each with its path and when it was archived; with parentId the archived nodes in that folder, also inside an archived one. Leaving it out lists what is not archived."),
84
+ // Over REST one comma-separated value (`?nodeIds=node_…,node_…`): a query string carries text.
85
+ nodeIds: z
86
+ .preprocess((value) => (typeof value === "string" ? value.split(",") : value), z.array(NodeId).min(1).max(100))
87
+ .optional()
88
+ .describe("Name these nodes, 1 to 100, for links and images in a text: the answer holds only those you can read, in the order given; one you cannot read or that does not exist is left out without a note."),
89
+ });
90
+ // A person behind a `user_…` id, as `access` names them. A deleted account has no name (null).
91
+ export const NodePerson = z.strictObject({
92
+ userId: z.string(),
93
+ name: z.string().nullable(),
94
+ kind: z.enum(["human", "machine"]).nullable(),
95
+ });
96
+ // The crumbs above a node, from the first level the caller can read, and the section they start in.
97
+ export const NodePath = z.strictObject({
98
+ section: NodeSection,
99
+ items: z.array(z.strictObject({ nodeId: NodeId, name: z.string() })),
100
+ });
101
+ export const NodeListItem = z.strictObject({
102
+ nodeId: NodeId,
103
+ kind: NodeKind,
104
+ name: z.string(),
105
+ hidden: z.boolean(),
106
+ // A root folder belongs to this person; null for every other node.
107
+ rootOf: z.string().nullable(),
108
+ // That person's picture as `access.directory.resolve` gives it (#123): null for every other node,
109
+ // for a machine and for a person without one.
110
+ rootImage: z.string().nullable(),
111
+ createdBy: NodePerson,
112
+ // Only for document, table and file (E32); null for every other kind.
113
+ responsible: NodePerson.nullable(),
114
+ // Bytes of the current version (#38), for the phone; null for a kind without versions and for a
115
+ // document, table or file that has none yet.
116
+ size: z.number().int().nullable(),
117
+ updatedAt: z.iso.datetime(),
118
+ // How many people hold a grant on it, inherited ones included.
119
+ sharedWith: z.number().int(),
120
+ // When it went into the archive; null for a node that is not archived.
121
+ archivedAt: z.iso.datetime().nullable(),
122
+ // The validation status (#47): the type of the column its ticket stands in; null for a kind that is
123
+ // not validated.
124
+ status: ColumnType.nullable(),
125
+ // A board that is a system part with a lock (#52: the tree draws the lock and no ⋯); null for
126
+ // every other node.
127
+ system: BoardSystem.nullable(),
128
+ // What a board is (#227): the tree, the folder and the archive draw a process and the validation
129
+ // board apart from a board; null for every other kind.
130
+ boardKind: BoardShownKind.nullable(),
131
+ // Only in the archive (`archived: true`): where it stood, as the caller can read it, for a folder
132
+ // how many archived nodes it holds directly, and for a board how many archived tasks (#135).
133
+ path: NodePath.optional(),
134
+ count: z.number().int().nullable().optional(),
135
+ // Only on a secret document or table (#357): the tree draws the lock.
136
+ secret: secretFlag,
137
+ // Only in section users (E97, #447): the root of an archived account, listed only while it still
138
+ // holds something, after all others.
139
+ rootArchived: z
140
+ .literal(true)
141
+ .optional()
142
+ .describe("Only in section users: the root folder of an archived account. It is listed only while something in it is not archived, after all others."),
143
+ });
144
+ export const NodeList = z.strictObject({
145
+ items: z.array(NodeListItem),
146
+ nextCursor: z.string().nullable(),
147
+ // Only with section own and not archived (#52): the caller's root folder, the parent of what is
148
+ // listed and the folder something new in Own is created in.
149
+ rootId: NodeId.optional(),
150
+ // Over MCP only, with parentId: the INSTRUCTIONS of that folder (#39).
151
+ instructions: Instructions.optional(),
152
+ });
153
+ // Where a hit was found (#386), told before its passage: in its name (`title`), its text (`text`),
154
+ // a column of a table (`column`, `label` the column's name), a page of a file (`page`, `label` the
155
+ // page's number as text) or, for a task found by its name, the card on a board (`card`, `label` the
156
+ // board's name where the caller reads it). `label` is null where there is nothing to name.
157
+ export const NodeHitFoundIn = z.strictObject({
158
+ kind: z.enum(["title", "text", "column", "page", "card"]),
159
+ label: z.string().nullable(),
160
+ });
161
+ // A hit of a search (#48): the node, where it stands for the caller, the passage that matched and its
162
+ // place in the fused order.
163
+ export const NodeHit = z.strictObject({
164
+ nodeId: NodeId,
165
+ kind: NodeKind,
166
+ name: z.string(),
167
+ // The crumbs above it, from the first level the caller can read, like `path` of the archive.
168
+ path: NodePath,
169
+ // ⚠️ Plain text: the matched words stand between <mark> and </mark>, and nothing else in it is
170
+ // markup. The UI splits on the two marks and never renders it as HTML (the text is a person's).
171
+ snippet: z.string(),
172
+ foundIn: NodeHitFoundIn,
173
+ // 1 is the best hit; counted over the whole answer, not per page.
174
+ rank: z.number().int().min(1),
175
+ // The validation status like `NodeListItem.status` (#236): the type of the column its ticket stands
176
+ // in; null for a kind that is not validated.
177
+ status: ColumnType.nullable(),
178
+ // The last change, beside the status on the hit (#236).
179
+ updatedAt: z.iso.datetime(),
180
+ // What a board is, like `NodeListItem.boardKind` (#227); null for every other kind.
181
+ boardKind: BoardShownKind.nullable(),
182
+ // Only on a secret document or table (#429): the hit draws the lock. Its content is never searched.
183
+ secret: secretFlag,
184
+ });
185
+ // The hits of one folder ("Vertrieb · 7 Treffer"): the folder the hits stand in, null where the
186
+ // caller cannot read it or a hit stands on the top level of Shared, and its crumbs.
187
+ export const NodeHitGroup = z.strictObject({
188
+ parentId: NodeId.nullable(),
189
+ path: NodePath,
190
+ count: z.number().int().min(1),
191
+ });
192
+ export const NodeSearch = z.strictObject({
193
+ items: z.array(NodeHit),
194
+ // Every folder with hits, over the whole answer, in the order of each folder's best hit.
195
+ groups: z.array(NodeHitGroup),
196
+ nextCursor: z.string().nullable(),
197
+ // unavailable: the semantic half did not answer, and the hits are the lexical half alone (E68).
198
+ semantic: z.enum(["ok", "unavailable"]),
199
+ });
200
+ // The search index for the page System (#48, #68): the last rebuild and whether one is running.
201
+ // Answered by `GET /api/intelligence/index`, a door without a tool (E67, E69).
202
+ export const SearchIndexState = z.strictObject({
203
+ running: z.boolean(),
204
+ last: z
205
+ .strictObject({
206
+ requestedBy: z.string(),
207
+ requestedAt: z.iso.datetime(),
208
+ startedAt: z.iso.datetime().nullable(),
209
+ completedAt: z.iso.datetime().nullable(),
210
+ })
211
+ .nullable(),
212
+ });
213
+ export const NodeGetInput = z.strictObject({ nodeId: NodeId });
214
+ // A document's, table's or file's validation (#47, Seiten › Validierung): where its ticket stands.
215
+ export const NodeValidation = z.strictObject({
216
+ ticketId: NodeId,
217
+ // The ticket's column; its type is the node's status.
218
+ column: TaskColumn,
219
+ // The end of the ticket's period, set by the Operator ("gültig bis"); null without one.
220
+ validUntil: z.iso.datetime().nullable(),
221
+ // Who is asked when the validity is to be decided: the node's responsible person.
222
+ responsible: NodePerson,
223
+ // What holds for exactly this node, the ticket's Markdown; empty without a word.
224
+ content: z.string(),
225
+ });
226
+ export const NodeDetail = z.strictObject({
227
+ nodeId: NodeId,
228
+ kind: NodeKind,
229
+ name: z.string(),
230
+ hidden: z.boolean(),
231
+ rootOf: z.string().nullable(),
232
+ // A board that is a system part with a lock (#52): its page shows no ⋯; null for every other node.
233
+ system: BoardSystem.nullable(),
234
+ // What a board is, like `NodeListItem.boardKind` (#227): the recently opened nodes of the search
235
+ // are these; null for every other kind.
236
+ boardKind: BoardShownKind.nullable(),
237
+ // Null at the top level of Shared, and where the caller cannot read the parent.
238
+ parentId: NodeId.nullable(),
239
+ path: NodePath,
240
+ createdBy: NodePerson,
241
+ responsible: NodePerson.nullable(),
242
+ // What the caller may do here; reading is implied by the answer itself.
243
+ rights: z.strictObject({ write: z.boolean(), share: z.boolean() }),
244
+ // Only for a folder: how many hidden nodes it holds ("Versteckte anzeigen").
245
+ hiddenCount: z.number().int().nullable(),
246
+ // Bytes of the current version, as in the listing (#38).
247
+ size: z.number().int().nullable(),
248
+ rev: z.number().int(),
249
+ // When it went into the archive; null for a node that is not archived.
250
+ archivedAt: z.iso.datetime().nullable(),
251
+ // Only for an archived node: per table, the rows deleting it for good would take along.
252
+ purge: z.record(z.string(), z.number().int()).nullable(),
253
+ createdAt: z.iso.datetime(),
254
+ updatedAt: z.iso.datetime(),
255
+ // Only for a document, table or file with a ticket (#47); null for every other node.
256
+ validation: NodeValidation.nullable(),
257
+ // Over MCP only: the INSTRUCTIONS of the node's folder, the node itself for a folder (#39).
258
+ instructions: Instructions.optional(),
259
+ // Over MCP only, for a board, a task and a dashboard (E87, #354): the board's or dashboard's own
260
+ // instruction, a task's board's (its run's copy for a run's task); null without one.
261
+ instruction: z.string().nullable().optional(),
262
+ // Only on a secret document or table (#357, E94): the password's id (for its settings), whether
263
+ // its content is withheld from this caller, and until when this browser session holds it unlocked
264
+ // (null when it does not; an admin in admin mode reads it without).
265
+ ...SecretFields,
266
+ secretId: SecretId.optional(),
267
+ // Who made it secret (they and an admin change its password and make it public again) and when its
268
+ // password was last set (#429); never the password.
269
+ secretBy: NodePerson.optional(),
270
+ secretSetAt: z.iso.datetime().optional(),
271
+ unlockedUntil: z.iso.datetime().nullable().optional(),
272
+ });
273
+ export const NodeUpdateInput = z.strictObject({
274
+ nodeId: NodeId,
275
+ rev: Rev,
276
+ name: NodeName.optional(),
277
+ responsibleId: idSchema("user")
278
+ .optional()
279
+ .describe("Make this person responsible for the content's validity. Only for documents, tables and files, and only someone who can read the node."),
280
+ });
281
+ export const NodeMoveInput = z.strictObject({
282
+ nodeId: NodeId,
283
+ // ⚠️ Required and nullable (trap C015): null is the top level of Shared, and leaving the field out
284
+ // is refused, so a forgetful caller cannot move a node to the top by accident.
285
+ parentId: NodeId.nullable().describe("The folder to move the node into, one you can write to; null puts it on the top level of Shared. The node takes the grants of its new folder and loses those of the old one."),
286
+ });
287
+ // Who reaches a node after inheritance (`readersOf`), and where it comes from.
288
+ export const NodeReader = z.strictObject({
289
+ userId: z.string(),
290
+ name: z.string().nullable(),
291
+ kind: z.enum(["human", "machine"]).nullable(),
292
+ right: z.enum(["read", "write", "share"]),
293
+ // creator: made this node; direct: a grant on this node; inherited: from the folder `fromNodeId`,
294
+ // by a grant on it or by having made it.
295
+ origin: z.enum(["creator", "direct", "inherited"]),
296
+ fromNodeId: NodeId,
297
+ });
298
+ export const NodeMoved = z.strictObject({
299
+ nodeId: NodeId,
300
+ parentId: NodeId.nullable(),
301
+ // Who can read the node now, for the short note the UI shows after the drop.
302
+ readers: z.array(NodeReader),
303
+ });
304
+ export const FolderCreateInput = z.strictObject({
305
+ // ⚠️ Required and nullable (trap C015): null is the top level of Shared.
306
+ parentId: NodeId.nullable().describe("The folder to create it in, one you can write to; null creates it on the top level of Shared, visible to you until you share it."),
307
+ name: NodeName,
308
+ idempotencyKey: IdempotencyKey,
309
+ });
310
+ export const FolderCreated = z.strictObject({
311
+ nodeId: NodeId,
312
+ kind: z.literal("folder"),
313
+ name: z.string(),
314
+ hidden: z.boolean(),
315
+ parentId: NodeId.nullable(),
316
+ rev: z.number().int(),
317
+ createdAt: z.iso.datetime(),
318
+ updatedAt: z.iso.datetime(),
319
+ });
320
+ // ⚠️ Not `UserListInput`, the name `toolSchemaName` derives: that one is `access_user_list`'s, and
321
+ // the derivation drops the package. The package word goes in front where two packages share a
322
+ // resource and an action.
323
+ export const IntelligenceUserListInput = z.strictObject({
324
+ query: z
325
+ .string()
326
+ .trim()
327
+ .min(2)
328
+ .max(200)
329
+ .optional()
330
+ .describe("Part of a name or an address, at least two characters. Leaving it out with a nodeId lists the first people who can read that node."),
331
+ nodeId: NodeId.optional().describe("Say for each person whether they can read this node (canRead), for the @ menu and the share dialog."),
332
+ readersOnly: Flag.optional().describe("With nodeId: only the people who can read the node, the only ones a mention or an assignment may name."),
333
+ cursor: z
334
+ .string()
335
+ .max(1000)
336
+ .optional()
337
+ .describe("The nextCursor of the previous page, unchanged. Leaving it out starts at the top."),
338
+ limit: Limit.optional(),
339
+ });
340
+ export const IntelligenceUser = z.strictObject({
341
+ userId: z.string(),
342
+ kind: z.enum(["human", "machine"]),
343
+ name: z.string(),
344
+ email: z.string(),
345
+ image: z.string().nullable(),
346
+ // A machine's kind, and an Operator's provider ("Validierung · Claude", #403); null for a person.
347
+ machine: MessageMachine.nullable(),
348
+ // Only with nodeId.
349
+ canRead: z.boolean().optional(),
350
+ });
351
+ export const IntelligenceUserList = z.strictObject({
352
+ items: z.array(IntelligenceUser),
353
+ nextCursor: z.string().nullable(),
354
+ });