@anchrd/intel-contract 0.10.0 → 0.11.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/dist/contract/contract.d.ts +46 -0
- package/dist/contract/contract.js +120 -20
- package/package.json +1 -1
|
@@ -471,6 +471,7 @@ export declare const BoardStatus: z.ZodObject<{
|
|
|
471
471
|
id: z.ZodString;
|
|
472
472
|
label: z.ZodString;
|
|
473
473
|
order: z.ZodNumber;
|
|
474
|
+
terminal: z.ZodBoolean;
|
|
474
475
|
}, z.core.$strict>;
|
|
475
476
|
export type BoardStatus = z.infer<typeof BoardStatus>;
|
|
476
477
|
export declare const BoardDefaultStatuses: readonly BoardStatus[];
|
|
@@ -502,6 +503,45 @@ export declare const BoardTaskId: z.ZodString;
|
|
|
502
503
|
export declare const BoardTaskLabel: z.ZodString;
|
|
503
504
|
export declare const BoardTaskDate: z.ZodISODate;
|
|
504
505
|
export declare const BoardTaskDescription: z.ZodString;
|
|
506
|
+
/**
|
|
507
|
+
* The tasks one task waits for (#285), each of them at most once (anchrd/intel#318).
|
|
508
|
+
*
|
|
509
|
+
* ⚠️ Board-internal only, enforced on the write path: a dependency on a task in another board would
|
|
510
|
+
* hang this node on a file that can change without anyone here noticing. Across boards the link is
|
|
511
|
+
* `references`, which points at the board NODE and lands in the link graph.
|
|
512
|
+
*
|
|
513
|
+
* ⚠️ Refused rather than folded together, the same shape as the status ids in `ConfigureBoardInput`.
|
|
514
|
+
* A repeat carries no information — but that is a fact about the value, not about the answer: a
|
|
515
|
+
* caller handed back a shorter list than it sent is told nothing, and composes the same one again.
|
|
516
|
+
* The refusal names the mistake once, and the caller is holding the list it has to fix. (The one
|
|
517
|
+
* place a repeat is folded instead is `upgradeStoredBoard`, where there is no caller to tell.)
|
|
518
|
+
*
|
|
519
|
+
* ⚠️ It sits on the STORED task as well as on the two inputs, so a consumer may rely on it rather
|
|
520
|
+
* than defend against it — `createBoardGraph` mints one edge key per pair, and a second one threw
|
|
521
|
+
* the whole graph view off the screen for everybody looking at that board.
|
|
522
|
+
*/
|
|
523
|
+
export declare const BoardTaskDependsOn: z.ZodArray<z.ZodString>;
|
|
524
|
+
/**
|
|
525
|
+
* A task's labels, each of them at most once (anchrd/intel#318).
|
|
526
|
+
*
|
|
527
|
+
* ⚠️ The same rule the detail panel has always applied to what a person types — it refuses to add a
|
|
528
|
+
* label the task already carries — stated where every surface meets it, because the MCP write path
|
|
529
|
+
* did not. A repeated label draws the same chip twice on the card, with two remove buttons of which
|
|
530
|
+
* either takes both away, and weights that word higher in the search text (`indexing.ts`).
|
|
531
|
+
*/
|
|
532
|
+
export declare const BoardTaskLabels: z.ZodArray<z.ZodString>;
|
|
533
|
+
/**
|
|
534
|
+
* The Intel nodes a task points at, each of them at most once (anchrd/intel#318).
|
|
535
|
+
*
|
|
536
|
+
* They land in the link graph as `text` links, the same way a document's inline links do, so what a
|
|
537
|
+
* board points at is visible from the other side too.
|
|
538
|
+
*
|
|
539
|
+
* ⚠️ Distinct for the same reason as `labels`: the picker in the detail panel already refuses one
|
|
540
|
+
* the task holds, and the link graph counts a repeat once anyway (`ON CONFLICT DO NOTHING`), so a
|
|
541
|
+
* duplicate is a second row in the panel and nothing else — which is exactly the kind of value that
|
|
542
|
+
* has no reading and should not be storable.
|
|
543
|
+
*/
|
|
544
|
+
export declare const BoardTaskReferences: z.ZodArray<z.ZodString>;
|
|
505
545
|
export declare const BoardTask: z.ZodObject<{
|
|
506
546
|
id: z.ZodString;
|
|
507
547
|
title: z.ZodString;
|
|
@@ -528,6 +568,7 @@ export declare const BoardDocument: z.ZodObject<{
|
|
|
528
568
|
id: z.ZodString;
|
|
529
569
|
label: z.ZodString;
|
|
530
570
|
order: z.ZodNumber;
|
|
571
|
+
terminal: z.ZodBoolean;
|
|
531
572
|
}, z.core.$strict>>;
|
|
532
573
|
tasks: z.ZodArray<z.ZodObject<{
|
|
533
574
|
id: z.ZodString;
|
|
@@ -581,6 +622,7 @@ export declare const NodeBoard: z.ZodObject<{
|
|
|
581
622
|
id: z.ZodString;
|
|
582
623
|
label: z.ZodString;
|
|
583
624
|
order: z.ZodNumber;
|
|
625
|
+
terminal: z.ZodBoolean;
|
|
584
626
|
}, z.core.$strict>>;
|
|
585
627
|
tasks: z.ZodArray<z.ZodObject<{
|
|
586
628
|
id: z.ZodString;
|
|
@@ -609,6 +651,7 @@ export type NodeBoard = z.infer<typeof NodeBoard>;
|
|
|
609
651
|
export declare const BoardStatusInput: z.ZodObject<{
|
|
610
652
|
id: z.ZodString;
|
|
611
653
|
label: z.ZodString;
|
|
654
|
+
terminal: z.ZodOptional<z.ZodBoolean>;
|
|
612
655
|
}, z.core.$strict>;
|
|
613
656
|
export type BoardStatusInput = z.infer<typeof BoardStatusInput>;
|
|
614
657
|
export declare const ConfigureBoardInput: z.ZodObject<{
|
|
@@ -616,6 +659,7 @@ export declare const ConfigureBoardInput: z.ZodObject<{
|
|
|
616
659
|
statuses: z.ZodArray<z.ZodObject<{
|
|
617
660
|
id: z.ZodString;
|
|
618
661
|
label: z.ZodString;
|
|
662
|
+
terminal: z.ZodOptional<z.ZodBoolean>;
|
|
619
663
|
}, z.core.$strict>>;
|
|
620
664
|
idempotencyKey: z.ZodString;
|
|
621
665
|
}, z.core.$strict>;
|
|
@@ -829,6 +873,7 @@ export declare const ConfigureBoardResult: z.ZodObject<{
|
|
|
829
873
|
id: z.ZodString;
|
|
830
874
|
label: z.ZodString;
|
|
831
875
|
order: z.ZodNumber;
|
|
876
|
+
terminal: z.ZodBoolean;
|
|
832
877
|
}, z.core.$strict>>;
|
|
833
878
|
}, z.core.$strict>;
|
|
834
879
|
export type ConfigureBoardResult = z.infer<typeof ConfigureBoardResult>;
|
|
@@ -1761,6 +1806,7 @@ export declare const ToolCatalog: z.ZodObject<{
|
|
|
1761
1806
|
}, z.core.$strict>;
|
|
1762
1807
|
fingerprint: z.ZodString;
|
|
1763
1808
|
}, z.core.$strict>>;
|
|
1809
|
+
reached: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1764
1810
|
}, z.core.$strict>;
|
|
1765
1811
|
export type ToolCatalog = z.infer<typeof ToolCatalog>;
|
|
1766
1812
|
/**
|
|
@@ -291,14 +291,32 @@ export const BoardStatus = z.strictObject({
|
|
|
291
291
|
// both claiming position 3 is a board no surface could draw, and it is a state nobody has to be
|
|
292
292
|
// able to reason about if it cannot be expressed.
|
|
293
293
|
order: z.number().int().nonnegative(),
|
|
294
|
+
/**
|
|
295
|
+
* Whether standing in this column means the work is finished (anchrd/intel#311).
|
|
296
|
+
*
|
|
297
|
+
* It answers the one question #285 left open — when a `dependsOn` is satisfied — and it is the
|
|
298
|
+
* ONLY answer to it. There is deliberately no second reading anywhere: a surface that decided
|
|
299
|
+
* "done" for itself would decide it differently the first time somebody reconfigured a board.
|
|
300
|
+
*
|
|
301
|
+
* ⚠️ It is a property of the status, not a position in the list, and that distinction is the
|
|
302
|
+
* whole ticket. #286 first read "the last column before `archived`" as done, reasoning by symmetry
|
|
303
|
+
* with the server's rule that a new task lands in the first column that is not `archived`. But a
|
|
304
|
+
* status list is configurable on purpose, so `… done → blocked → archived` makes "blocked" mean
|
|
305
|
+
* finished — silently, with a wrong blocked marker as the only symptom.
|
|
306
|
+
*
|
|
307
|
+
* ⚠️ Several columns may carry it. "Done" and a cancelled-like column are both ends of the work,
|
|
308
|
+
* and nothing waiting on a cancelled task is still blocked by it.
|
|
309
|
+
*/
|
|
310
|
+
terminal: z.boolean(),
|
|
294
311
|
});
|
|
295
312
|
// What a board starts out with. Five columns, of which the last one is the fixed `archived` shelf.
|
|
313
|
+
// `done` and the shelf are where work ends; the three before them are not (anchrd/intel#311).
|
|
296
314
|
export const BoardDefaultStatuses = [
|
|
297
|
-
{ id: "backlog", label: "Backlog", order: 0 },
|
|
298
|
-
{ id: "in_progress", label: "In progress", order: 1 },
|
|
299
|
-
{ id: "review", label: "Review", order: 2 },
|
|
300
|
-
{ id: "done", label: "Done", order: 3 },
|
|
301
|
-
{ id: ArchivedBoardStatusId, label: "Archived", order: 4 },
|
|
315
|
+
{ id: "backlog", label: "Backlog", order: 0, terminal: false },
|
|
316
|
+
{ id: "in_progress", label: "In progress", order: 1, terminal: false },
|
|
317
|
+
{ id: "review", label: "Review", order: 2, terminal: false },
|
|
318
|
+
{ id: "done", label: "Done", order: 3, terminal: true },
|
|
319
|
+
{ id: ArchivedBoardStatusId, label: "Archived", order: 4, terminal: true },
|
|
302
320
|
];
|
|
303
321
|
/**
|
|
304
322
|
* Who a task is on: a person Gate knows, or an agent node in this installation (#285).
|
|
@@ -328,27 +346,76 @@ export const BoardTaskDate = z.iso.date();
|
|
|
328
346
|
// Markdown, and capped: a task's description is a card, and what needs more than this is a document
|
|
329
347
|
// the task can point at through `references`.
|
|
330
348
|
export const BoardTaskDescription = z.string().max(20_000);
|
|
349
|
+
/**
|
|
350
|
+
* The tasks one task waits for (#285), each of them at most once (anchrd/intel#318).
|
|
351
|
+
*
|
|
352
|
+
* ⚠️ Board-internal only, enforced on the write path: a dependency on a task in another board would
|
|
353
|
+
* hang this node on a file that can change without anyone here noticing. Across boards the link is
|
|
354
|
+
* `references`, which points at the board NODE and lands in the link graph.
|
|
355
|
+
*
|
|
356
|
+
* ⚠️ Refused rather than folded together, the same shape as the status ids in `ConfigureBoardInput`.
|
|
357
|
+
* A repeat carries no information — but that is a fact about the value, not about the answer: a
|
|
358
|
+
* caller handed back a shorter list than it sent is told nothing, and composes the same one again.
|
|
359
|
+
* The refusal names the mistake once, and the caller is holding the list it has to fix. (The one
|
|
360
|
+
* place a repeat is folded instead is `upgradeStoredBoard`, where there is no caller to tell.)
|
|
361
|
+
*
|
|
362
|
+
* ⚠️ It sits on the STORED task as well as on the two inputs, so a consumer may rely on it rather
|
|
363
|
+
* than defend against it — `createBoardGraph` mints one edge key per pair, and a second one threw
|
|
364
|
+
* the whole graph view off the screen for everybody looking at that board.
|
|
365
|
+
*/
|
|
366
|
+
export const BoardTaskDependsOn = z
|
|
367
|
+
.array(BoardTaskId)
|
|
368
|
+
.max(64)
|
|
369
|
+
.refine((ids) => new Set(ids).size === ids.length, {
|
|
370
|
+
error: "A task can be named only once in dependsOn",
|
|
371
|
+
});
|
|
372
|
+
/**
|
|
373
|
+
* A task's labels, each of them at most once (anchrd/intel#318).
|
|
374
|
+
*
|
|
375
|
+
* ⚠️ The same rule the detail panel has always applied to what a person types — it refuses to add a
|
|
376
|
+
* label the task already carries — stated where every surface meets it, because the MCP write path
|
|
377
|
+
* did not. A repeated label draws the same chip twice on the card, with two remove buttons of which
|
|
378
|
+
* either takes both away, and weights that word higher in the search text (`indexing.ts`).
|
|
379
|
+
*/
|
|
380
|
+
export const BoardTaskLabels = z
|
|
381
|
+
.array(BoardTaskLabel)
|
|
382
|
+
.max(32)
|
|
383
|
+
.refine((labels) => new Set(labels).size === labels.length, {
|
|
384
|
+
error: "A label can be named only once",
|
|
385
|
+
});
|
|
386
|
+
/**
|
|
387
|
+
* The Intel nodes a task points at, each of them at most once (anchrd/intel#318).
|
|
388
|
+
*
|
|
389
|
+
* They land in the link graph as `text` links, the same way a document's inline links do, so what a
|
|
390
|
+
* board points at is visible from the other side too.
|
|
391
|
+
*
|
|
392
|
+
* ⚠️ Distinct for the same reason as `labels`: the picker in the detail panel already refuses one
|
|
393
|
+
* the task holds, and the link graph counts a repeat once anyway (`ON CONFLICT DO NOTHING`), so a
|
|
394
|
+
* duplicate is a second row in the panel and nothing else — which is exactly the kind of value that
|
|
395
|
+
* has no reading and should not be storable.
|
|
396
|
+
*/
|
|
397
|
+
export const BoardTaskReferences = z
|
|
398
|
+
.array(IntelId)
|
|
399
|
+
.max(64)
|
|
400
|
+
.refine((ids) => new Set(ids).size === ids.length, {
|
|
401
|
+
error: "A node can be referenced only once",
|
|
402
|
+
});
|
|
331
403
|
export const BoardTask = z.strictObject({
|
|
332
404
|
id: BoardTaskId,
|
|
333
405
|
title: z.string().trim().min(1).max(240),
|
|
334
406
|
status: BoardStatusId,
|
|
335
407
|
assignee: BoardAssignee.nullable(),
|
|
336
|
-
labels:
|
|
408
|
+
labels: BoardTaskLabels,
|
|
337
409
|
startDate: BoardTaskDate.nullable(),
|
|
338
410
|
dueDate: BoardTaskDate.nullable(),
|
|
339
411
|
// ⚠️ The whole hierarchy in one field, deliberately: epic, task and subtask are a DEPTH and not a
|
|
340
412
|
// type (#285). A `kind` beside it would allow a subtask under nothing and an epic under an epic,
|
|
341
413
|
// and every surface would then need its own opinion about which combinations mean anything.
|
|
342
414
|
parentId: BoardTaskId.nullable(),
|
|
343
|
-
|
|
344
|
-
// would hang this node on a file that can change without anyone here noticing. Across boards the
|
|
345
|
-
// link is `references`, which points at the board NODE and lands in the link graph.
|
|
346
|
-
dependsOn: z.array(BoardTaskId).max(64),
|
|
415
|
+
dependsOn: BoardTaskDependsOn,
|
|
347
416
|
order: BoardTaskOrder,
|
|
348
417
|
description: BoardTaskDescription,
|
|
349
|
-
|
|
350
|
-
// do, so what a board points at is visible from the other side too.
|
|
351
|
-
references: z.array(IntelId).max(64),
|
|
418
|
+
references: BoardTaskReferences,
|
|
352
419
|
});
|
|
353
420
|
// The whole board, as it is stored and as it is read. There is no second representation to keep in
|
|
354
421
|
// step with it — this document is the file.
|
|
@@ -370,6 +437,16 @@ export const NodeBoard = z.strictObject({
|
|
|
370
437
|
export const BoardStatusInput = z.strictObject({
|
|
371
438
|
id: BoardStatusId,
|
|
372
439
|
label: z.string().trim().min(1).max(60),
|
|
440
|
+
/**
|
|
441
|
+
* Whether this column means finished (anchrd/intel#311).
|
|
442
|
+
*
|
|
443
|
+
* ⚠️ Optional, and the absence is not the same as `false`. A caller who says nothing gets the
|
|
444
|
+
* server's answer — `false` for an ordinary column, `true` for the shelf, which cannot be
|
|
445
|
+
* anything else. Making it a required boolean would force every caller that only wanted to rename
|
|
446
|
+
* a column to restate the whole board's notion of done, and getting one entry wrong there is a
|
|
447
|
+
* silent change to what counts as blocked.
|
|
448
|
+
*/
|
|
449
|
+
terminal: z.boolean().optional(),
|
|
373
450
|
});
|
|
374
451
|
// The status list, written whole and in the order it should be drawn — never a patch. Adding,
|
|
375
452
|
// renaming and reordering are all this one call, and `archived` has to be in what it is given.
|
|
@@ -384,7 +461,12 @@ export const ConfigureBoardInput = z.strictObject({
|
|
|
384
461
|
})
|
|
385
462
|
.refine((statuses) => statuses.some((status) => status.id === ArchivedBoardStatusId), {
|
|
386
463
|
error: `The "${ArchivedBoardStatusId}" status cannot be removed`,
|
|
387
|
-
})
|
|
464
|
+
})
|
|
465
|
+
// ⚠️ Refused rather than corrected, the same way removing the shelf is refused. A task swept
|
|
466
|
+
// onto `archived` is finished with, and a board that could declare the shelf non-terminal would
|
|
467
|
+
// hold every archived task open as a blocker forever. Only an EXPLICIT `false` is refused —
|
|
468
|
+
// saying nothing is fine and means the server's `true` (anchrd/intel#311).
|
|
469
|
+
.refine((statuses) => statuses.find((status) => status.id === ArchivedBoardStatusId)?.terminal !== false, { error: `The "${ArchivedBoardStatusId}" status is always terminal` }),
|
|
388
470
|
idempotencyKey: z.string().min(8).max(200),
|
|
389
471
|
});
|
|
390
472
|
/**
|
|
@@ -402,13 +484,13 @@ export const AddBoardTaskInput = z.strictObject({
|
|
|
402
484
|
// the shelf.
|
|
403
485
|
status: BoardStatusId.optional(),
|
|
404
486
|
assignee: BoardAssignee.nullable().default(null),
|
|
405
|
-
labels:
|
|
487
|
+
labels: BoardTaskLabels.default([]),
|
|
406
488
|
startDate: BoardTaskDate.nullable().default(null),
|
|
407
489
|
dueDate: BoardTaskDate.nullable().default(null),
|
|
408
490
|
parentId: BoardTaskId.nullable().default(null),
|
|
409
|
-
dependsOn:
|
|
491
|
+
dependsOn: BoardTaskDependsOn.default([]),
|
|
410
492
|
description: BoardTaskDescription.default(""),
|
|
411
|
-
references:
|
|
493
|
+
references: BoardTaskReferences.default([]),
|
|
412
494
|
// Where among its neighbours it goes. Both absent puts it last in its column.
|
|
413
495
|
afterTaskId: BoardTaskId.nullable().default(null),
|
|
414
496
|
beforeTaskId: BoardTaskId.nullable().default(null),
|
|
@@ -428,12 +510,12 @@ export const UpdateBoardTaskInput = z
|
|
|
428
510
|
taskId: BoardTaskId,
|
|
429
511
|
title: z.string().trim().min(1).max(240).optional(),
|
|
430
512
|
assignee: BoardAssignee.nullable().optional(),
|
|
431
|
-
labels:
|
|
513
|
+
labels: BoardTaskLabels.optional(),
|
|
432
514
|
startDate: BoardTaskDate.nullable().optional(),
|
|
433
515
|
dueDate: BoardTaskDate.nullable().optional(),
|
|
434
|
-
dependsOn:
|
|
516
|
+
dependsOn: BoardTaskDependsOn.optional(),
|
|
435
517
|
description: BoardTaskDescription.optional(),
|
|
436
|
-
references:
|
|
518
|
+
references: BoardTaskReferences.optional(),
|
|
437
519
|
idempotencyKey: z.string().min(8).max(200),
|
|
438
520
|
})
|
|
439
521
|
.refine((input) => input.title !== undefined ||
|
|
@@ -1030,6 +1112,24 @@ export const ToolCapability = z.strictObject({
|
|
|
1030
1112
|
export const ToolCatalog = z.strictObject({
|
|
1031
1113
|
portalConnected: z.boolean(),
|
|
1032
1114
|
items: z.array(ToolCapability),
|
|
1115
|
+
/**
|
|
1116
|
+
* Which delegated servers actually contributed a tool to this catalog (#289).
|
|
1117
|
+
*
|
|
1118
|
+
* ⚠️ Present only where the attribution was actually made — a delegated caller whose catalog was
|
|
1119
|
+
* read. It is absent for an ordinary user, and absent as well when the answer comes from one of
|
|
1120
|
+
* the short paths that never reach the portal (nothing delegated, no portal sign-in, connection
|
|
1121
|
+
* dropped). Absent therefore means "not stated", never "nothing arrived"; `[]` is the second one.
|
|
1122
|
+
*
|
|
1123
|
+
* That it is missing rather than empty on those paths is deliberate rather than half-finished:
|
|
1124
|
+
* the attribution already happens for a delegation — `capabilities` has to make it to cut the
|
|
1125
|
+
* list — so naming it costs nothing there, while computing the same thing for an ordinary user
|
|
1126
|
+
* would mean a second portal request per call, for a question their screen does not ask.
|
|
1127
|
+
*
|
|
1128
|
+
* ⚠️ It is the answer to "what arrived", never to "what was granted". A server missing here has
|
|
1129
|
+
* been switched off, revoked, or is failing right now; the delegation in the definition is
|
|
1130
|
+
* unchanged. Reading it the other way round would turn an outage into a permission change.
|
|
1131
|
+
*/
|
|
1132
|
+
reached: z.array(ToolServerHandle).optional(),
|
|
1033
1133
|
});
|
|
1034
1134
|
/**
|
|
1035
1135
|
* One MCP server the asking user reaches right now, as the portal itself names it (D30).
|