@anchrd/colab-sdk 0.1.10 → 0.1.12

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.
@@ -1,10 +1,13 @@
1
1
  import { z } from "zod";
2
+ import { CardKind, CardKindsInput, TaskFields, TaskFieldsInput, TaskKind, TaskKindInput, } from "../card-kinds/card-kinds.js";
2
3
  import { ColumnId, ColumnType, TaskColumn } from "../columns/columns.js";
3
- import { Schedule } from "../dashboards/dashboards.js";
4
4
  import { idSchema } from "../ids/ids.js";
5
+ import { Flag } from "../list-input.js";
5
6
  import { BoardShownKind, BoardSystem, NodeId, NodePerson } from "../nodes/nodes.js";
6
7
  import { IdempotencyKey, Rev } from "../primitives/primitives.js";
7
- import { TicketMove, TicketSubject, TicketSubjectRef } from "../validation/validation.js";
8
+ import { Schedule } from "../schedule/schedule.js";
9
+ import { TicketSubject, TicketSubjectRef } from "../validation/validation.js";
10
+ import { TaskMove } from "../versions/versions.js";
8
11
  // Boards, their columns and labels, and tasks (#42, Nodes › Board, Nodes › Aufgabe, E38, E40, E41,
9
12
  // E43, E44, E67, E70): the inputs of `intelligence_board_create`, `_get`, `_update`,
10
13
  // `intelligence_board_task_list`, `_create`, `intelligence_task_get`, `_update`, and the answers. A
@@ -28,6 +31,8 @@ export const BoardKind = z
28
31
  .enum(boardKinds)
29
32
  .describe("board: a board people work on. process: a template whose runs the Operator works through, each a copy of its columns and tasks; it needs a machine (an Operator) with write on it, a first column of type backlog, and every task of the template in that first column.");
30
33
  const Name = z.string().max(200);
34
+ // A column's description (#624), Markdown for every AI working on the board.
35
+ const ColumnDescription = z.string().max(20_000);
31
36
  const ColumnInput = z.strictObject({
32
37
  columnId: ColumnId.optional().describe("The column to keep, as intelligence_board_get returned it. Leaving it out makes a new column."),
33
38
  name: Name.describe("The column's name as people read it."),
@@ -36,6 +41,7 @@ const ColumnInput = z.strictObject({
36
41
  .boolean()
37
42
  .optional()
38
43
  .describe("Whether the board shows the column. Leaving it out shows it, except the archive column, which is hidden by default."),
44
+ description: ColumnDescription.optional().describe("What holds for a card in this column and what an AI does or leaves there, Markdown. Every AI working on the board gets it with each read. An empty text removes it; leaving it out keeps it (a new column has none)."),
39
45
  });
40
46
  const Columns = z
41
47
  .array(ColumnInput)
@@ -50,15 +56,16 @@ export const BoardCreateInput = z.strictObject({
50
56
  idempotencyKey: IdempotencyKey,
51
57
  });
52
58
  export const BoardGetInput = z.strictObject({ boardId: BoardId });
53
- // The instruction of a board or a dashboard (E87, #354), Markdown for every AI working on it.
59
+ // The instruction of a board (E87, #354), Markdown for every AI working on it.
54
60
  const BoardInstruction = z.string().max(200_000);
55
61
  export const BoardUpdateInput = z.strictObject({
56
62
  boardId: BoardId,
57
63
  rev: Rev,
58
64
  kind: BoardKind.optional().describe("Make the board a process or a board again. Saving a process is refused with conflict while no machine can write on the board, the first column is not of type backlog, or a task of the template stands outside the first column."),
59
- schedule: Schedule.optional().describe("When a run of the process or of the validation falls due (Ausführung), as on a dashboard. Leaving it out keeps it; a board made a process without one runs by hand."),
65
+ schedule: Schedule.optional().describe("When a run of the process or of the validation falls due (Ausführung). Leaving it out keeps it; a board made a process without one runs by hand."),
60
66
  instruction: BoardInstruction.optional().describe("The board's instruction, Markdown: what the board is about and how every AI working on it goes about it. It comes along with every read of the board and its tasks over MCP. On the validation board only an admin in admin mode changes it. An empty text removes it; leaving it out keeps it."),
61
67
  columns: Columns.optional(),
68
+ cardKinds: CardKindsInput.optional(),
62
69
  labels: z
63
70
  .array(z.strictObject({
64
71
  labelId: LabelId.optional().describe("The label to keep or rename. Leaving it out makes a new label."),
@@ -73,6 +80,8 @@ export const BoardColumn = z.object({
73
80
  name: z.string(),
74
81
  type: ColumnType,
75
82
  visible: z.boolean(),
83
+ // Markdown, empty without one (#624).
84
+ description: z.string(),
76
85
  });
77
86
  export const BoardLabel = z.object({ labelId: LabelId, name: z.string() });
78
87
  // What stands between a board and saving it as a process (#43): the UI shows a box for each, and the
@@ -108,6 +117,8 @@ export const BoardDetail = z.object({
108
117
  // for every reader of the validation board; null without one and for every other board.
109
118
  validator: NodePerson.nullable(),
110
119
  columns: z.array(BoardColumn),
120
+ // The card kinds with their fields in order (#638, E115); empty on a board of free cards.
121
+ cardKinds: z.array(CardKind),
111
122
  labels: z.array(BoardLabel),
112
123
  rights: z.object({ write: z.boolean() }),
113
124
  rev: z.number().int(),
@@ -119,7 +130,9 @@ const TaskLimit = z.coerce
119
130
  .int()
120
131
  .min(1)
121
132
  .max(500)
122
- .describe("How many tasks one page holds, 1 to 500. Leaving it out gives 200.");
133
+ .describe("How many tasks one page holds, 1 to 500. Leaving it out gives 200. With content at most 100, and leaving it out gives 100.");
134
+ // The most tasks one call reads by id, creates or changes (#625, E114).
135
+ export const maxBulkTasks = 100;
123
136
  export const BoardTaskListInput = z.strictObject({
124
137
  boardId: BoardId,
125
138
  runId: RunRef.optional().describe("The run of this process whose tasks and columns to list. Leaving it out lists the template, the board itself."),
@@ -128,6 +141,12 @@ export const BoardTaskListInput = z.strictObject({
128
141
  assigneeId: idSchema("user").optional().describe("Only the tasks assigned to this person."),
129
142
  labelId: LabelId.optional().describe("Only the tasks carrying this label."),
130
143
  parentTaskId: TaskId.optional().describe("Only the direct subtasks of this task."),
144
+ // Over REST one comma-separated value (`?taskIds=node_…,node_…`): a query string carries text.
145
+ taskIds: z
146
+ .preprocess((value) => (typeof value === "string" ? value.split(",") : value), z.array(TaskId).min(1).max(maxBulkTasks))
147
+ .optional()
148
+ .describe("Only these tasks of the board (of the run, with runId), 1 to 100, also from the archive column: one you cannot read or that is not there is left out without a note."),
149
+ content: Flag.optional().describe("true: every task also carries its Markdown text as content, beside its rev, so you check a whole board without reading task by task. A page then holds at most 100 tasks."),
131
150
  cursor: z
132
151
  .string()
133
152
  .max(1000)
@@ -157,9 +176,8 @@ const Position = z
157
176
  .max(100)
158
177
  .describe("The place in the column: a fractional-indexing key between the positions of the neighbours, as intelligence_board_task_list returns them. Leaving it out puts the task at the end of its column.");
159
178
  const Assignee = idSchema("user").describe("The one person responsible for the task, someone who can read the board. Leaving it out on create makes it you, on a process the first machine that can write on it.");
160
- export const BoardTaskCreateInput = z.strictObject({
161
- boardId: BoardId,
162
- runId: RunRef.optional().describe("Create the task in this running run of the process, in one of the run's columns. Leaving it out creates it in the template. A completed run takes no task."),
179
+ // The fields of one new task, alone or as an entry of `tasks` (#625).
180
+ const newTask = {
163
181
  title: Title,
164
182
  content: Content.optional(),
165
183
  columnId: ColumnId.optional().describe("The column to put the task in. Leaving it out puts it in the board's first column."),
@@ -170,8 +188,42 @@ export const BoardTaskCreateInput = z.strictObject({
170
188
  parentTaskId: TaskId.optional().describe("Make it a subtask of this task of the same board; it is still a card of its own."),
171
189
  dependsOn: DependsOn.optional(),
172
190
  position: Position.optional(),
191
+ kind: TaskKindInput.optional(),
192
+ fields: TaskFieldsInput.optional(),
193
+ };
194
+ const Ref = z
195
+ .string()
196
+ .min(1)
197
+ .max(100)
198
+ .describe("Your own name for this task within the call, unique in it: parentRef and dependsOnRefs of other entries point to it, and the answer names its taskId under it.");
199
+ // One entry of `tasks`: a task like the single create, plus a ref other entries point to.
200
+ const NewTaskEntry = z.strictObject({
201
+ ref: Ref,
202
+ ...newTask,
203
+ parentRef: Ref.optional().describe("Make it a subtask of the entry of this call with this ref. Not together with parentTaskId."),
204
+ dependsOnRefs: z
205
+ .array(Ref)
206
+ .max(maxBulkTasks)
207
+ .optional()
208
+ .describe("The entries of this call this task waits for, by their ref; beside dependsOn."),
209
+ });
210
+ export const BoardTaskCreateInput = z.strictObject({
211
+ boardId: BoardId,
212
+ runId: RunRef.optional().describe("Create the task in this running run of the process, in one of the run's columns. Leaving it out creates it in the template. A completed run takes no task."),
213
+ ...newTask,
214
+ title: Title.optional().describe("The task's title, for one task. To create several, leave it out and send tasks."),
215
+ tasks: z
216
+ .array(NewTaskEntry)
217
+ .min(1)
218
+ .max(maxBulkTasks)
219
+ .optional()
220
+ .describe("Several tasks at once, 1 to 100, instead of the fields of one: a whole structure of tasks, subtasks and waits in one call. All or nothing: if one entry is invalid, none is created and issues names every entry that is. The answer names taskId and rev under each ref. idempotencyKey covers the whole call."),
173
221
  idempotencyKey: IdempotencyKey,
174
222
  });
223
+ // The answer to `intelligence_board_task_create` with `tasks` (#625): each entry under its ref.
224
+ export const BoardTaskCreated = z.object({
225
+ tasks: z.array(z.object({ ref: z.string(), taskId: NodeId, rev: z.number().int() })),
226
+ });
175
227
  export const TaskGetInput = z.strictObject({ taskId: TaskId });
176
228
  export const TaskUpdateInput = z.strictObject({
177
229
  taskId: TaskId,
@@ -192,6 +244,8 @@ export const TaskUpdateInput = z.strictObject({
192
244
  .describe("Hang the task under this task of the same board; null makes it a task of its own again."),
193
245
  dependsOn: DependsOn.optional(),
194
246
  position: Position.optional(),
247
+ kind: TaskKindInput.optional().describe("Only to confirm: a card never changes its kind, so any other kind than its own is invalid."),
248
+ fields: TaskFieldsInput.optional(),
195
249
  waiting: z
196
250
  .boolean()
197
251
  .optional()
@@ -200,7 +254,28 @@ export const TaskUpdateInput = z.strictObject({
200
254
  .string()
201
255
  .max(10_000)
202
256
  .optional()
203
- .describe("Only on a ticket of the validation board, together with columnId: why it moves, kept in the ticket's history. Elsewhere it is invalid."),
257
+ .describe("Only together with columnId: why the task moves. Kept in the version the move makes; without a move it is invalid."),
258
+ editSession: z
259
+ .string()
260
+ .min(1)
261
+ .max(100)
262
+ .optional()
263
+ .describe("The editing session the browser keeps while a person stays on the task: its saves go into one version, a move always into its own. Leaving it out makes every change a version of its own, which is right for an AI."),
264
+ });
265
+ // Many tasks of one board or run changed in one call (#625, E114): only by id, each with its rev,
266
+ // all or nothing.
267
+ export const BoardTaskUpdateInput = z.strictObject({
268
+ boardId: BoardId,
269
+ runId: RunRef.optional().describe("The running run of the process whose tasks these are. Leaving it out changes tasks of the template, the board itself."),
270
+ tasks: z
271
+ .array(TaskUpdateInput)
272
+ .min(1)
273
+ .max(maxBulkTasks)
274
+ .describe("The tasks to change, 1 to 100, each once, with taskId, the rev you read and the fields of intelligence_task_update. All or nothing: if one is invalid or someone saved one in between, nothing changes and issues names every entry concerned."),
275
+ });
276
+ // The answer: each task with the rev its next change sends, in the order given.
277
+ export const BoardTaskUpdated = z.object({
278
+ tasks: z.array(z.object({ taskId: NodeId, rev: z.number().int() })),
204
279
  });
205
280
  // An image linked in a task's content: an outside URL, or a file in Colab the caller can read.
206
281
  export const TaskImage = z.union([
@@ -223,6 +298,10 @@ export const BoardTaskItem = z.object({
223
298
  // Everything it waits for is in a column of type done or discarded (true without any).
224
299
  ready: z.boolean(),
225
300
  images: z.array(TaskImage),
301
+ // The card's kind and the values of its fields by name (#638, E115); null and {} on a board
302
+ // without kinds.
303
+ kind: TaskKind.nullable(),
304
+ fields: TaskFields,
226
305
  // A ticket of the validation board (#47): the node it validates; null for every other task.
227
306
  subject: TicketSubjectRef.nullable(),
228
307
  // Whether the caller may change this task, as intelligence_task_update decides it: the board's
@@ -232,6 +311,8 @@ export const BoardTaskItem = z.object({
232
311
  position: z.string(),
233
312
  rev: z.number().int(),
234
313
  updatedAt: z.iso.datetime(),
314
+ // Only with `content: true` (#625): the task's Markdown text.
315
+ content: z.string().optional(),
235
316
  });
236
317
  export const BoardTaskList = z.object({
237
318
  items: z.array(BoardTaskItem),
@@ -239,8 +320,17 @@ export const BoardTaskList = z.object({
239
320
  // Over MCP only (E87, #354): the board's instruction, a run's copy of it with `runId`; null
240
321
  // without one.
241
322
  instruction: z.string().nullable().optional(),
323
+ // Over MCP only (#624): every column of the board (of the run, with `runId`) in order, with its
324
+ // description, once per page.
325
+ columns: z.array(BoardColumn).optional(),
326
+ });
327
+ // A subtask or a task waited for; `kind` its card kind (#638), null without one.
328
+ const TaskRef = z.object({
329
+ taskId: NodeId,
330
+ title: z.string(),
331
+ column: TaskColumn,
332
+ kind: TaskKind.nullable(),
242
333
  });
243
- const TaskRef = z.object({ taskId: NodeId, title: z.string(), column: TaskColumn });
244
334
  export const TaskDetail = z.object({
245
335
  taskId: NodeId,
246
336
  boardId: NodeId,
@@ -270,14 +360,19 @@ export const TaskDetail = z.object({
270
360
  dependencies: z.array(TaskRef),
271
361
  ready: z.boolean(),
272
362
  images: z.array(TaskImage),
363
+ // The card's kind and the values of its fields by name (#638, E115); null and {} on a board
364
+ // without kinds.
365
+ kind: TaskKind.nullable(),
366
+ fields: TaskFields,
273
367
  rights: z.object({ write: z.boolean() }),
274
368
  // The task waits (#377, E77): its assignee lacks something, a right above all, and asked in the
275
369
  // chat. Shown in place of the column; null while it does not wait.
276
370
  waiting: z.object({ since: z.iso.datetime(), by: NodePerson }).nullable(),
277
- // A ticket of the validation board (#47): the node it validates with its path, and every move,
278
- // newest first. Both null for every other task.
371
+ // A ticket of the validation board (#47): the node it validates with its path, and its last move
372
+ // from its versions (E117), null before its first. Both null for every other task; the history of
373
+ // every task stands in intelligence_node_version_list.
279
374
  subject: TicketSubject.nullable(),
280
- history: z.array(TicketMove).nullable(),
375
+ lastMove: TaskMove.nullable(),
281
376
  createdBy: NodePerson,
282
377
  rev: z.number().int(),
283
378
  archivedAt: z.iso.datetime().nullable(),
@@ -286,4 +381,7 @@ export const TaskDetail = z.object({
286
381
  // Over MCP only (E87, #354): the instruction of the task's board, of its run for a run's task;
287
382
  // null without one.
288
383
  instruction: z.string().nullable().optional(),
384
+ // Over MCP only (#624): every column of the task's board (of its run for a run's task) in order,
385
+ // with its description; `current` marks the task's own.
386
+ columns: z.array(BoardColumn.extend({ current: z.boolean() })).optional(),
289
387
  });
@@ -0,0 +1,265 @@
1
+ import { z } from "zod";
2
+ export declare const CardKindId: z.ZodTemplateLiteral<`kind_${string}`>;
3
+ export type CardKindId = z.infer<typeof CardKindId>;
4
+ export declare const CardFieldId: z.ZodTemplateLiteral<`field_${string}`>;
5
+ export type CardFieldId = z.infer<typeof CardFieldId>;
6
+ export declare const CardOptionId: z.ZodTemplateLiteral<`option_${string}`>;
7
+ export type CardOptionId = z.infer<typeof CardOptionId>;
8
+ export declare const cardFieldTypes: readonly ["text", "list", "checklist", "number", "date", "link", "select"];
9
+ export declare const CardFieldType: z.ZodEnum<{
10
+ number: "number";
11
+ date: "date";
12
+ list: "list";
13
+ link: "link";
14
+ text: "text";
15
+ checklist: "checklist";
16
+ select: "select";
17
+ }>;
18
+ export type CardFieldType = z.infer<typeof CardFieldType>;
19
+ export declare const cardKindIcons: readonly ["flag", "route", "arrow-right", "square-check", "file-text", "bulb", "target", "search", "user", "calendar", "star", "bolt", "bug", "message", "package", "rocket"];
20
+ export declare const CardKindIcon: z.ZodEnum<{
21
+ message: "message";
22
+ user: "user";
23
+ package: "package";
24
+ search: "search";
25
+ flag: "flag";
26
+ route: "route";
27
+ "arrow-right": "arrow-right";
28
+ "square-check": "square-check";
29
+ "file-text": "file-text";
30
+ bulb: "bulb";
31
+ target: "target";
32
+ calendar: "calendar";
33
+ star: "star";
34
+ bolt: "bolt";
35
+ bug: "bug";
36
+ rocket: "rocket";
37
+ }>;
38
+ export type CardKindIcon = z.infer<typeof CardKindIcon>;
39
+ export declare const CardFieldOptionInput: z.ZodObject<{
40
+ optionId: z.ZodOptional<z.ZodTemplateLiteral<`option_${string}`>>;
41
+ name: z.ZodString;
42
+ }, z.core.$strict>;
43
+ export declare const CardFieldInput: z.ZodObject<{
44
+ fieldId: z.ZodOptional<z.ZodTemplateLiteral<`field_${string}`>>;
45
+ name: z.ZodString;
46
+ type: z.ZodEnum<{
47
+ number: "number";
48
+ date: "date";
49
+ list: "list";
50
+ link: "link";
51
+ text: "text";
52
+ checklist: "checklist";
53
+ select: "select";
54
+ }>;
55
+ description: z.ZodOptional<z.ZodString>;
56
+ required: z.ZodOptional<z.ZodBoolean>;
57
+ visible: z.ZodOptional<z.ZodBoolean>;
58
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
59
+ optionId: z.ZodOptional<z.ZodTemplateLiteral<`option_${string}`>>;
60
+ name: z.ZodString;
61
+ }, z.core.$strict>>>;
62
+ }, z.core.$strict>;
63
+ export type CardFieldInput = z.infer<typeof CardFieldInput>;
64
+ export declare const CardKindInput: z.ZodObject<{
65
+ kindId: z.ZodOptional<z.ZodTemplateLiteral<`kind_${string}`>>;
66
+ name: z.ZodString;
67
+ icon: z.ZodOptional<z.ZodEnum<{
68
+ message: "message";
69
+ user: "user";
70
+ package: "package";
71
+ search: "search";
72
+ flag: "flag";
73
+ route: "route";
74
+ "arrow-right": "arrow-right";
75
+ "square-check": "square-check";
76
+ "file-text": "file-text";
77
+ bulb: "bulb";
78
+ target: "target";
79
+ calendar: "calendar";
80
+ star: "star";
81
+ bolt: "bolt";
82
+ bug: "bug";
83
+ rocket: "rocket";
84
+ }>>;
85
+ description: z.ZodOptional<z.ZodString>;
86
+ standard: z.ZodOptional<z.ZodBoolean>;
87
+ fields: z.ZodArray<z.ZodObject<{
88
+ fieldId: z.ZodOptional<z.ZodTemplateLiteral<`field_${string}`>>;
89
+ name: z.ZodString;
90
+ type: z.ZodEnum<{
91
+ number: "number";
92
+ date: "date";
93
+ list: "list";
94
+ link: "link";
95
+ text: "text";
96
+ checklist: "checklist";
97
+ select: "select";
98
+ }>;
99
+ description: z.ZodOptional<z.ZodString>;
100
+ required: z.ZodOptional<z.ZodBoolean>;
101
+ visible: z.ZodOptional<z.ZodBoolean>;
102
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
103
+ optionId: z.ZodOptional<z.ZodTemplateLiteral<`option_${string}`>>;
104
+ name: z.ZodString;
105
+ }, z.core.$strict>>>;
106
+ }, z.core.$strict>>;
107
+ }, z.core.$strict>;
108
+ export type CardKindInput = z.infer<typeof CardKindInput>;
109
+ export declare const CardKindsInput: z.ZodArray<z.ZodObject<{
110
+ kindId: z.ZodOptional<z.ZodTemplateLiteral<`kind_${string}`>>;
111
+ name: z.ZodString;
112
+ icon: z.ZodOptional<z.ZodEnum<{
113
+ message: "message";
114
+ user: "user";
115
+ package: "package";
116
+ search: "search";
117
+ flag: "flag";
118
+ route: "route";
119
+ "arrow-right": "arrow-right";
120
+ "square-check": "square-check";
121
+ "file-text": "file-text";
122
+ bulb: "bulb";
123
+ target: "target";
124
+ calendar: "calendar";
125
+ star: "star";
126
+ bolt: "bolt";
127
+ bug: "bug";
128
+ rocket: "rocket";
129
+ }>>;
130
+ description: z.ZodOptional<z.ZodString>;
131
+ standard: z.ZodOptional<z.ZodBoolean>;
132
+ fields: z.ZodArray<z.ZodObject<{
133
+ fieldId: z.ZodOptional<z.ZodTemplateLiteral<`field_${string}`>>;
134
+ name: z.ZodString;
135
+ type: z.ZodEnum<{
136
+ number: "number";
137
+ date: "date";
138
+ list: "list";
139
+ link: "link";
140
+ text: "text";
141
+ checklist: "checklist";
142
+ select: "select";
143
+ }>;
144
+ description: z.ZodOptional<z.ZodString>;
145
+ required: z.ZodOptional<z.ZodBoolean>;
146
+ visible: z.ZodOptional<z.ZodBoolean>;
147
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
148
+ optionId: z.ZodOptional<z.ZodTemplateLiteral<`option_${string}`>>;
149
+ name: z.ZodString;
150
+ }, z.core.$strict>>>;
151
+ }, z.core.$strict>>;
152
+ }, z.core.$strict>>;
153
+ export declare const CardFieldOption: z.ZodObject<{
154
+ optionId: z.ZodTemplateLiteral<`option_${string}`>;
155
+ name: z.ZodString;
156
+ }, z.core.$strip>;
157
+ export type CardFieldOption = z.infer<typeof CardFieldOption>;
158
+ export declare const CardField: z.ZodObject<{
159
+ fieldId: z.ZodTemplateLiteral<`field_${string}`>;
160
+ name: z.ZodString;
161
+ type: z.ZodEnum<{
162
+ number: "number";
163
+ date: "date";
164
+ list: "list";
165
+ link: "link";
166
+ text: "text";
167
+ checklist: "checklist";
168
+ select: "select";
169
+ }>;
170
+ description: z.ZodString;
171
+ required: z.ZodBoolean;
172
+ visible: z.ZodBoolean;
173
+ options: z.ZodArray<z.ZodObject<{
174
+ optionId: z.ZodTemplateLiteral<`option_${string}`>;
175
+ name: z.ZodString;
176
+ }, z.core.$strip>>;
177
+ }, z.core.$strip>;
178
+ export type CardField = z.infer<typeof CardField>;
179
+ export declare const CardKind: z.ZodObject<{
180
+ kindId: z.ZodTemplateLiteral<`kind_${string}`>;
181
+ name: z.ZodString;
182
+ icon: z.ZodEnum<{
183
+ message: "message";
184
+ user: "user";
185
+ package: "package";
186
+ search: "search";
187
+ flag: "flag";
188
+ route: "route";
189
+ "arrow-right": "arrow-right";
190
+ "square-check": "square-check";
191
+ "file-text": "file-text";
192
+ bulb: "bulb";
193
+ target: "target";
194
+ calendar: "calendar";
195
+ star: "star";
196
+ bolt: "bolt";
197
+ bug: "bug";
198
+ rocket: "rocket";
199
+ }>;
200
+ description: z.ZodString;
201
+ standard: z.ZodBoolean;
202
+ fields: z.ZodArray<z.ZodObject<{
203
+ fieldId: z.ZodTemplateLiteral<`field_${string}`>;
204
+ name: z.ZodString;
205
+ type: z.ZodEnum<{
206
+ number: "number";
207
+ date: "date";
208
+ list: "list";
209
+ link: "link";
210
+ text: "text";
211
+ checklist: "checklist";
212
+ select: "select";
213
+ }>;
214
+ description: z.ZodString;
215
+ required: z.ZodBoolean;
216
+ visible: z.ZodBoolean;
217
+ options: z.ZodArray<z.ZodObject<{
218
+ optionId: z.ZodTemplateLiteral<`option_${string}`>;
219
+ name: z.ZodString;
220
+ }, z.core.$strip>>;
221
+ }, z.core.$strip>>;
222
+ }, z.core.$strip>;
223
+ export type CardKind = z.infer<typeof CardKind>;
224
+ export declare const TaskKind: z.ZodObject<{
225
+ kindId: z.ZodTemplateLiteral<`kind_${string}`>;
226
+ name: z.ZodString;
227
+ icon: z.ZodEnum<{
228
+ message: "message";
229
+ user: "user";
230
+ package: "package";
231
+ search: "search";
232
+ flag: "flag";
233
+ route: "route";
234
+ "arrow-right": "arrow-right";
235
+ "square-check": "square-check";
236
+ "file-text": "file-text";
237
+ bulb: "bulb";
238
+ target: "target";
239
+ calendar: "calendar";
240
+ star: "star";
241
+ bolt: "bolt";
242
+ bug: "bug";
243
+ rocket: "rocket";
244
+ }>;
245
+ }, z.core.$strip>;
246
+ export type TaskKind = z.infer<typeof TaskKind>;
247
+ export declare const ChecklistItem: z.ZodObject<{
248
+ text: z.ZodString;
249
+ done: z.ZodBoolean;
250
+ }, z.core.$strip>;
251
+ export type ChecklistItem = z.infer<typeof ChecklistItem>;
252
+ export declare const CardFieldValue: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodString>, z.ZodArray<z.ZodObject<{
253
+ text: z.ZodString;
254
+ done: z.ZodBoolean;
255
+ }, z.core.$strip>>]>;
256
+ export type CardFieldValue = z.infer<typeof CardFieldValue>;
257
+ export declare const TaskFields: z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodArray<z.ZodString>, z.ZodArray<z.ZodObject<{
258
+ text: z.ZodString;
259
+ done: z.ZodBoolean;
260
+ }, z.core.$strip>>]>>>;
261
+ export type TaskFields = z.infer<typeof TaskFields>;
262
+ export declare const TaskFieldsInput: z.ZodRecord<z.ZodString, z.ZodUnknown>;
263
+ export type TaskFieldsInput = z.infer<typeof TaskFieldsInput>;
264
+ export declare function emptyValue(value: unknown): boolean;
265
+ export declare const TaskKindInput: z.ZodString;
@@ -0,0 +1,153 @@
1
+ import { z } from "zod";
2
+ // Card kinds and their fields (#638, E115, Nodes › Board › Kartenarten): a board has no card kind
3
+ // (every card is Markdown) or several, and then every card has exactly one. A kind has a name, an
4
+ // icon, a description in Markdown and its fields in a fixed order; a field has a name, a type, a
5
+ // description, "required" and "visible on the card". Colab checks two things only: the type of every
6
+ // value and that no required field is empty.
7
+ //
8
+ // Kinds, fields and options are rows of a board, no words of the grammar and no tools of their own:
9
+ // `intelligence_board_update` takes the kinds as the whole list, like the columns. A task names its
10
+ // values by the field's name (`fields`), so an AI reads and writes them without ids. ⚠️ The values
11
+ // come in as a loose record and the handler checks them, so a wrong type is `invalid` with an issue
12
+ // per field at both doors, not the MCP SDK's own wording.
13
+ const ulid = z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/);
14
+ export const CardKindId = z
15
+ .templateLiteral([z.literal("kind"), z.literal("_"), ulid])
16
+ .describe("A card kind of this board, `kind_…`, as intelligence_board_get returned it.");
17
+ export const CardFieldId = z
18
+ .templateLiteral([z.literal("field"), z.literal("_"), ulid])
19
+ .describe("A field of this card kind, `field_…`, as intelligence_board_get returned it.");
20
+ export const CardOptionId = z
21
+ .templateLiteral([z.literal("option"), z.literal("_"), ulid])
22
+ .describe("An option of this select field, `option_…`, as intelligence_board_get returned it.");
23
+ // The seven types of a field and what a value of each is (Nodes › Board › Kartenarten).
24
+ export const cardFieldTypes = [
25
+ "text",
26
+ "list",
27
+ "checklist",
28
+ "number",
29
+ "date",
30
+ "link",
31
+ "select",
32
+ ];
33
+ export const CardFieldType = z
34
+ .enum(cardFieldTypes)
35
+ .describe('What a field holds. text: Markdown as a string. list: points, an array of strings, one per line. checklist: points with a tick, an array of { text, done }. number: a number. date: a day, "YYYY-MM-DD". link: a node of Colab by its id `node_…`, or an address starting with http:// or https://. select: one of the field\'s options, by its name.');
36
+ // The icons a card kind may carry, Tabler names (design/system: Tabler Icons).
37
+ export const cardKindIcons = [
38
+ "flag",
39
+ "route",
40
+ "arrow-right",
41
+ "square-check",
42
+ "file-text",
43
+ "bulb",
44
+ "target",
45
+ "search",
46
+ "user",
47
+ "calendar",
48
+ "star",
49
+ "bolt",
50
+ "bug",
51
+ "message",
52
+ "package",
53
+ "rocket",
54
+ ];
55
+ export const CardKindIcon = z
56
+ .enum(cardKindIcons)
57
+ .describe("The kind's icon, shown on every card of the kind and in its tab.");
58
+ const Name = z.string().max(200);
59
+ const Description = z.string().max(20_000);
60
+ export const CardFieldOptionInput = z.strictObject({
61
+ optionId: CardOptionId.optional().describe("The option to keep (and rename). Leaving it out makes a new option."),
62
+ name: Name.describe("The option's name, unique within the field whatever its case."),
63
+ });
64
+ export const CardFieldInput = z.strictObject({
65
+ fieldId: CardFieldId.optional().describe("The field to keep, as intelligence_board_get returned it. Leaving it out makes a new field."),
66
+ name: Name.describe("The field's name, unique within the kind whatever its case; a card names its value by it."),
67
+ type: CardFieldType.describe("What the field holds. A field's type changes only while no card has a value in it; else the answer is conflict."),
68
+ description: Description.optional().describe("What belongs into the field, Markdown; the card shows it as the placeholder of an empty field. Leaving it out keeps it (a new field has none)."),
69
+ required: z
70
+ .boolean()
71
+ .optional()
72
+ .describe("true: a card of the kind is saved only with a value in it. Cards that already stand keep it empty until their next save. Leaving it out keeps it (a new field is not required)."),
73
+ visible: z
74
+ .boolean()
75
+ .optional()
76
+ .describe("true: the card on the board shows the value under its title. Leaving it out keeps it (a new field is not shown)."),
77
+ options: z
78
+ .array(CardFieldOptionInput)
79
+ .max(50)
80
+ .optional()
81
+ .describe("Only for type select: its options, all of them, in their order. An option left out is removed, and a card holding it is empty there."),
82
+ });
83
+ export const CardKindInput = z.strictObject({
84
+ kindId: CardKindId.optional().describe("The card kind to keep, as intelligence_board_get returned it. Leaving it out makes a new kind."),
85
+ name: Name.describe("The kind's name, unique on the board whatever its case."),
86
+ icon: CardKindIcon.optional().describe("The kind's icon. Leaving it out keeps it (a new kind gets square-check)."),
87
+ description: Description.optional().describe("What a card of this kind is, Markdown. An empty text removes it; leaving it out keeps it."),
88
+ standard: z
89
+ .boolean()
90
+ .optional()
91
+ .describe("true for the one kind a new card gets when it names none. Without any, the first kind is the standard."),
92
+ fields: z
93
+ .array(CardFieldInput)
94
+ .max(50)
95
+ .describe("The kind's fields, all of them, in their order: a field with fieldId is kept, one without is made, one left out is removed (its values stay in the versions of the cards)."),
96
+ });
97
+ export const CardKindsInput = z
98
+ .array(CardKindInput)
99
+ .max(20)
100
+ .describe("The board's card kinds, all of them, in their order: a kind with kindId is kept, one without is made, one left out is removed, which only a kind no card has can be. Once a board has kinds, every card has exactly one: the cards that stand get the standard kind when the first kind is made, and a card never changes its kind. Not on the validation board.");
101
+ export const CardFieldOption = z.object({ optionId: CardOptionId, name: z.string() });
102
+ export const CardField = z.object({
103
+ fieldId: CardFieldId,
104
+ name: z.string(),
105
+ type: CardFieldType,
106
+ // Markdown, empty without one.
107
+ description: z.string(),
108
+ required: z.boolean(),
109
+ visible: z.boolean(),
110
+ // Only a select field has options; empty for every other type.
111
+ options: z.array(CardFieldOption),
112
+ });
113
+ export const CardKind = z.object({
114
+ kindId: CardKindId,
115
+ name: z.string(),
116
+ icon: CardKindIcon,
117
+ // Markdown, empty without one.
118
+ description: z.string(),
119
+ standard: z.boolean(),
120
+ fields: z.array(CardField),
121
+ });
122
+ // A task's kind as its answers name it, null on a board without kinds.
123
+ export const TaskKind = z.object({ kindId: CardKindId, name: z.string(), icon: CardKindIcon });
124
+ export const ChecklistItem = z.object({ text: z.string(), done: z.boolean() });
125
+ // A field's value as an answer carries it: text, date, link and select a string (select by the
126
+ // option's name), a number, a list of strings, or a checklist. Null is empty.
127
+ export const CardFieldValue = z.union([
128
+ z.string(),
129
+ z.number(),
130
+ z.array(z.string()),
131
+ z.array(ChecklistItem),
132
+ ]);
133
+ // Every field of the task's kind in the kind's order, by name; null for an empty one.
134
+ export const TaskFields = z.record(z.string(), CardFieldValue.nullable());
135
+ export const TaskFieldsInput = z
136
+ .record(z.string().max(200), z.unknown())
137
+ .describe('The values of the card\'s fields by the field\'s name, as intelligence_board_get names the fields of its kind: only the fields given change, null (or an empty text or list) empties one. A value of the wrong type, a field the kind does not have, or a required field left empty is invalid, and issues names each field. Example: { "Ziel": "…", "Fertig wenn": ["…", "…"], "Abgenommen": [{ "text": "…", "done": false }], "Aufwand": 3, "Fällig": "2026-10-24", "Prüft": "node_…", "Priorität": "hoch" }.');
138
+ // The checks of a value against its field (#638): the same rule in the backend, which refuses, and in
139
+ // the UI, which keeps "Anlegen" closed. `empty` is what a required field may not be.
140
+ export function emptyValue(value) {
141
+ if (value === null || value === undefined)
142
+ return true;
143
+ if (typeof value === "string")
144
+ return value.trim() === "";
145
+ if (Array.isArray(value))
146
+ return value.length === 0;
147
+ return false;
148
+ }
149
+ export const TaskKindInput = z
150
+ .string()
151
+ .min(1)
152
+ .max(200)
153
+ .describe("The card kind of the new card, by its name or its kindId. Leaving it out gives the board's standard kind; a board without kinds takes none. A card keeps its kind.");