@khorsheed/dsh-room 0.2.2 → 0.2.3

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 (109) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.en.md +29 -62
  3. package/README.i18n.yaml +2 -2
  4. package/README.md +28 -61
  5. package/lib/client.js +13097 -4182
  6. package/lib/index.js +4045 -730
  7. package/lib/journal-B4FOGO6S.js +482 -0
  8. package/lib/journal-Rid9AAnD.js +485 -0
  9. package/lib/tool.js +112 -166
  10. package/lib/typert.host.js +2031 -374
  11. package/lib/typert.remote-client.d.ts +34 -10
  12. package/lib/typert.remote-client.js +1599 -210
  13. package/lib/types/agent-setup.d.ts +1 -1
  14. package/lib/types/client/InviteAgentAction.js +4 -16
  15. package/lib/types/client/InviteDialog.d.ts +28 -6
  16. package/lib/types/client/InviteDialog.js +76 -12
  17. package/lib/types/client/MemberCard.d.ts +5 -1
  18. package/lib/types/client/MemberCard.js +4 -4
  19. package/lib/types/client/MembersView.d.ts +1 -1
  20. package/lib/types/client/MembersView.js +58 -22
  21. package/lib/types/client/RemoveMemberConfirm.d.ts +40 -0
  22. package/lib/types/client/RemoveMemberConfirm.js +85 -0
  23. package/lib/types/client/RoomApprovalView.d.ts +11 -0
  24. package/lib/types/client/RoomApprovalView.js +28 -0
  25. package/lib/types/client/RoomComposer.d.ts +1 -1
  26. package/lib/types/client/RoomComposer.js +195 -29
  27. package/lib/types/client/RoomDecisionView.d.ts +22 -0
  28. package/lib/types/client/RoomDecisionView.js +35 -0
  29. package/lib/types/client/RoomHelpView.d.ts +17 -0
  30. package/lib/types/client/RoomHelpView.js +56 -0
  31. package/lib/types/client/RoomInboxView.d.ts +10 -0
  32. package/lib/types/client/RoomInboxView.js +14 -0
  33. package/lib/types/client/RoomQuestionView.d.ts +13 -0
  34. package/lib/types/client/RoomQuestionView.js +61 -0
  35. package/lib/types/client/RoomRelayView.js +1 -1
  36. package/lib/types/client/RoomRunView.d.ts +3 -1
  37. package/lib/types/client/RoomRunView.js +12 -5
  38. package/lib/types/client/RoomSettingsView.d.ts +19 -0
  39. package/lib/types/client/RoomSettingsView.js +30 -0
  40. package/lib/types/client/RoomSpeechView.d.ts +22 -8
  41. package/lib/types/client/RoomSpeechView.js +94 -11
  42. package/lib/types/client/RoomStatsLine.d.ts +26 -5
  43. package/lib/types/client/RoomStatsLine.js +53 -7
  44. package/lib/types/client/RoomTaskCapsule.d.ts +19 -0
  45. package/lib/types/client/RoomTaskCapsule.js +37 -0
  46. package/lib/types/client/TasksTab.d.ts +41 -0
  47. package/lib/types/client/TasksTab.js +43 -0
  48. package/lib/types/client/TasksView.d.ts +44 -0
  49. package/lib/types/client/TasksView.js +149 -0
  50. package/lib/types/client/TeamView.d.ts +33 -0
  51. package/lib/types/client/TeamView.js +210 -0
  52. package/lib/types/client/at-menu.d.ts +127 -0
  53. package/lib/types/client/at-menu.js +173 -0
  54. package/lib/types/client/draft-chips.d.ts +67 -0
  55. package/lib/types/client/draft-chips.js +95 -0
  56. package/lib/types/client/executions.d.ts +0 -30
  57. package/lib/types/client/executions.js +4 -34
  58. package/lib/types/client/icons-local.d.ts +25 -0
  59. package/lib/types/client/icons-local.js +10 -0
  60. package/lib/types/client/icons.d.ts +2 -1
  61. package/lib/types/client/icons.js +1 -0
  62. package/lib/types/client/index.js +276 -72
  63. package/lib/types/client/locales.d.ts +482 -52
  64. package/lib/types/client/locales.js +490 -60
  65. package/lib/types/client/nodes.d.ts +112 -17
  66. package/lib/types/client/nodes.js +197 -26
  67. package/lib/types/client/slots.d.ts +117 -47
  68. package/lib/types/client/task-tag.d.ts +32 -0
  69. package/lib/types/client/task-tag.js +33 -0
  70. package/lib/types/client/tasks.d.ts +50 -0
  71. package/lib/types/client/tasks.js +82 -0
  72. package/lib/types/client/team.d.ts +73 -0
  73. package/lib/types/client/team.js +187 -0
  74. package/lib/types/decisions.d.ts +49 -0
  75. package/lib/types/decisions.js +101 -0
  76. package/lib/types/deliveries.d.ts +17 -1
  77. package/lib/types/deliveries.js +82 -6
  78. package/lib/types/dispatch.d.ts +92 -4
  79. package/lib/types/dispatch.js +477 -109
  80. package/lib/types/help.d.ts +137 -0
  81. package/lib/types/help.js +216 -0
  82. package/lib/types/helps.d.ts +26 -0
  83. package/lib/types/helps.js +47 -0
  84. package/lib/types/index.d.ts +292 -52
  85. package/lib/types/index.js +1415 -199
  86. package/lib/types/jobs.d.ts +22 -0
  87. package/lib/types/jobs.js +77 -0
  88. package/lib/types/journal.d.ts +17 -27
  89. package/lib/types/journal.js +120 -43
  90. package/lib/types/messaging.d.ts +65 -0
  91. package/lib/types/messaging.js +160 -0
  92. package/lib/types/plan-service.js +7 -1
  93. package/lib/types/report-gate.d.ts +81 -0
  94. package/lib/types/report-gate.js +89 -0
  95. package/lib/types/tool-definition.d.ts +43 -20
  96. package/lib/types/tool-definition.js +145 -212
  97. package/lib/types/tool.d.ts +2 -2
  98. package/lib/types/tool.js +3 -2
  99. package/lib/types/types.d.ts +755 -78
  100. package/locale/zh.json +1 -1
  101. package/package.json +3 -3
  102. package/lib/types/client/RoomActivityDock.d.ts +0 -19
  103. package/lib/types/client/RoomActivityDock.js +0 -105
  104. package/lib/types/client/RoomDockCapsules.d.ts +0 -64
  105. package/lib/types/client/RoomDockCapsules.js +0 -277
  106. package/lib/types/client/RoomPlanTab.d.ts +0 -15
  107. package/lib/types/client/RoomPlanTab.js +0 -13
  108. package/lib/types/client/RoomTaskLineView.d.ts +0 -13
  109. package/lib/types/client/RoomTaskLineView.js +0 -21
@@ -35,11 +35,23 @@ export interface RoomMemberAddedEvent {
35
35
  /** Stable identity; older journals derive it from their original join event. */
36
36
  readonly id?: string;
37
37
  readonly name: string;
38
- readonly kind: 'main-agent' | 'cli';
39
- /** CLI provider id; present exactly on `kind: 'cli'` members. */
38
+ readonly kind: 'main-agent' | 'cli' | 'native';
39
+ /** CLI provider id on `kind: 'cli'` members; `dsh` on native ones. */
40
40
  readonly provider?: string;
41
+ /**
42
+ * The host agent preset a native DSH member composes (`kind: 'native'`):
43
+ * a child session + agent in this host process, mounted with that preset
44
+ * at creation and locked from then on. Absent = the host's default preset.
45
+ */
46
+ readonly preset?: string;
41
47
  /** Role instructions, prepended to the member's first dispatch. */
42
48
  readonly instructions?: string;
49
+ /**
50
+ * The member's short public role (≤ 30 chars — journal `ROOM_ROLE_MAX` — e.g.
51
+ * 「代码审查」): what the roster, the cards and the team view show to
52
+ * everyone else. The instructions stay private to the member.
53
+ */
54
+ readonly role?: string;
43
55
  readonly invitedBy: 'human' | 'agent';
44
56
  /**
45
57
  * The member's own working directory (empty = inherits the room session's
@@ -55,6 +67,13 @@ export interface RoomMemberAddedEvent {
55
67
  * default.
56
68
  */
57
69
  readonly model?: string;
70
+ /**
71
+ * The delegation's reasoning effort (invite-time only, local-agent harness
72
+ * providers): recorded and consumed exactly like {@link RoomMemberAddedEvent.model}
73
+ * — the facade `start` call's `effort` option on the first dispatch, bound
74
+ * at spawn. Blank/omitted = follow the harness default.
75
+ */
76
+ readonly effort?: string;
58
77
  /** The CLI member's dsh child session, once delegation has started. */
59
78
  readonly childSessionId?: SessionId;
60
79
  }
@@ -70,6 +89,8 @@ export interface RoomMemberUpdatedEvent {
70
89
  readonly rename?: string;
71
90
  /** New role instructions; null CLEARS them (later dispatches inject none). */
72
91
  readonly instructions?: string | null;
92
+ /** New public role; null CLEARS it. */
93
+ readonly role?: string | null;
73
94
  /**
74
95
  * New member-level cwd (roster-recorded; the delegation facade's per-call
75
96
  * override is the family's open R2). null CLEARS the override — the member
@@ -84,6 +105,13 @@ export interface RoomMemberUpdatedEvent {
84
105
  * both). null CLEARS it — the member follows the harness default again.
85
106
  */
86
107
  readonly model?: string | null;
108
+ /**
109
+ * The member's intended reasoning effort, edited through the members tab's
110
+ * edit dialog. Roster-recorded intent consumed like the model above (a
111
+ * never-dispatched member's first facade `start`; a live member's switch
112
+ * rides the member-configuration channel). null CLEARS it.
113
+ */
114
+ readonly effort?: string | null;
87
115
  /**
88
116
  * The CLI member's delegation handle, journaled when the member's first
89
117
  * run starts (invite predates the handle; the dispatch engine appends this
@@ -116,7 +144,53 @@ export interface RoomDispatchEvent {
116
144
  /** Caller retry identity, persisted before accepting input. */
117
145
  readonly id?: string;
118
146
  readonly targetIds?: readonly string[];
119
- readonly origin?: 'human' | 'coordinator' | 'report' | 'relay';
147
+ /**
148
+ * Who sent it: the human, the coordinator, any other member (`member`,
149
+ * free member-to-member messaging), a delivery's report, or a legacy
150
+ * confirmed relay.
151
+ */
152
+ readonly origin?: 'human' | 'coordinator' | 'member' | 'report' | 'relay' | 'help';
153
+ /** A help request from another room (origin `help`): its final reply goes back there. */
154
+ readonly help?: RoomHelpOrigin;
155
+ /** The sending member's id (coordinator/member origins). */
156
+ readonly from?: string;
157
+ /**
158
+ * `task` (default for member sends): the recipient's final reply is reported
159
+ * back to the sender. `notify`: an FYI, never reported.
160
+ */
161
+ readonly kind?: 'task' | 'notify';
162
+ /**
163
+ * Position in its causal chain: 1 for a human message (or a send outside
164
+ * any room round), the sender's own delivery hop + 1 otherwise; reports
165
+ * count too. A send past the room's hop limit is held for the human.
166
+ */
167
+ readonly hop?: number;
168
+ /** The message this one answers (`#m<seq>` of an earlier dispatch). */
169
+ readonly inReplyTo?: number;
170
+ /**
171
+ * The sender's own words on what it is waiting for ("三位都打完招呼再一起跟
172
+ * 用户说"): read by the report gate when this delivery's report arrives.
173
+ */
174
+ readonly note?: string;
175
+ /**
176
+ * A report the gate HELD: not run as its own round. A native recipient has
177
+ * it in its inbox already; a CLI recipient gets it carried by its next round.
178
+ */
179
+ readonly held?: true;
180
+ /** A release round: wakes the recipient for the reports it holds (these dispatch seqs). */
181
+ readonly releases?: readonly number[];
182
+ /**
183
+ * The task (job) this message belongs to: the id of the human message that
184
+ * started it (its `user/message` id), or this dispatch's own `id` for a
185
+ * human dispatch that has no message (an invite's first task).
186
+ */
187
+ readonly task?: string;
188
+ /**
189
+ * The delivery during which the sender sent this (`<seq>:<memberId>`), so
190
+ * a member's sub-delegations nest under its own work in the task tree.
191
+ */
192
+ readonly parent?: string;
193
+ /** The member id this delivery's outcome is reported to. */
120
194
  readonly replyTo?: string;
121
195
  /** Completion report deduplication key (one source delivery). */
122
196
  readonly reportFor?: string;
@@ -131,11 +205,17 @@ export interface RoomDispatchEvent {
131
205
  export interface RoomSpeechEvent {
132
206
  /** Partial output from a stopped or failed run; never a completed answer. */
133
207
  readonly interrupted?: 'cancelled' | 'failed';
208
+ /** The member this reply was also reported to (the delivery's sender), by name. */
209
+ readonly reportedTo?: string;
134
210
  readonly member: string;
135
211
  readonly text: string;
136
212
  readonly childSessionId?: SessionId;
137
213
  /** Native admission→settle milliseconds, excluding queue time. */
138
214
  readonly durationMs?: number;
215
+ /** The run this speech closed (its execution metadata — tokens, model — is keyed by it). */
216
+ readonly runId?: string;
217
+ /** The member's closing assistant message in its own session (`childSessionId`): what per-message tools address. */
218
+ readonly messageId?: string;
139
219
  }
140
220
  /** Observed execution metadata; separate from lifecycle edges to avoid restarting chat nodes. */
141
221
  export interface RoomExecutionMetadataEvent {
@@ -143,10 +223,22 @@ export interface RoomExecutionMetadataEvent {
143
223
  readonly model?: string;
144
224
  readonly effort?: string;
145
225
  readonly tokens?: number;
226
+ /** The round's billing breakdown as the harness reported it (disjoint counts, the host's TokenUsage). */
227
+ readonly usage?: RoomRunUsage;
228
+ }
229
+ /** One round's billing breakdown: uncached input, cache read/write and output are disjoint. */
230
+ export interface RoomRunUsage {
231
+ readonly inputTokens: number;
232
+ readonly outputTokens: number;
233
+ readonly cacheReadTokens?: number;
234
+ readonly cacheWriteTokens?: number;
235
+ readonly reasoningTokens?: number;
146
236
  }
147
237
  /** A member run's lifecycle edge. */
148
238
  export interface RoomRunStateEvent {
149
239
  readonly childSessionId?: SessionId;
240
+ /** The child session's round this run reached (the last turn/start it wrote); terminal edges only, live sessions only. */
241
+ readonly childTurn?: number;
150
242
  /** Observed round metadata, never a requested-model guess or session total. */
151
243
  readonly model?: string;
152
244
  readonly effort?: string;
@@ -179,13 +271,262 @@ export interface RoomRelayEvent {
179
271
  readonly to: string;
180
272
  readonly content: string;
181
273
  readonly provenance?: Record<string, RoomJsonValue>;
274
+ /**
275
+ * Why the message waits for the human: the room asks for confirmation of
276
+ * member messages, the chain reached the hop limit, or the room is paused
277
+ * (released automatically on resume). Absent on legacy relays.
278
+ */
279
+ readonly reason?: RoomHoldReason;
280
+ /** The dispatch to create once released (absent on legacy relays). */
281
+ readonly intent?: RoomHeldDispatch;
282
+ }
283
+ /** Why a member message is held at the gate. */
284
+ export type RoomHoldReason = 'confirm' | 'hop-limit' | 'paused';
285
+ /** A held message's would-be dispatch. */
286
+ export interface RoomHeldDispatch {
287
+ readonly origin: 'coordinator' | 'member' | 'report' | 'help';
288
+ /** A help request from another room (origin `help`): its final reply goes back there. */
289
+ readonly help?: RoomHelpOrigin;
290
+ readonly from?: string;
291
+ readonly kind?: 'task' | 'notify';
292
+ readonly hop: number;
293
+ readonly inReplyTo?: number;
294
+ readonly replyTo?: string;
295
+ readonly reportFor?: string;
296
+ readonly plan?: {
297
+ readonly goalId: string;
298
+ };
299
+ readonly note?: string;
300
+ readonly task?: string;
301
+ readonly parent?: string;
302
+ }
303
+ /**
304
+ * The room's collaboration settings (latest event wins per field). Members
305
+ * message each other freely by default; `confirm` holds every non-coordinator
306
+ * member message for the human. `hopLimit` caps a causal chain (each delivery
307
+ * and report is one hop) before the room stops relaying automatically.
308
+ * `paused` holds every agent-originated message until resumed.
309
+ */
310
+ export interface RoomSettingsEvent {
311
+ readonly memberMessages?: 'free' | 'confirm';
312
+ readonly hopLimit?: number;
313
+ readonly paused?: boolean;
314
+ /**
315
+ * When a report reaches the member waiting on it: `judge` (default) asks
316
+ * the decision model whether to hand it over now or hold it in the
317
+ * recipient's inbox; `each` hands every report over at once.
318
+ */
319
+ readonly reportTiming?: 'judge' | 'each';
320
+ /** Automatic task filing: false = an untagged human message always starts a new task. */
321
+ readonly autoTaskFiling?: boolean;
322
+ /** Report timing: the "hand it over now" probability that delivers at once (0.1–0.9). */
323
+ readonly reportThreshold?: number;
324
+ /** Report timing: the longest a held report waits before it is handed over anyway, in minutes (1–30). */
325
+ readonly reportWaitMinutes?: number;
326
+ /** Cross-session help: minutes an unanswered request waits before its row turns amber (10–120). */
327
+ readonly helpReminderMinutes?: number;
328
+ }
329
+ /** The folded settings with defaults applied. */
330
+ export interface RoomSettings {
331
+ readonly memberMessages: 'free' | 'confirm';
332
+ readonly hopLimit: number;
333
+ readonly paused: boolean;
334
+ readonly reportTiming: 'judge' | 'each';
335
+ readonly autoTaskFiling: boolean;
336
+ readonly reportThreshold: number;
337
+ readonly reportWaitMinutes: number;
338
+ readonly helpReminderMinutes: number;
339
+ }
340
+ /** The room's own decision scenarios (the decision-model table, see decisions.ts). */
341
+ export type RoomDecisionScenario = 'task-filing' | 'report-timing';
342
+ /** One call to the decision model (typesafe), recorded as it went out and came back. */
343
+ export interface RoomDecisionCall {
344
+ /** The model the service answered with (or was asked, on a failure). */
345
+ readonly model: string;
346
+ readonly latencyMs?: number;
347
+ readonly cached?: boolean;
348
+ readonly inputTokens?: number;
349
+ readonly outputTokens?: number;
350
+ /** The request body's judged parts: the state and the questions, as sent. */
351
+ readonly request: {
352
+ readonly state: RoomJsonValue;
353
+ readonly questions: RoomJsonValue;
354
+ };
355
+ /** The answers as they came back. */
356
+ readonly response?: RoomJsonValue;
357
+ /** Why the call produced no usable answer (timeout, circuit-open, http …). */
358
+ readonly failure?: {
359
+ readonly reason: string;
360
+ readonly detail?: string;
361
+ };
362
+ }
363
+ /**
364
+ * One decision the room made on its own — by a rule, or by asking the
365
+ * decision model — with what it was about. The timeline shows the outcome;
366
+ * Context Lens lists the ones with a model call as requests.
367
+ */
368
+ export interface RoomDecisionEvent {
369
+ readonly id: string;
370
+ readonly scenario: RoomDecisionScenario;
371
+ /** task-filing: `new` or the task number; report-timing: `now` or `later`. */
372
+ readonly outcome: string;
373
+ /** The rule that decided (a fallback after a failed call included); absent = the model decided. */
374
+ readonly rule?: string;
375
+ /** The probability the outcome was taken with, when the model decided. */
376
+ readonly probability?: number;
377
+ readonly call?: RoomDecisionCall;
378
+ /** What it was about: the human message (task-filing) or the report's sender and recipient (report-timing). */
379
+ readonly about: {
380
+ readonly message?: string;
381
+ readonly task?: {
382
+ readonly number: number;
383
+ readonly title: string;
384
+ };
385
+ readonly from?: string;
386
+ readonly to?: string;
387
+ };
388
+ }
389
+ /**
390
+ * Which task a human message belongs to, when it is not a task of its own:
391
+ * the composer's explicit tag (`human`), the coordinator's own call
392
+ * (`coordinator`), or the decision model's suggestion (`model`). The latest
393
+ * link for a message wins; a message with no link starts its own task.
394
+ */
395
+ export interface RoomTaskLinkEvent {
396
+ /** The human message's `user/message` id. */
397
+ readonly message: string;
398
+ /** The task it belongs to (that task's root message id; its own id = a new task). */
399
+ readonly task: string;
400
+ readonly by: 'human' | 'coordinator' | 'model';
401
+ readonly probability?: number;
402
+ }
403
+ /** A human stopped a whole task: its open work was cancelled. */
404
+ export interface RoomJobStoppedEvent {
405
+ readonly task: string;
406
+ }
407
+ /** The report gate's verdict on one arrived report (journal record, UI line). */
408
+ export interface RoomReportGateEvent {
409
+ /** The report dispatch the verdict is about. */
410
+ readonly dispatchSeq: number;
411
+ /** The member the report is for. */
412
+ readonly memberId: string;
413
+ /** Its name when the verdict was written (the room line's label). */
414
+ readonly member: string;
415
+ readonly verdict: 'deliver' | 'hold' | 'release';
416
+ /**
417
+ * Why: a rule (`failure`, `last`, `question`, `setting`, `unavailable`,
418
+ * `timeout`, `manual`, `carried`) or the model (`model`).
419
+ */
420
+ readonly reason: string;
421
+ /** The model's yes-probability for "hand it over now", when asked. */
422
+ readonly probability?: number;
423
+ }
424
+ /**
425
+ * A CLI member's mode tool (a host preset's plugin tool reached through its
426
+ * bridge) needs the human's approval before it runs; the room asks in the
427
+ * conversation instead of the member's own session.
428
+ */
429
+ export interface RoomApprovalEvent {
430
+ readonly id: string;
431
+ readonly member: string;
432
+ readonly memberId: string;
433
+ readonly tool: string;
434
+ readonly reason?: string;
182
435
  }
436
+ /** How a member's tool approval ended. */
437
+ export interface RoomApprovalResolvedEvent {
438
+ readonly id: string;
439
+ /** `cancelled`: the call ended, or the host restarted, before an answer. */
440
+ readonly outcome: 'allowed-once' | 'rejected' | 'cancelled';
441
+ }
442
+ /** A member's tool approval still waiting for the human. */
443
+ export interface RoomApproval {
444
+ readonly id: string;
445
+ readonly member: string;
446
+ readonly tool: string;
447
+ readonly reason?: string;
448
+ readonly time: number;
449
+ }
450
+ /** answerApproval request: the human's answer to a pending approval. */
451
+ export interface RoomAnswerApprovalRequest {
452
+ readonly sessionId: SessionId;
453
+ readonly id: string;
454
+ readonly outcome: 'allowed-once' | 'rejected';
455
+ }
456
+ /** answerApproval outcome. */
457
+ export type RoomAnswerApprovalResult = {
458
+ readonly ok: true;
459
+ } | {
460
+ readonly ok: false;
461
+ readonly error: RoomFailure;
462
+ };
463
+ /** One option of a member's question to the human. */
464
+ export interface RoomQuestionOption {
465
+ readonly label: string;
466
+ readonly description?: string;
467
+ }
468
+ /** One question a member asks the human (the host's ask_user_question shape). */
469
+ export interface RoomQuestionItem {
470
+ readonly id: string;
471
+ readonly question: string;
472
+ readonly header?: string;
473
+ readonly options?: readonly RoomQuestionOption[];
474
+ readonly multiSelect?: boolean;
475
+ }
476
+ /** The human's answer to one question: the picked option labels and/or free text. */
477
+ export interface RoomQuestionAnswer {
478
+ readonly id: string;
479
+ readonly selected: readonly string[];
480
+ readonly custom?: string;
481
+ }
482
+ /**
483
+ * A member asks the human questions through its bridge (`ask_user_question`)
484
+ * instead of writing them into its reply: the room shows them as a card the
485
+ * human answers by picking, and the member's call waits for the answer.
486
+ */
487
+ export interface RoomQuestionEvent {
488
+ readonly id: string;
489
+ readonly member: string;
490
+ readonly memberId: string;
491
+ readonly questions: readonly RoomQuestionItem[];
492
+ }
493
+ /** How a member's questions ended. */
494
+ export interface RoomQuestionResolvedEvent {
495
+ readonly id: string;
496
+ /** `cancelled`: the call ended, timed out, or the host restarted before an answer. */
497
+ readonly outcome: 'answered' | 'cancelled';
498
+ readonly answers?: readonly RoomQuestionAnswer[];
499
+ }
500
+ /** A member's questions still waiting for the human. */
501
+ export interface RoomQuestion {
502
+ readonly id: string;
503
+ readonly member: string;
504
+ readonly questions: readonly RoomQuestionItem[];
505
+ readonly time: number;
506
+ }
507
+ /** answerQuestion request: the human's answers to a pending question card. */
508
+ export interface RoomAnswerQuestionRequest {
509
+ readonly sessionId: SessionId;
510
+ readonly id: string;
511
+ readonly answers: readonly RoomQuestionAnswer[];
512
+ }
513
+ /** answerQuestion outcome. */
514
+ export type RoomAnswerQuestionResult = {
515
+ readonly ok: true;
516
+ } | {
517
+ readonly ok: false;
518
+ readonly error: RoomFailure;
519
+ };
183
520
  /** A relay left the pending state (confirmed, dismissed, or delivered). */
184
521
  export interface RoomRelayResolvedEvent {
185
522
  readonly id: string;
186
523
  readonly state: 'confirmed' | 'dismissed' | 'sent';
187
524
  }
188
525
  /**
526
+ * Legacy: the retired task board (`room/task-*` events) is no longer
527
+ * written; old logs still replay into `RoomState.tasks`, which no view shows.
528
+ * Tasks are now `RoomJob`s, folded from dispatches.
529
+ *
189
530
  * Task-board task statuses. `failed` is terminal-from-the-engine (the run
190
531
  * settle writes it) but stays human-actionable: the board keeps the row
191
532
  * visible until the human dismisses it (closeTask → cancelled) or
@@ -196,7 +537,7 @@ export type RoomTaskStatus = 'pending' | 'in_progress' | 'done' | 'cancelled' |
196
537
  * The room's goal was set (or cleared: an empty text). Log-only; the journal
197
538
  * fold keeps the LATEST goal event's text as the current goal (empty/absent =
198
539
  * unset). The goal rides the roster section of every member prompt, and the
199
- * dock's goal capsule renders it with the task progress.
540
+ * task page shows and edits it.
200
541
  */
201
542
  export interface RoomGoalEvent {
202
543
  readonly text: string;
@@ -236,6 +577,105 @@ export interface RoomTaskEditedEvent {
236
577
  readonly title?: string;
237
578
  /** New blocking member; explicit null clears the wait. */
238
579
  readonly blockedBy?: string | null;
580
+ /** Hand the task to another member's lane (a removal's transfer). */
581
+ readonly member?: string;
582
+ }
583
+ /**
584
+ * Cross-session help: a member of this room asked another session for help.
585
+ * The helper stays in its own session (its own queue, model and context); the
586
+ * room journals the thread and carries messages both ways.
587
+ */
588
+ export interface RoomHelpEvent {
589
+ readonly id: string;
590
+ /** The asking member's id and name. */
591
+ readonly from: string;
592
+ readonly fromName: string;
593
+ /**
594
+ * The helper's session. A room target (`room`) routes through that room:
595
+ * to the named `member`, else to its coordinator.
596
+ */
597
+ readonly target: {
598
+ readonly sessionId: string;
599
+ readonly title: string;
600
+ readonly room?: true;
601
+ readonly member?: string;
602
+ };
603
+ /** The request as the helper reads it. */
604
+ readonly text: string;
605
+ }
606
+ /** An outside session kept on this room's member list (「加入房间成员」): a shortcut for asking it. */
607
+ export interface RoomLinkedSession {
608
+ readonly sessionId: string;
609
+ readonly title: string;
610
+ readonly time: number;
611
+ }
612
+ /** link / unlink / dismiss-hint requests: the room and the outside session. */
613
+ export interface RoomHelpLinkRequest {
614
+ readonly sessionId: SessionId;
615
+ /** The outside session. */
616
+ readonly target: string;
617
+ /** Its title (link only). */
618
+ readonly title?: string;
619
+ }
620
+ /** link / unlink / dismiss-hint outcome. */
621
+ export type RoomHelpLinkResult = {
622
+ readonly ok: true;
623
+ } | {
624
+ readonly ok: false;
625
+ readonly error: RoomFailure;
626
+ };
627
+ /** Where a help request in this room came from (the asking room's thread). */
628
+ export interface RoomHelpOrigin {
629
+ /** The thread id in the asking room. */
630
+ readonly id: string;
631
+ readonly room: string;
632
+ readonly roomTitle: string;
633
+ /** The asking member's name. */
634
+ readonly from: string;
635
+ }
636
+ /** Another room asked this room for help (shown on this room's timeline). */
637
+ export interface RoomHelpInEvent extends RoomHelpOrigin {
638
+ /** The member it was handed to (the named one, else the coordinator). */
639
+ readonly member: string;
640
+ readonly text: string;
641
+ /** `message`: the asker writing again on the thread. */
642
+ readonly op: 'request' | 'message';
643
+ /** Held at the gate (this room is paused) instead of delivered. */
644
+ readonly held?: true;
645
+ }
646
+ /** One message on a help thread after the request. */
647
+ export interface RoomHelpMessageEvent {
648
+ readonly help: string;
649
+ /**
650
+ * `question`: the helper asks the asker. `reply`: the helper's answer (its
651
+ * final reply plus a short handoff). `message`: the asker writes again
652
+ * (an answer to a question, or a follow-up).
653
+ */
654
+ readonly kind: 'question' | 'reply' | 'message';
655
+ readonly text: string;
656
+ /** The helper's short handoff note on a reply. */
657
+ readonly handoff?: string;
658
+ /** A reply taken from the helper's last answer because it never called the reply tool. */
659
+ readonly fallback?: true;
660
+ }
661
+ /** Where a help thread stands. */
662
+ export type RoomHelpStatus = 'queued' | 'running' | 'asking' | 'replied' | 'failed';
663
+ /** A help thread changed state. */
664
+ export interface RoomHelpStateEvent {
665
+ readonly help: string;
666
+ readonly state: RoomHelpStatus;
667
+ readonly error?: string;
668
+ }
669
+ /** A help thread, folded from its events. */
670
+ export interface RoomHelp extends RoomHelpEvent {
671
+ readonly state: RoomHelpStatus;
672
+ /** When the thread entered its current state (epoch ms). */
673
+ readonly since: number;
674
+ readonly error?: string;
675
+ readonly messages: readonly (RoomHelpMessageEvent & {
676
+ readonly time: number;
677
+ })[];
678
+ readonly time: number;
239
679
  }
240
680
  declare module '@deepseek-ai/dsh-session/types' {
241
681
  interface SessionEventMap {
@@ -262,6 +702,14 @@ declare module '@deepseek-ai/dsh-session/types' {
262
702
  'room/relay': RoomRelayEvent;
263
703
  /** Notification gate: a relay was confirmed, dismissed, or delivered. */
264
704
  'room/relay-resolved': RoomRelayResolvedEvent;
705
+ /** A CLI member's mode tool waits for the human's approval. */
706
+ 'room/approval': RoomApprovalEvent;
707
+ /** That approval was answered, or expired with its call. */
708
+ 'room/approval-resolved': RoomApprovalResolvedEvent;
709
+ /** A CLI member asks the human questions (a pick-to-answer card). */
710
+ 'room/question': RoomQuestionEvent;
711
+ /** Those questions were answered, or expired with the call. */
712
+ 'room/question-resolved': RoomQuestionResolvedEvent;
265
713
  /** Task board: a task was added. */
266
714
  'room/task-added': RoomTaskAddedEvent;
267
715
  /** Task board: a task changed status. */
@@ -270,20 +718,57 @@ declare module '@deepseek-ai/dsh-session/types' {
270
718
  'room/task-edited': RoomTaskEditedEvent;
271
719
  /** Goal: the room's goal was set (or cleared). */
272
720
  'room/goal': RoomGoalEvent;
721
+ /** Collaboration settings changed. */
722
+ 'room/settings': RoomSettingsEvent;
723
+ /** The report gate decided on an arrived report. */
724
+ 'room/report-gate': RoomReportGateEvent;
725
+ /** The room decided something on its own (a rule, or the decision model). */
726
+ 'room/decision': RoomDecisionEvent;
727
+ /** A human message was attributed to a task. */
728
+ 'room/task-link': RoomTaskLinkEvent;
729
+ /** A human stopped a task. */
730
+ 'room/job-stopped': RoomJobStoppedEvent;
731
+ /** Cross-session help: a member asked another session. */
732
+ 'room/help': RoomHelpEvent;
733
+ /** A message on a help thread (the helper's question or reply, the asker's follow-up). */
734
+ 'room/help-message': RoomHelpMessageEvent;
735
+ /** A help thread changed state. */
736
+ 'room/help-state': RoomHelpStateEvent;
737
+ /** Another room asked this room for help. */
738
+ 'room/help-in': RoomHelpInEvent;
739
+ /** An outside session joined this room's member list (a shortcut for asking it). */
740
+ 'room/help-link': {
741
+ readonly sessionId: string;
742
+ readonly title: string;
743
+ };
744
+ /** It left the list (its own session is untouched). */
745
+ 'room/help-unlink': {
746
+ readonly sessionId: string;
747
+ };
748
+ /** The human dismissed the 加入房间成员 hint for a session. */
749
+ 'room/help-nudge-dismissed': {
750
+ readonly sessionId: string;
751
+ };
273
752
  }
274
753
  }
275
754
  /** One roster member, as folded by the journal replay. */
276
755
  export interface RoomMember {
277
756
  readonly id?: string;
278
757
  readonly name: string;
279
- readonly kind: 'main-agent' | 'cli';
758
+ readonly kind: 'main-agent' | 'cli' | 'native';
280
759
  readonly provider?: string;
281
760
  readonly instructions?: string;
761
+ /** Short public role shown to the other members (see {@link RoomMemberAddedEvent.role}). */
762
+ readonly role?: string;
763
+ /** Native members: the host agent preset (see {@link RoomMemberAddedEvent.preset}). */
764
+ readonly preset?: string;
282
765
  readonly invitedBy: 'human' | 'agent';
283
766
  /** Member-level working directory (roster record; not yet passed to the facade). */
284
767
  readonly cwd?: string;
285
768
  /** The member's intended model (roster record; the facade start's `model` option on the first dispatch). */
286
769
  readonly model?: string;
770
+ /** The member's intended reasoning effort (roster record; the facade start's `effort` option on the first dispatch). */
771
+ readonly effort?: string;
287
772
  readonly childSessionId?: SessionId;
288
773
  }
289
774
  /** One notification relay, as folded by the journal replay. */
@@ -294,6 +779,8 @@ export interface RoomRelay {
294
779
  readonly content: string;
295
780
  readonly provenance?: Record<string, RoomJsonValue>;
296
781
  readonly state: RoomRelayState;
782
+ readonly reason?: RoomHoldReason;
783
+ readonly intent?: RoomHeldDispatch;
297
784
  }
298
785
  /** One task-board task, as folded by the journal replay. */
299
786
  export interface RoomTask {
@@ -327,10 +814,13 @@ export interface RoomExecution extends RoomMemberRun {
327
814
  readonly id: string;
328
815
  readonly memberId?: string;
329
816
  readonly childSessionId?: SessionId;
817
+ /** The child session round the run reached, as recorded by its terminal run-state edge. */
818
+ readonly childTurn?: number;
330
819
  readonly provider?: string;
331
820
  readonly model?: string;
332
821
  readonly effort?: string;
333
822
  readonly tokens?: number;
823
+ readonly usage?: RoomRunUsage;
334
824
  }
335
825
  /**
336
826
  * The replayed room state: roster, notification relays, the task board, run
@@ -345,10 +835,28 @@ export interface RoomState {
345
835
  readonly coordinator?: RoomCoordinatorEvent;
346
836
  readonly members: readonly RoomMember[];
347
837
  readonly relays: readonly RoomRelay[];
838
+ /** Members' tool approvals still waiting for the human. */
839
+ readonly approvals?: readonly RoomApproval[];
840
+ /** Members' questions still waiting for the human. */
841
+ readonly questions?: readonly RoomQuestion[];
348
842
  readonly tasks: readonly RoomTask[];
349
843
  readonly runs: readonly RoomMemberRun[];
350
844
  /** The current goal text (the latest `room/goal` event), undefined when unset. */
351
845
  readonly goal?: string;
846
+ /** Seq of the newest member speech addressed to the room (no `reportedTo`): the reply the human is reading, shown unfolded. */
847
+ readonly latestReplySeq?: number;
848
+ /** Seq of the newest member speech of any kind: its action row stays shown, older rows reveal on hover. */
849
+ readonly latestSpeechSeq?: number;
850
+ /** Collaboration settings (defaults when never set). */
851
+ readonly settings?: RoomSettings;
852
+ /** Tasks, newest first (absent in rooms that never dispatched work). */
853
+ readonly jobs?: readonly RoomJob[];
854
+ /** Cross-session help threads this room opened (absent when none). */
855
+ readonly helps?: readonly RoomHelp[];
856
+ /** Outside sessions kept on the member list (absent when none). */
857
+ readonly linked?: readonly RoomLinkedSession[];
858
+ /** Sessions whose 加入房间成员 hint was dismissed (absent when none). */
859
+ readonly helpNudgesDismissed?: readonly string[];
352
860
  }
353
861
  /**
354
862
  * The goal progress pair: done tasks over the COUNTABLE total — cancelled
@@ -395,6 +903,28 @@ export type RoomFailure = {
395
903
  readonly code: 'member-not-found';
396
904
  } | {
397
905
  readonly code: 'empty-text';
906
+ }
907
+ /** The public role is longer than 30 characters. */
908
+ | {
909
+ readonly code: 'role-too-long';
910
+ }
911
+ /** A settings value is out of range (hop limit 2–50). */
912
+ | {
913
+ readonly code: 'invalid-settings';
914
+ }
915
+ /** A member cannot message itself. */
916
+ | {
917
+ readonly code: 'self-message';
918
+ }
919
+ /** The `task` argument names no task of this room. */
920
+ | {
921
+ readonly code: 'unknown-task';
922
+ }
923
+ /** The preset is not one the host declares (carries the declared ids). */
924
+ | {
925
+ readonly code: 'unknown-preset';
926
+ readonly preset: string;
927
+ readonly available: readonly string[];
398
928
  } | {
399
929
  readonly code: 'nothing-to-update';
400
930
  } | {
@@ -423,6 +953,10 @@ export type RoomFailure = {
423
953
  /** The relay exists but already left the pending state. */
424
954
  | {
425
955
  readonly code: 'relay-not-pending';
956
+ } | {
957
+ readonly code: 'approval-not-pending';
958
+ } | {
959
+ readonly code: 'question-not-pending';
426
960
  }
427
961
  /** The main agent is the room itself: it cannot be renamed. */
428
962
  | {
@@ -452,9 +986,21 @@ export interface RoomMemberMessage {
452
986
  readonly content: string;
453
987
  readonly parentSessionId: SessionId;
454
988
  readonly provenance?: Record<string, RoomJsonValue>;
989
+ /** `task` (default): the reply is reported back; `notify`: FYI only. */
990
+ readonly kind?: 'task' | 'notify';
991
+ /** `m<seq>` (or the bare seq) of the message being answered. */
992
+ readonly inReplyTo?: string;
993
+ /** What the sender waits for before acting on the result. */
994
+ readonly note?: string;
995
+ /** `new` or a task number (see RoomMessageRequest.task). */
996
+ readonly task?: string;
455
997
  }
456
- /** The gate receipt handed back to the sending member through the bridge. */
457
- export type RoomMemberMessageReceipt = 'sent' | 'pending-confirm' | 'busy';
998
+ /**
999
+ * The gate receipt handed back to the sending member through the bridge,
1000
+ * quoted verbatim to the model: `sent #m<seq>…` or `pending-confirm …` with a
1001
+ * short explanation (the bare legacy words remain valid).
1002
+ */
1003
+ export type RoomMemberMessageReceipt = 'sent' | 'pending-confirm' | 'busy' | `sent ${string}` | `pending-confirm ${string}`;
458
1004
  /** isRoom probe: does this session carry the room marker? */
459
1005
  export interface RoomIsRoomRequest {
460
1006
  /** Session to probe. */
@@ -477,12 +1023,27 @@ export type RoomGetStateResult = {
477
1023
  export interface RoomInviteRequest {
478
1024
  /** Room session. */
479
1025
  readonly sessionId: SessionId;
1026
+ /**
1027
+ * `cli` (default): an external CLI through the local-agent family.
1028
+ * `native`: a DSH child agent in this host process, composing `preset`.
1029
+ */
1030
+ readonly kind?: 'cli' | 'native';
1031
+ /**
1032
+ * The member's mode: the host agent preset id. A native member composes it
1033
+ * (omitted = the host default); a CLI member reaches its plugin tools
1034
+ * through the bridge (omitted = no mode).
1035
+ */
1036
+ readonly preset?: string;
1037
+ /** With no `preset`: take the room session's own mode (the coordinator's invite default). */
1038
+ readonly inheritPreset?: boolean;
480
1039
  /** CLI provider id (non-blank). */
481
1040
  readonly provider: string;
482
1041
  /** Addressing/display name: unique in the room, no whitespace, no `@`. */
483
1042
  readonly name: string;
484
1043
  /** Role instructions, prepended to the member's first dispatch. */
485
1044
  readonly instructions?: string;
1045
+ /** Short public role (≤ 30 chars); blank/omitted = none. */
1046
+ readonly role?: string;
486
1047
  /**
487
1048
  * Member-level working directory (empty/omitted = inherits the room
488
1049
  * session's cwd). Recorded on the roster; not yet passed to the delegation
@@ -491,12 +1052,20 @@ export interface RoomInviteRequest {
491
1052
  readonly cwd?: string;
492
1053
  /** Optional first task, dispatched to the member as soon as it joins. */
493
1054
  readonly firstTask?: string;
1055
+ /** What the inviter waits for when the first task reports (see RoomDispatchEvent.note). */
1056
+ readonly note?: string;
494
1057
  /**
495
1058
  * The delegation's model (blank/omitted = follow the harness default).
496
1059
  * Applies to local-agent harness providers only: it lands as the facade
497
1060
  * `start` call's `model` option, bound at spawn for exec and live alike.
498
1061
  */
499
1062
  readonly model?: string;
1063
+ /**
1064
+ * The delegation's reasoning effort (blank/omitted = follow the harness
1065
+ * default): the facade `start` call's `effort` option, bound at spawn
1066
+ * alongside the model.
1067
+ */
1068
+ readonly effort?: string;
500
1069
  }
501
1070
  /** invite receipt. */
502
1071
  export interface RoomInvitation {
@@ -504,6 +1073,8 @@ export interface RoomInvitation {
504
1073
  readonly name: string;
505
1074
  /** True when a first task was supplied and dispatched with the invitation. */
506
1075
  readonly pendingFirstTask: boolean;
1076
+ /** The member's mode (preset id), when it has one. */
1077
+ readonly preset?: string;
507
1078
  }
508
1079
  /** invite outcome. */
509
1080
  export type RoomInviteResult = {
@@ -523,6 +1094,8 @@ export interface RoomUpdateMemberRequest {
523
1094
  readonly rename?: string;
524
1095
  /** New role instructions; null (or a blank string) CLEARS them. */
525
1096
  readonly instructions?: string | null;
1097
+ /** New public role; null (or a blank string) CLEARS it. */
1098
+ readonly role?: string | null;
526
1099
  /** New member-level cwd; null (or a blank string) CLEARS the override back to inheriting the room cwd. */
527
1100
  readonly cwd?: string | null;
528
1101
  /**
@@ -531,6 +1104,12 @@ export interface RoomUpdateMemberRequest {
531
1104
  * to following the harness default.
532
1105
  */
533
1106
  readonly model?: string | null;
1107
+ /**
1108
+ * New intended reasoning effort (roster-recorded, bound like the model on
1109
+ * the first dispatch); null (or a blank string) CLEARS it back to following
1110
+ * the harness default.
1111
+ */
1112
+ readonly effort?: string | null;
534
1113
  }
535
1114
  /** updateMember outcome. */
536
1115
  export type RoomUpdateMemberResult = {
@@ -549,8 +1128,31 @@ export interface RoomRemoveMemberRequest {
549
1128
  /** Member to remove. */
550
1129
  readonly name: string;
551
1130
  }
1131
+ /** What a removal actually did, for the undo toast and the room record. */
1132
+ export interface RoomRemoval {
1133
+ readonly name: string;
1134
+ /** True when a running round was stopped first. */
1135
+ readonly stopped: boolean;
1136
+ /** Queued messages that will never be delivered. */
1137
+ readonly cancelledDeliveries: number;
1138
+ /** Members that were waiting for a report and were told instead. */
1139
+ readonly notified: readonly string[];
1140
+ }
1141
+ /** restoreMember request: undo a removal (the member rejoins with its own session). */
1142
+ export interface RoomRestoreMemberRequest {
1143
+ readonly sessionId: SessionId;
1144
+ readonly name: string;
1145
+ }
552
1146
  /** removeMember outcome. */
553
1147
  export type RoomRemoveMemberResult = {
1148
+ readonly ok: true;
1149
+ readonly value: RoomRemoval;
1150
+ } | {
1151
+ readonly ok: false;
1152
+ readonly error: RoomFailure;
1153
+ };
1154
+ /** restoreMember outcome. */
1155
+ export type RoomRestoreMemberResult = {
554
1156
  readonly ok: true;
555
1157
  readonly value: {
556
1158
  readonly name: string;
@@ -560,6 +1162,28 @@ export type RoomRemoveMemberResult = {
560
1162
  readonly error: RoomFailure;
561
1163
  };
562
1164
  /** postMessage request: a human @-message into the room. */
1165
+ /** setTaskHint request: the composer's task tag for the human's next message. */
1166
+ export interface RoomSetTaskHintRequest {
1167
+ readonly sessionId: SessionId;
1168
+ /** `new`, a task root id, or null to clear. */
1169
+ readonly task: string | null;
1170
+ }
1171
+ /** stopJob request: stop every open delivery of one task. */
1172
+ export interface RoomStopJobRequest {
1173
+ readonly sessionId: SessionId;
1174
+ /** The task's root id. */
1175
+ readonly task: string;
1176
+ }
1177
+ /** stopJob outcome. */
1178
+ export type RoomStopJobResult = {
1179
+ readonly ok: true;
1180
+ readonly value: {
1181
+ readonly stopped: number;
1182
+ };
1183
+ } | {
1184
+ readonly ok: false;
1185
+ readonly error: RoomFailure;
1186
+ };
563
1187
  export interface RoomPostMessageRequest {
564
1188
  readonly requestId?: string;
565
1189
  /** Room session. */
@@ -573,6 +1197,8 @@ export interface RoomPostMessageRequest {
573
1197
  * way; the text itself is dispatched verbatim either way.
574
1198
  */
575
1199
  readonly targets?: readonly string[];
1200
+ /** The composer's task tag: `new` or a task root id (see RoomSetTaskHintRequest). */
1201
+ readonly task?: string;
576
1202
  }
577
1203
  /** What the postMessage parser made of the raw text. */
578
1204
  export interface RoomPostParsed {
@@ -600,17 +1226,71 @@ export interface RoomMessageRequest {
600
1226
  readonly member: string;
601
1227
  /** The message text. */
602
1228
  readonly text: string;
1229
+ /** `task` (default): the reply is reported back to the sender; `notify`: FYI only. */
1230
+ readonly kind?: 'task' | 'notify';
1231
+ /** `m<seq>` (or the bare seq) of the message being answered. */
1232
+ readonly inReplyTo?: string;
1233
+ /** What the sender is waiting for, for the report gate (see RoomDispatchEvent.note). */
1234
+ readonly note?: string;
1235
+ /**
1236
+ * Which task this belongs to: `new`, or a task number (「任务 N」). From the
1237
+ * room's own agent answering the human, it also re-files that human message.
1238
+ */
1239
+ readonly task?: string;
1240
+ }
1241
+ /** What happened to one member message. */
1242
+ export interface RoomMessageReceipt {
1243
+ readonly member: string;
1244
+ /** `m<seq>`: the message id the report will cite (absent while held). */
1245
+ readonly messageId?: string;
1246
+ /** Set when the message waits for the human instead of being delivered. */
1247
+ readonly held?: RoomHoldReason;
603
1248
  }
604
1249
  /** messageMember outcome. */
605
1250
  export type RoomMessageResult = {
1251
+ readonly ok: true;
1252
+ readonly value: RoomMessageReceipt;
1253
+ } | {
1254
+ readonly ok: false;
1255
+ readonly error: RoomFailure;
1256
+ };
1257
+ /** releaseReports request: hand a member its held reports now. */
1258
+ export interface RoomReleaseReportsRequest {
1259
+ readonly sessionId: SessionId;
1260
+ readonly name: string;
1261
+ }
1262
+ /** releaseReports outcome: whether anything was held. */
1263
+ export type RoomReleaseReportsResult = {
606
1264
  readonly ok: true;
607
1265
  readonly value: {
608
- readonly member: string;
1266
+ readonly released: boolean;
609
1267
  };
610
1268
  } | {
611
1269
  readonly ok: false;
612
1270
  readonly error: RoomFailure;
613
1271
  };
1272
+ /** setSettings request: change any subset of the collaboration settings. */
1273
+ export interface RoomSetSettingsRequest {
1274
+ readonly sessionId: SessionId;
1275
+ readonly reportTiming?: 'judge' | 'each';
1276
+ readonly autoTaskFiling?: boolean;
1277
+ readonly reportThreshold?: number;
1278
+ readonly reportWaitMinutes?: number;
1279
+ /** 10–120, in steps of 10. */
1280
+ readonly helpReminderMinutes?: number;
1281
+ readonly memberMessages?: 'free' | 'confirm';
1282
+ /** 2–50. */
1283
+ readonly hopLimit?: number;
1284
+ readonly paused?: boolean;
1285
+ }
1286
+ /** setSettings outcome: the folded settings after the change. */
1287
+ export type RoomSetSettingsResult = {
1288
+ readonly ok: true;
1289
+ readonly value: RoomSettings;
1290
+ } | {
1291
+ readonly ok: false;
1292
+ readonly error: RoomFailure;
1293
+ };
614
1294
  /** postMessage outcome. */
615
1295
  export type RoomPostMessageResult = {
616
1296
  readonly ok: true;
@@ -659,74 +1339,6 @@ export type RoomRelayResolveResult = {
659
1339
  readonly ok: false;
660
1340
  readonly error: RoomFailure;
661
1341
  };
662
- /** addTask request: a human-added task on a member's board lane. */
663
- export interface RoomAddTaskRequest {
664
- /** Room session. */
665
- readonly sessionId: SessionId;
666
- /** The member owning the task. */
667
- readonly member: string;
668
- /** Task title (non-blank). */
669
- readonly title: string;
670
- /**
671
- * Optional member this task waits on ("等 ada" — display only, never an
672
- * automatic dispatch). Must name a roster member when present.
673
- */
674
- readonly blockedBy?: string;
675
- }
676
- /** addTask outcome. */
677
- export type RoomAddTaskResult = {
678
- readonly ok: true;
679
- readonly value: {
680
- readonly id: string;
681
- };
682
- } | {
683
- readonly ok: false;
684
- readonly error: RoomFailure;
685
- };
686
- /** closeTask request: close an open task. */
687
- export interface RoomCloseTaskRequest {
688
- /** Room session. */
689
- readonly sessionId: SessionId;
690
- /** The task to close. */
691
- readonly taskId: string;
692
- /** Closing status (default 'done'). */
693
- readonly status?: 'done' | 'cancelled';
694
- }
695
- /** closeTask outcome. */
696
- export type RoomCloseTaskResult = {
697
- readonly ok: true;
698
- readonly value: {
699
- readonly id: string;
700
- };
701
- } | {
702
- readonly ok: false;
703
- readonly error: RoomFailure;
704
- };
705
- /**
706
- * updateTask request: edit an open task's title and/or blockedBy (the
707
- * `room_task` tool's update action — host method only, not on the Remote
708
- * surface; the capsule UI edits nothing but the goal).
709
- */
710
- export interface RoomUpdateTaskRequest {
711
- /** Room session. */
712
- readonly sessionId: SessionId;
713
- /** The task to edit. */
714
- readonly taskId: string;
715
- /** New title (non-blank when present). */
716
- readonly title?: string;
717
- /** New blocking member (must be on the roster); explicit null clears the wait. */
718
- readonly blockedBy?: string | null;
719
- }
720
- /** updateTask outcome. */
721
- export type RoomUpdateTaskResult = {
722
- readonly ok: true;
723
- readonly value: {
724
- readonly id: string;
725
- };
726
- } | {
727
- readonly ok: false;
728
- readonly error: RoomFailure;
729
- };
730
1342
  /** setGoal request: set (or, with a blank text, clear) the room's goal. */
731
1343
  export interface RoomSetGoalRequest {
732
1344
  /** Room session. */
@@ -744,8 +1356,10 @@ export type RoomSetGoalResult = {
744
1356
  readonly ok: false;
745
1357
  readonly error: RoomFailure;
746
1358
  };
747
- /** listProviders request (no parameters). */
1359
+ /** listProviders request. */
748
1360
  export interface RoomListProvidersRequest {
1361
+ /** The session the invite is for: the result then carries its mode (`sessionPreset`). */
1362
+ readonly sessionId?: SessionId;
749
1363
  }
750
1364
  /** One invitable CLI provider. */
751
1365
  export interface RoomProviderInfo {
@@ -766,6 +1380,23 @@ export interface RoomProviderList {
766
1380
  /** False when the local-agent delegation facade is absent (CLI members undispatchable). */
767
1381
  readonly localAgentAvailable: boolean;
768
1382
  readonly providers: readonly RoomProviderInfo[];
1383
+ /**
1384
+ * The host's agent presets a native DSH member may compose; absent when
1385
+ * the composition mounts no preset registry (native members then run the
1386
+ * plain composition).
1387
+ */
1388
+ readonly presets?: readonly RoomPresetInfo[];
1389
+ /** The requested session's own mode (preset id), when known: the dialog's default mode. */
1390
+ readonly sessionPreset?: string;
1391
+ }
1392
+ /** One host agent preset, as the invite dialog lists it. */
1393
+ export interface RoomPresetInfo {
1394
+ readonly id: string;
1395
+ readonly name?: string;
1396
+ readonly description?: string;
1397
+ readonly isDefault: boolean;
1398
+ /** Why the preset cannot be composed right now. */
1399
+ readonly broken?: string;
769
1400
  }
770
1401
  /** Durable role change. Handoff is bounded context, never native history migration. */
771
1402
  export interface RoomCoordinatorEvent {
@@ -807,11 +1438,57 @@ export interface RoomDelivery {
807
1438
  readonly id: string;
808
1439
  readonly dispatchSeq: number;
809
1440
  readonly memberId: string;
810
- readonly status: 'queued' | RoomDeliveryStateEvent['state'];
1441
+ /** `held`: a report the gate keeps for a later round (never run on its own). */
1442
+ readonly status: 'queued' | 'held' | RoomDeliveryStateEvent['state'];
811
1443
  readonly origin: NonNullable<RoomDispatchEvent['origin']>;
1444
+ /** The member id this delivery's outcome is reported to, when any. */
1445
+ readonly replyTo?: string;
1446
+ /** The sending member's id (coordinator/member origins). */
1447
+ readonly from?: string;
1448
+ /** `task` or `notify` (member sends); absent on human and legacy dispatches. */
1449
+ readonly kind?: 'task' | 'notify';
812
1450
  readonly text: string;
813
1451
  readonly error?: string;
814
1452
  readonly plan?: RoomDispatchEvent['plan'];
1453
+ /** The task this delivery belongs to (see RoomDispatchEvent.task). */
1454
+ readonly task?: string;
1455
+ /** The sender's own delivery this was sent from (the task tree's parent). */
1456
+ readonly parent?: string;
1457
+ /** Epoch ms: dispatched, admitted (first running edge), settled. */
1458
+ readonly queuedAt: number;
1459
+ readonly startedAt?: number;
1460
+ readonly endedAt?: number;
1461
+ /** Epoch ms the report gate held this report, and released it. */
1462
+ readonly heldAt?: number;
1463
+ readonly releasedAt?: number;
1464
+ }
1465
+ /**
1466
+ * One task: a human message that led to work (at least one delivery), the
1467
+ * follow-up messages attributed to it, and everything that work spawned.
1468
+ */
1469
+ export interface RoomJob {
1470
+ /** Root message id (or the root human dispatch's id). */
1471
+ readonly id: string;
1472
+ /** 1-based ordinal in the room, for 「任务 N」 and the coordinator's `task` argument. */
1473
+ readonly number: number;
1474
+ readonly title: string;
1475
+ readonly messages: readonly {
1476
+ readonly id: string;
1477
+ readonly time: number;
1478
+ readonly text: string;
1479
+ readonly by?: RoomTaskLinkEvent['by'];
1480
+ readonly probability?: number;
1481
+ }[];
1482
+ readonly status: 'running' | 'attention' | 'done' | 'stopped';
1483
+ readonly startedAt: number;
1484
+ /** Last settlement, when nothing is open any more. */
1485
+ readonly endedAt?: number;
1486
+ /** Delivery ids, in dispatch order. */
1487
+ readonly deliveries: readonly string[];
1488
+ /** Member ids that took part. */
1489
+ readonly members: readonly string[];
1490
+ /** The formal goal (room_plan) this task's work belongs to, when any. */
1491
+ readonly goalId?: string;
815
1492
  }
816
1493
  export interface RoomReconcileDeliveryRequest {
817
1494
  readonly sessionId: SessionId;