@brightbeamai/chap-coordinator-mcp 0.2.9

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.
@@ -0,0 +1,600 @@
1
+ // src/schemas.ts
2
+ var PARTICIPANT_URI = {
3
+ type: "string",
4
+ description: "Participant URI, e.g. 'human:alice@example.org' or 'agent:bot@local'."
5
+ };
6
+ var WORKSPACE_ID = {
7
+ type: "string",
8
+ description: "Workspace identifier, e.g. 'wsp_techcorp_support'."
9
+ };
10
+ var TASK_ID = {
11
+ type: "string",
12
+ description: "Task identifier returned by chap.task.create."
13
+ };
14
+ var ROUTING_HINTS = {
15
+ type: "object",
16
+ description: "Optional signals for the routing/1.0 profile.",
17
+ properties: {
18
+ criticality: { type: "string", enum: ["low", "medium", "high", "critical"] },
19
+ deadline: { type: "string", description: "ISO 8601 timestamp." },
20
+ risk_tier: { type: "string" },
21
+ max_cost_usd: { type: "number" }
22
+ },
23
+ additionalProperties: true
24
+ };
25
+ var SCHEMAS = {
26
+ "chap.workspace.create": {
27
+ type: "object",
28
+ properties: {
29
+ workspace: { ...WORKSPACE_ID, description: "Workspace id to create. If omitted, one is generated." },
30
+ profiles: {
31
+ type: "array",
32
+ items: { type: "string" },
33
+ description: "Profile identifiers to enable, e.g. ['core/1.0', 'review/1.0']."
34
+ },
35
+ mode: { type: "string", enum: ["shadow", "trial", "production"], default: "trial" },
36
+ mode_ceiling: { type: "string", enum: ["shadow", "trial", "production"], default: "production" }
37
+ },
38
+ additionalProperties: false
39
+ },
40
+ "chap.workspace.describe": {
41
+ type: "object",
42
+ properties: { workspace: WORKSPACE_ID },
43
+ required: ["workspace"]
44
+ },
45
+ "chap.workspace.set_profiles": {
46
+ type: "object",
47
+ properties: {
48
+ workspace: WORKSPACE_ID,
49
+ profiles: { type: "array", items: { type: "string" } }
50
+ },
51
+ required: ["workspace", "profiles"]
52
+ },
53
+ "chap.participant.join": {
54
+ type: "object",
55
+ properties: {
56
+ workspace: WORKSPACE_ID,
57
+ from: PARTICIPANT_URI,
58
+ type: { type: "string", enum: ["human", "agent", "service", "group", "workspace"] },
59
+ role: { type: "string", description: "Operator-defined role, e.g. 'reviewer' or 'drafter'." },
60
+ display_name: { type: "string" }
61
+ },
62
+ required: ["workspace", "from", "type"]
63
+ },
64
+ "chap.participant.leave": {
65
+ type: "object",
66
+ properties: { workspace: WORKSPACE_ID, from: PARTICIPANT_URI },
67
+ required: ["workspace", "from"]
68
+ },
69
+ "chap.task.create": {
70
+ type: "object",
71
+ properties: {
72
+ workspace: WORKSPACE_ID,
73
+ from: { ...PARTICIPANT_URI, description: "Delegator URI." },
74
+ kind: { type: "string", description: "Task kind, e.g. 'draft_response' or 'review'." },
75
+ assignee: { ...PARTICIPANT_URI, description: "Who the task is assigned to. Must be a workspace member." },
76
+ input: { type: "object", description: "Task-specific input payload.", additionalProperties: true },
77
+ routing_hints: ROUTING_HINTS,
78
+ mode: { type: "string", enum: ["shadow", "trial", "production"] }
79
+ },
80
+ required: ["workspace", "from", "kind", "assignee", "input"]
81
+ },
82
+ "chap.task.update": {
83
+ type: "object",
84
+ properties: {
85
+ workspace: WORKSPACE_ID,
86
+ from: PARTICIPANT_URI,
87
+ task_id: TASK_ID,
88
+ state: { type: "string", enum: ["in_progress", "review_requested", "declined", "paused", "cancelled", "completed"] },
89
+ progress_note: { type: "string" }
90
+ },
91
+ required: ["workspace", "from", "task_id", "state"]
92
+ },
93
+ "chap.task.complete": {
94
+ type: "object",
95
+ properties: {
96
+ workspace: WORKSPACE_ID,
97
+ from: PARTICIPANT_URI,
98
+ task_id: TASK_ID,
99
+ output: { description: "The task's output artefact. Pass as a JSON object or array, not a JSON-encoded string." },
100
+ confidence: { type: "number", description: "Self-reported confidence (0-1), where supported." },
101
+ routing_hints: ROUTING_HINTS
102
+ },
103
+ required: ["workspace", "from", "task_id"]
104
+ },
105
+ "chap.audit.read": {
106
+ type: "object",
107
+ properties: {
108
+ workspace: WORKSPACE_ID,
109
+ range: {
110
+ type: "object",
111
+ properties: {
112
+ from_seq: { type: "integer", description: "Start sequence number (inclusive)." },
113
+ to_seq: { type: "integer", description: "End sequence number (exclusive)." }
114
+ }
115
+ },
116
+ filter: {
117
+ type: "object",
118
+ properties: {
119
+ method: { type: "string" },
120
+ from: { type: "string" },
121
+ task_id: { type: "string" }
122
+ }
123
+ }
124
+ },
125
+ required: ["workspace"]
126
+ },
127
+ // ============================================================
128
+ // review/1.0
129
+ // ============================================================
130
+ "chap.review.request": {
131
+ type: "object",
132
+ properties: {
133
+ workspace: WORKSPACE_ID,
134
+ from: PARTICIPANT_URI,
135
+ task_id: TASK_ID,
136
+ to: {
137
+ oneOf: [PARTICIPANT_URI, { type: "array", items: PARTICIPANT_URI }],
138
+ description: "One or more reviewers. A single URI string, or a JSON array of URI strings (not a JSON-encoded string)."
139
+ },
140
+ rule: {
141
+ type: "string",
142
+ enum: ["any_one_approves", "all_approve", "quorum:2", "quorum:3"],
143
+ default: "any_one_approves"
144
+ },
145
+ artefact: { description: "The draft being submitted for review. Pass as a JSON object or array, not a JSON-encoded string." },
146
+ deadline: { type: "string" }
147
+ },
148
+ required: ["workspace", "from", "task_id", "to", "artefact"]
149
+ },
150
+ "chap.decide.approve": {
151
+ type: "object",
152
+ properties: {
153
+ workspace: WORKSPACE_ID,
154
+ from: PARTICIPANT_URI,
155
+ task_id: TASK_ID,
156
+ comment: { type: "string" },
157
+ tags: { type: "array", items: { type: "string" } }
158
+ },
159
+ required: ["workspace", "from", "task_id"]
160
+ },
161
+ "chap.decide.reject": {
162
+ type: "object",
163
+ properties: {
164
+ workspace: WORKSPACE_ID,
165
+ from: PARTICIPANT_URI,
166
+ task_id: TASK_ID,
167
+ comment: { type: "string" },
168
+ tags: { type: "array", items: { type: "string" } },
169
+ request_revision: { type: "boolean", description: "If true, task returns to in_progress instead of declined." }
170
+ },
171
+ required: ["workspace", "from", "task_id"]
172
+ },
173
+ "chap.decide.override": {
174
+ type: "object",
175
+ properties: {
176
+ workspace: WORKSPACE_ID,
177
+ from: PARTICIPANT_URI,
178
+ task_id: TASK_ID,
179
+ diff: {
180
+ type: "array",
181
+ description: "RFC 6902 JSON Patch operations applied to the artefact under review.",
182
+ items: {
183
+ type: "object",
184
+ properties: {
185
+ op: { type: "string", enum: ["add", "replace", "remove", "copy", "move", "test"] },
186
+ path: { type: "string" },
187
+ value: {},
188
+ from: { type: "string" }
189
+ },
190
+ required: ["op", "path"]
191
+ }
192
+ },
193
+ rationale: { type: "string", description: "Why the override was applied. Required for the structured-override audit trail." },
194
+ tags: { type: "array", items: { type: "string" } },
195
+ policy_refs: { type: "array", items: { type: "string" } },
196
+ logical_id: { type: "string" },
197
+ intent_preserved: { type: "boolean" }
198
+ },
199
+ required: ["workspace", "from", "task_id", "diff", "rationale"]
200
+ },
201
+ "chap.abstain.declare": {
202
+ type: "object",
203
+ properties: {
204
+ workspace: WORKSPACE_ID,
205
+ from: PARTICIPANT_URI,
206
+ task_id: TASK_ID,
207
+ reason: { type: "string" },
208
+ category: { type: "string", enum: ["conflict_of_interest", "insufficient_context", "out_of_scope", "other"] }
209
+ },
210
+ required: ["workspace", "from", "task_id", "reason"]
211
+ },
212
+ "chap.escalate.raise": {
213
+ type: "object",
214
+ properties: {
215
+ workspace: WORKSPACE_ID,
216
+ from: PARTICIPANT_URI,
217
+ original_task_id: TASK_ID,
218
+ new_task: {
219
+ type: "object",
220
+ properties: {
221
+ kind: { type: "string" },
222
+ assignee: PARTICIPANT_URI,
223
+ input: { type: "object", additionalProperties: true }
224
+ },
225
+ required: ["assignee"]
226
+ }
227
+ },
228
+ required: ["workspace", "from", "original_task_id", "new_task"]
229
+ },
230
+ // ============================================================
231
+ // whisper/1.0
232
+ // ============================================================
233
+ "chap.whisper.ask": {
234
+ type: "object",
235
+ properties: {
236
+ workspace: WORKSPACE_ID,
237
+ from: PARTICIPANT_URI,
238
+ task_id: TASK_ID,
239
+ to: { type: "array", items: PARTICIPANT_URI, description: "Who is being asked." },
240
+ question: { type: "string" },
241
+ options: {
242
+ type: "array",
243
+ items: { type: "object", properties: { id: { type: "string" }, label: { type: "string" } }, required: ["id"] },
244
+ description: "Optional multiple-choice options. If present, answer_option must be one of these ids."
245
+ },
246
+ deadline_ms: { type: "integer", description: "Time-to-live in milliseconds from now." },
247
+ default_if_lapsed: { description: "Value applied if the whisper lapses without an answer." },
248
+ urgency: { type: "string", enum: ["low", "medium", "high"], default: "low" }
249
+ },
250
+ required: ["workspace", "from", "task_id", "to", "question", "deadline_ms", "default_if_lapsed"]
251
+ },
252
+ "chap.whisper.answer": {
253
+ type: "object",
254
+ properties: {
255
+ workspace: WORKSPACE_ID,
256
+ from: PARTICIPANT_URI,
257
+ whisper_id: { type: "string" },
258
+ answer_option: { type: "string", description: "Option id (required when the whisper has options)." },
259
+ answer: { type: "string", description: "Free-text answer (when no options)." },
260
+ comment: { type: "string" }
261
+ },
262
+ required: ["workspace", "from", "whisper_id"]
263
+ },
264
+ // ============================================================
265
+ // deliberation/1.0
266
+ // ============================================================
267
+ "chap.deliberate.open": {
268
+ type: "object",
269
+ properties: {
270
+ workspace: WORKSPACE_ID,
271
+ from: PARTICIPANT_URI,
272
+ to: { type: "array", items: PARTICIPANT_URI, description: "Deliberation participants." },
273
+ task_id: TASK_ID,
274
+ rule: {
275
+ type: "string",
276
+ description: "Voting rule. Examples: any_one_approves, all_approve, quorum:N, weighted_vote:T, weighted_vote_with_veto:T."
277
+ },
278
+ question: { type: "string" },
279
+ weights: { type: "object", additionalProperties: { type: "number" }, description: "Voter -> weight map (for weighted rules)." },
280
+ veto: { type: "object", additionalProperties: { type: "boolean" }, description: "Voter -> can-veto map." },
281
+ deadline: { type: "string" }
282
+ },
283
+ required: ["workspace", "from", "to", "rule"]
284
+ },
285
+ "chap.deliberate.comment": {
286
+ type: "object",
287
+ properties: {
288
+ workspace: WORKSPACE_ID,
289
+ from: PARTICIPANT_URI,
290
+ deliberation_id: { type: "string" },
291
+ comment: { type: "string" }
292
+ },
293
+ required: ["workspace", "from", "deliberation_id", "comment"]
294
+ },
295
+ "chap.deliberate.vote": {
296
+ type: "object",
297
+ properties: {
298
+ workspace: WORKSPACE_ID,
299
+ from: PARTICIPANT_URI,
300
+ deliberation_id: { type: "string" },
301
+ vote: { type: "string", enum: ["yea", "nay", "abstain"] },
302
+ weight: { type: "number" },
303
+ comment: { type: "string" },
304
+ veto_invoked: { type: "boolean" }
305
+ },
306
+ required: ["workspace", "from", "deliberation_id", "vote"]
307
+ },
308
+ "chap.deliberate.close": {
309
+ type: "object",
310
+ properties: {
311
+ workspace: WORKSPACE_ID,
312
+ from: PARTICIPANT_URI,
313
+ deliberation_id: { type: "string" }
314
+ },
315
+ required: ["workspace", "from", "deliberation_id"]
316
+ },
317
+ // ============================================================
318
+ // handoff/1.0
319
+ // ============================================================
320
+ "chap.handoff.propose": {
321
+ type: "object",
322
+ properties: {
323
+ workspace: WORKSPACE_ID,
324
+ from: PARTICIPANT_URI,
325
+ to: { type: "string", description: "Recipient (URI or 'group:...')." },
326
+ tasks: {
327
+ type: "array",
328
+ items: {
329
+ type: "object",
330
+ properties: {
331
+ task_id: TASK_ID,
332
+ title: { type: "string" },
333
+ status_summary: { type: "string" },
334
+ next_action: { type: "string" },
335
+ blockers: { type: "array", items: { type: "string" } }
336
+ },
337
+ required: ["task_id"]
338
+ }
339
+ },
340
+ summary: { type: "string" },
341
+ context_links: { type: "array", items: { type: "string" } }
342
+ },
343
+ required: ["workspace", "from", "to", "tasks"]
344
+ },
345
+ "chap.handoff.accept": {
346
+ type: "object",
347
+ properties: {
348
+ workspace: WORKSPACE_ID,
349
+ from: PARTICIPANT_URI,
350
+ handoff_id: { type: "string" },
351
+ accepted_task_ids: { type: "array", items: TASK_ID, description: "If omitted, all proposed tasks are accepted." },
352
+ comment: { type: "string" }
353
+ },
354
+ required: ["workspace", "from", "handoff_id"]
355
+ },
356
+ "chap.handoff.decline": {
357
+ type: "object",
358
+ properties: {
359
+ workspace: WORKSPACE_ID,
360
+ from: PARTICIPANT_URI,
361
+ handoff_id: { type: "string" },
362
+ reason: { type: "string" },
363
+ suggested_target: PARTICIPANT_URI
364
+ },
365
+ required: ["workspace", "from", "handoff_id"]
366
+ },
367
+ // ============================================================
368
+ // control/1.0
369
+ // ============================================================
370
+ "chap.control.pause": {
371
+ type: "object",
372
+ properties: {
373
+ workspace: WORKSPACE_ID,
374
+ from: PARTICIPANT_URI,
375
+ scope: { type: "string", enum: ["task", "participant", "workspace"], default: "task" },
376
+ task_id: TASK_ID,
377
+ participant_uri: PARTICIPANT_URI,
378
+ in_flight_policy: { type: "string", enum: ["allow_to_complete", "interrupt"] },
379
+ reason: { type: "string" }
380
+ },
381
+ required: ["workspace", "from"]
382
+ },
383
+ "chap.control.resume": {
384
+ type: "object",
385
+ properties: {
386
+ workspace: WORKSPACE_ID,
387
+ from: PARTICIPANT_URI,
388
+ scope: { type: "string", enum: ["task", "participant", "workspace"], default: "task" },
389
+ task_id: TASK_ID,
390
+ participant_uri: PARTICIPANT_URI
391
+ },
392
+ required: ["workspace", "from"]
393
+ },
394
+ "chap.control.cancel": {
395
+ type: "object",
396
+ properties: {
397
+ workspace: WORKSPACE_ID,
398
+ from: PARTICIPANT_URI,
399
+ task_id: TASK_ID,
400
+ reason: { type: "string" }
401
+ },
402
+ required: ["workspace", "from", "task_id"]
403
+ },
404
+ "chap.control.snapshot": {
405
+ type: "object",
406
+ properties: {
407
+ workspace: WORKSPACE_ID,
408
+ from: PARTICIPANT_URI,
409
+ label: { type: "string" },
410
+ include: { type: "array", items: { type: "string" }, description: "Aspects to snapshot, e.g. ['members', 'open_tasks', 'mode_ceiling']." }
411
+ },
412
+ required: ["workspace", "from"]
413
+ },
414
+ "chap.control.rollback": {
415
+ type: "object",
416
+ properties: {
417
+ workspace: WORKSPACE_ID,
418
+ from: PARTICIPANT_URI,
419
+ to_snapshot_artefact_id: { type: "string" },
420
+ what_to_restore: { type: "array", items: { type: "string" } },
421
+ reason: { type: "string" }
422
+ },
423
+ required: ["workspace", "from", "to_snapshot_artefact_id"]
424
+ },
425
+ "chap.control.supersede": {
426
+ type: "object",
427
+ properties: {
428
+ workspace: WORKSPACE_ID,
429
+ from: PARTICIPANT_URI,
430
+ task_id: TASK_ID,
431
+ successor_task: {
432
+ type: "object",
433
+ properties: {
434
+ kind: { type: "string" },
435
+ assignee: PARTICIPANT_URI,
436
+ input: { type: "object", additionalProperties: true }
437
+ },
438
+ required: ["kind"]
439
+ },
440
+ reason: { type: "string" }
441
+ },
442
+ required: ["workspace", "from", "task_id", "successor_task"]
443
+ },
444
+ "chap.control.set_mode_ceiling": {
445
+ type: "object",
446
+ properties: {
447
+ workspace: WORKSPACE_ID,
448
+ from: PARTICIPANT_URI,
449
+ new_ceiling: { type: "string", enum: ["shadow", "trial", "production"] },
450
+ reason: { type: "string" }
451
+ },
452
+ required: ["workspace", "from", "new_ceiling"]
453
+ },
454
+ // ============================================================
455
+ // routing/1.0
456
+ // ============================================================
457
+ "chap.task.route": {
458
+ type: "object",
459
+ properties: {
460
+ workspace: WORKSPACE_ID,
461
+ from: PARTICIPANT_URI,
462
+ task_id: TASK_ID,
463
+ candidates: { type: "array", items: PARTICIPANT_URI, description: "Candidate assignees." }
464
+ },
465
+ required: ["workspace", "from", "task_id", "candidates"]
466
+ },
467
+ "chap.review.depth": {
468
+ type: "object",
469
+ properties: {
470
+ workspace: WORKSPACE_ID,
471
+ from: PARTICIPANT_URI,
472
+ task_id: TASK_ID,
473
+ artefact_routing_hints: {
474
+ type: "object",
475
+ description: "Per-artefact signals like confidence, model_id, cost_consumed_usd.",
476
+ additionalProperties: true
477
+ }
478
+ },
479
+ required: ["workspace", "from", "task_id"]
480
+ },
481
+ "chap.escalate.auto": {
482
+ type: "object",
483
+ properties: {
484
+ workspace: WORKSPACE_ID,
485
+ from: PARTICIPANT_URI,
486
+ task_id: TASK_ID,
487
+ default_escalation_target: PARTICIPANT_URI
488
+ },
489
+ required: ["workspace", "from", "task_id"]
490
+ },
491
+ // ============================================================
492
+ // security-signed/1.0
493
+ // ============================================================
494
+ "chap.participant.rotate_key": {
495
+ type: "object",
496
+ properties: {
497
+ workspace: WORKSPACE_ID,
498
+ from: PARTICIPANT_URI,
499
+ old_kid: { type: "string" },
500
+ new_jwk: { type: "object", additionalProperties: true }
501
+ },
502
+ required: ["workspace", "from", "old_kid", "new_jwk"]
503
+ },
504
+ "chap.participant.revoke_key": {
505
+ type: "object",
506
+ properties: {
507
+ workspace: WORKSPACE_ID,
508
+ from: PARTICIPANT_URI,
509
+ target_uri: PARTICIPANT_URI,
510
+ kid: { type: "string" },
511
+ reason: { type: "string" }
512
+ },
513
+ required: ["workspace", "from", "target_uri", "kid"]
514
+ },
515
+ // ============================================================
516
+ // audit-scitt/1.0
517
+ // ============================================================
518
+ "chap.audit.submit_to_scitt": {
519
+ type: "object",
520
+ properties: {
521
+ workspace: WORKSPACE_ID,
522
+ from: PARTICIPANT_URI,
523
+ range: {
524
+ type: "object",
525
+ properties: {
526
+ from_seq: { type: "integer" },
527
+ to_seq: { type: "integer" }
528
+ }
529
+ },
530
+ issuer: { type: "string" }
531
+ },
532
+ required: ["workspace"]
533
+ },
534
+ "chap.audit.verify_receipt": {
535
+ type: "object",
536
+ properties: {
537
+ workspace: WORKSPACE_ID,
538
+ from: PARTICIPANT_URI,
539
+ receipt: { type: "object", additionalProperties: true }
540
+ },
541
+ required: ["workspace", "receipt"]
542
+ },
543
+ "chap.audit.verify_chain": {
544
+ type: "object",
545
+ properties: { workspace: WORKSPACE_ID, from: PARTICIPANT_URI },
546
+ required: ["workspace"]
547
+ }
548
+ };
549
+ var TOOL_NAMES = Object.keys(SCHEMAS);
550
+ function schemaFor(toolName) {
551
+ return SCHEMAS[toolName] ?? null;
552
+ }
553
+ function methodForTool(toolName) {
554
+ if (!toolName.startsWith("chap.")) return null;
555
+ return toolName.slice("chap.".length);
556
+ }
557
+ function admitsType(schema, t) {
558
+ if (!schema) return false;
559
+ if (schema.type === t) return true;
560
+ if (schema.oneOf) return schema.oneOf.some((s) => admitsType(s, t));
561
+ if (schema.type === void 0 && !schema.oneOf && !schema.enum) return true;
562
+ return false;
563
+ }
564
+ function coerceValue(value, schema) {
565
+ if (typeof value !== "string") return value;
566
+ const trimmed = value.trim();
567
+ if (trimmed.length === 0) return value;
568
+ const looksLikeObject = trimmed.startsWith("{");
569
+ const looksLikeArray = trimmed.startsWith("[");
570
+ if (!looksLikeObject && !looksLikeArray) return value;
571
+ const wantObject = looksLikeObject && admitsType(schema, "object");
572
+ const wantArray = looksLikeArray && admitsType(schema, "array");
573
+ if (!wantObject && !wantArray) return value;
574
+ try {
575
+ const parsed = JSON.parse(value);
576
+ if (Array.isArray(parsed) && admitsType(schema, "array")) return parsed;
577
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && admitsType(schema, "object")) return parsed;
578
+ return value;
579
+ } catch {
580
+ return value;
581
+ }
582
+ }
583
+ function coerceToolArgs(toolName, args) {
584
+ const schema = schemaFor(toolName);
585
+ const props = schema?.properties;
586
+ if (!props) return args;
587
+ const out = {};
588
+ for (const [key, value] of Object.entries(args)) {
589
+ out[key] = coerceValue(value, props[key]);
590
+ }
591
+ return out;
592
+ }
593
+ export {
594
+ SCHEMAS,
595
+ TOOL_NAMES,
596
+ coerceToolArgs,
597
+ methodForTool,
598
+ schemaFor
599
+ };
600
+ //# sourceMappingURL=schemas.js.map