pi-roundtable-web 0.25.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +165 -12
  3. package/dist/account-zk4efb87.css +102 -0
  4. package/dist/chunk-account-ghq105t4.js +1 -0
  5. package/dist/chunk-action-menu-me0g9qsc.js +1 -0
  6. package/dist/{chunk-agent-0pm9p3nn.js → chunk-agent-rdv7ekrt.js} +1 -1
  7. package/dist/chunk-arranged-rooms-81rqhx9x.js +1 -0
  8. package/dist/chunk-character-creator-bd426yjw.js +1 -0
  9. package/dist/chunk-codeeditor-ajhgd33t.js +2 -0
  10. package/dist/chunk-confirm-p3mts8mx.js +1 -0
  11. package/dist/{chunk-connectors-anhghy3k.js → chunk-connectors-bkv3xn83.js} +1 -1
  12. package/dist/chunk-conversations-0e0vbxwr.js +1 -0
  13. package/dist/{chunk-drag-q4fx9b22.js → chunk-drag-peyb8t0k.js} +1 -1
  14. package/dist/{chunk-entry-he1embgp.js → chunk-entry-mv7q8br0.js} +1 -1
  15. package/dist/chunk-folder-list-era3tksh.js +1 -0
  16. package/dist/chunk-folds-hvws0bd5.js +1 -0
  17. package/dist/chunk-gate-hc7dd0fx.js +1 -0
  18. package/dist/chunk-group-scene-dkbpmbh5.js +1 -0
  19. package/dist/chunk-group-table-fqmxgdfw.js +1 -0
  20. package/dist/chunk-host-icons-4xde9ntk.js +1 -0
  21. package/dist/chunk-host-picture-014yzk20.js +1 -0
  22. package/dist/chunk-host-state-t56e5sdy.js +1 -0
  23. package/dist/chunk-host-ui-p1zy9nmp.js +1 -0
  24. package/dist/chunk-index-0fmmvgee.js +2 -0
  25. package/dist/chunk-index-0q15ysrb.js +1 -0
  26. package/dist/chunk-index-0xh24y25.js +2 -0
  27. package/dist/chunk-index-2yebd9tb.js +426 -0
  28. package/dist/chunk-index-4t0r3t3b.js +2 -0
  29. package/dist/chunk-index-5yzfrf7b.js +138 -0
  30. package/dist/{chunk-index-d5abvq7v.js → chunk-index-6twb7ccd.js} +2 -2
  31. package/dist/chunk-index-73gh7kgr.js +920 -0
  32. package/dist/chunk-index-7xffskfa.js +8 -0
  33. package/dist/chunk-index-aqw7cy5j.js +1 -0
  34. package/dist/chunk-index-b6ca02e8.js +2 -0
  35. package/dist/chunk-index-b8nvhcx5.js +2 -0
  36. package/dist/{chunk-index-bvfqjh77.js → chunk-index-cvbdf2ca.js} +2 -2
  37. package/dist/chunk-index-czdketze.js +2 -0
  38. package/dist/{chunk-index-9jqcskb4.js → chunk-index-dt9775ka.js} +5 -5
  39. package/dist/chunk-index-eg55mqqe.js +1 -0
  40. package/dist/chunk-index-gr6e0hse.js +2 -0
  41. package/dist/chunk-index-gyary7np.js +13 -0
  42. package/dist/chunk-index-j214tczc.js +1 -0
  43. package/dist/chunk-index-jd6632ef.js +2 -0
  44. package/dist/chunk-index-jw7dtshr.js +2 -0
  45. package/dist/{chunk-index-krtk6nn2.js → chunk-index-k7t14rwa.js} +2 -2
  46. package/dist/chunk-index-kwcx62wb.js +4 -0
  47. package/dist/chunk-index-m7fvw92f.js +2 -0
  48. package/dist/chunk-index-mmg788a1.js +2 -0
  49. package/dist/chunk-index-mq0dacwr.js +2 -0
  50. package/dist/chunk-index-p53ak25v.js +2 -0
  51. package/dist/{chunk-index-27qca4mr.js → chunk-index-pk1yxkv4.js} +2 -2
  52. package/dist/{chunk-index-9b1kt7qw.css → chunk-index-rbcz9jd4.css} +1 -1
  53. package/dist/{chunk-index-s681nny9.js → chunk-index-rmxbdmn2.js} +2 -2
  54. package/dist/chunk-index-rnxj3z8k.js +2 -0
  55. package/dist/chunk-index-snzzfhk3.js +2 -0
  56. package/dist/chunk-index-v3bmr0nw.js +2 -0
  57. package/dist/chunk-index-vcyzwtk2.js +2 -0
  58. package/dist/{chunk-index-zfd00hwb.js → chunk-index-w2j3njb6.js} +2 -2
  59. package/dist/chunk-index-w31c4yjv.js +2 -0
  60. package/dist/chunk-index-wrm8w165.js +2 -0
  61. package/dist/chunk-index-xh0mg9cw.js +2 -0
  62. package/dist/chunk-index-ybtvvx85.js +2 -0
  63. package/dist/chunk-index-yzsgsvnp.js +2 -0
  64. package/dist/{chunk-index-18gxy79n.js → chunk-index-z9x4cnzf.js} +2 -2
  65. package/dist/chunk-index-zrvg23jd.js +2 -0
  66. package/dist/chunk-index-zynq0b0w.js +50 -0
  67. package/dist/chunk-lang-css-88v3hp3d.js +1 -0
  68. package/dist/{chunk-lang-dockerfile-d5mzxs60.js → chunk-lang-dockerfile-k728ewsf.js} +1 -1
  69. package/dist/{chunk-lang-go-830fmhba.js → chunk-lang-go-wjwgay4v.js} +3 -3
  70. package/dist/chunk-lang-html-07d47es4.js +1 -0
  71. package/dist/chunk-lang-javascript-fmhhgzwd.js +1 -0
  72. package/dist/{chunk-lang-json-5eaarz7j.js → chunk-lang-json-7gd89mvs.js} +1 -1
  73. package/dist/chunk-lang-markdown-b6qbe8bt.js +6 -0
  74. package/dist/{chunk-lang-python-fjw84w10.js → chunk-lang-python-3v56y31b.js} +2 -2
  75. package/dist/{chunk-lang-rust-5rbp2zdk.js → chunk-lang-rust-kh0z74d1.js} +1 -1
  76. package/dist/{chunk-lang-shell-vzagpym3.js → chunk-lang-shell-9zv0zvbx.js} +1 -1
  77. package/dist/{chunk-lang-sql-0c2w9c2y.js → chunk-lang-sql-yw6bf3t7.js} +2 -2
  78. package/dist/{chunk-lang-toml-yr9fv6eb.js → chunk-lang-toml-tg1r96nq.js} +1 -1
  79. package/dist/chunk-lang-typescript-etjjvr2g.js +1 -0
  80. package/dist/{chunk-lang-xml-eze08p42.js → chunk-lang-xml-ev1mndd4.js} +1 -1
  81. package/dist/{chunk-lang-yaml-c4b6ft3y.js → chunk-lang-yaml-fz5qpb3r.js} +1 -1
  82. package/dist/chunk-layout-actions-48ecgtkg.js +1 -0
  83. package/dist/{chunk-menu-items-jrwxycr1.js → chunk-menu-items-1epy3h0t.js} +2 -2
  84. package/dist/chunk-mode-toggle-fxmfxsa4.js +1 -0
  85. package/dist/chunk-note-row-kd0fy7ee.js +75 -0
  86. package/dist/chunk-notes-yb8f057c.js +1 -0
  87. package/dist/chunk-notice-bell-wr4f1rph.js +1 -0
  88. package/dist/chunk-notices-x07da5bb.js +1 -0
  89. package/dist/chunk-onboarding-csrkbh9z.js +1 -0
  90. package/dist/chunk-overview-avc2d30t.js +1 -0
  91. package/dist/chunk-palette-9nhp95bz.js +1 -0
  92. package/dist/chunk-placement-items-q694dpgk.js +1 -0
  93. package/dist/chunk-profile-6qemf3m7.js +1 -0
  94. package/dist/chunk-prompt-history-7enzp2p3.js +1 -0
  95. package/dist/chunk-prompts-nv6mrn0q.js +1 -0
  96. package/dist/chunk-room-confirms-zz7n61y7.js +1 -0
  97. package/dist/chunk-room-menu-rr6nzap1.js +1 -0
  98. package/dist/chunk-rooms-menu-button-zbtwj47d.js +1 -0
  99. package/dist/chunk-schedules-rw57nr0m.js +1 -0
  100. package/dist/{chunk-seat-menu-jv4s7hmj.js → chunk-seat-menu-ys5v9abz.js} +1 -1
  101. package/dist/chunk-sheet-hosts-jhvaacst.js +1 -0
  102. package/dist/chunk-skill-editor-sz8an8qr.js +8 -0
  103. package/dist/chunk-skills-tnr1h16h.js +1 -0
  104. package/dist/chunk-switcher-list-17enhrse.js +1 -0
  105. package/dist/chunk-tab-dot-r6brdbmw.js +1 -0
  106. package/dist/chunk-table-r12cja6p.js +1 -0
  107. package/dist/chunk-table-seats-g3t392zz.js +1 -0
  108. package/dist/{chunk-table2d-4sje1fr0.js → chunk-table2d-p3ezsdcj.js} +1 -1
  109. package/dist/{chunk-table3d-h64skazp.js → chunk-table3d-4x2n2b00.js} +23 -23
  110. package/dist/chunk-thread-actions-qc6ezkha.js +1 -0
  111. package/dist/chunk-transcript-n2s6dher.js +1 -0
  112. package/dist/chunk-where-f3scdydc.js +1 -0
  113. package/dist/chunk-workspace-xs023bxm.js +1 -0
  114. package/dist/chunk-zh-tw-efvmk3fd.js +1 -0
  115. package/dist/index.html +1 -1
  116. package/dist/sw.js +1 -1
  117. package/package.json +5 -4
  118. package/src/api-types.ts +356 -4
  119. package/src/app/app.ts +201 -32
  120. package/src/app/desk.ts +47 -22
  121. package/src/app/files.ts +73 -7
  122. package/src/app/presence.ts +2 -2
  123. package/src/app/protocol.ts +63 -1
  124. package/src/app/room-log.ts +153 -14
  125. package/src/app/rooms.ts +39 -0
  126. package/src/app/routes.ts +168 -28
  127. package/src/app/socket.ts +349 -81
  128. package/src/app/sockets.ts +108 -20
  129. package/src/app/surface.ts +72 -36
  130. package/src/app/threads.ts +31 -2
  131. package/src/app/uploads.ts +33 -7
  132. package/src/auth/authenticator.ts +77 -8
  133. package/src/auth/login-page.ts +4 -2
  134. package/src/auth/next.ts +52 -0
  135. package/src/auth/oidc-pages.ts +62 -0
  136. package/src/auth/oidc.ts +649 -0
  137. package/src/auth/sessions.ts +193 -0
  138. package/src/authz.ts +173 -0
  139. package/src/console-api.ts +122 -25
  140. package/src/console-server.ts +102 -12
  141. package/src/gate.ts +90 -0
  142. package/src/host/access.ts +161 -0
  143. package/src/host/cards.ts +112 -0
  144. package/src/host/context.ts +188 -0
  145. package/src/host/forms.ts +240 -0
  146. package/src/host/frames.ts +349 -0
  147. package/src/host/host-app.ts +178 -0
  148. package/src/host/host-context.ts +49 -0
  149. package/src/host/host-routes.ts +396 -0
  150. package/src/host/pages.ts +266 -0
  151. package/src/host/reads.ts +155 -0
  152. package/src/host/retention.ts +41 -0
  153. package/src/host/room-views.ts +137 -0
  154. package/src/host/rooms-service.ts +429 -0
  155. package/src/host/stored-json.ts +13 -0
  156. package/src/host/views.ts +106 -0
  157. package/src/i18n/zh-tw.ts +139 -0
  158. package/src/index.ts +15 -1
  159. package/src/notices/api.ts +43 -0
  160. package/src/notices/mount.ts +292 -0
  161. package/src/notices/service.ts +294 -0
  162. package/src/notices/store.ts +298 -0
  163. package/src/notices/urls.ts +38 -0
  164. package/src/onboarding/api.ts +32 -0
  165. package/src/onboarding/service.ts +149 -0
  166. package/src/onboarding/steps.ts +75 -0
  167. package/src/onboarding/waivers.ts +40 -0
  168. package/src/options.ts +534 -34
  169. package/src/page-presentation.ts +47 -2
  170. package/src/profile/api.ts +175 -0
  171. package/src/profile/links.ts +162 -0
  172. package/src/push/api.ts +189 -52
  173. package/src/push/dispatch.ts +156 -0
  174. package/src/push/drain.ts +139 -0
  175. package/src/push/outbox.ts +218 -0
  176. package/src/push/prefs.ts +118 -0
  177. package/src/push/sender.ts +7 -2
  178. package/src/push/triggers.ts +56 -5
  179. package/src/push/vapid.ts +19 -0
  180. package/src/push/web-push-transport.ts +106 -0
  181. package/src/push-sender/index.ts +14 -0
  182. package/src/push-sender/run.ts +118 -0
  183. package/src/push-sender/session.ts +54 -0
  184. package/src/pwa.ts +32 -4
  185. package/src/visitors.ts +94 -6
  186. package/src/web-app.ts +718 -0
  187. package/src/web-plugin.ts +279 -26
  188. package/dist/chunk-action-menu-qe839g4b.js +0 -1
  189. package/dist/chunk-arranged-rooms-enpfswmg.js +0 -1
  190. package/dist/chunk-character-creator-6yf29xwx.js +0 -1
  191. package/dist/chunk-codeeditor-gdbdg7rp.js +0 -2
  192. package/dist/chunk-confirm-xrw7d732.js +0 -1
  193. package/dist/chunk-conversations-ry228aes.js +0 -1
  194. package/dist/chunk-folder-list-5cp8stna.js +0 -1
  195. package/dist/chunk-folds-hff104tk.js +0 -1
  196. package/dist/chunk-group-scene-h228jdat.js +0 -1
  197. package/dist/chunk-index-0p5h2kdz.js +0 -2
  198. package/dist/chunk-index-0pt08yd9.js +0 -1
  199. package/dist/chunk-index-12bw9yj8.js +0 -2
  200. package/dist/chunk-index-2ad17eh4.js +0 -2
  201. package/dist/chunk-index-31wh5twj.js +0 -52
  202. package/dist/chunk-index-4dy94pbz.js +0 -2
  203. package/dist/chunk-index-4ecjtdy8.js +0 -13
  204. package/dist/chunk-index-4v1b7ks9.js +0 -2
  205. package/dist/chunk-index-5d8yjj4m.js +0 -2
  206. package/dist/chunk-index-89ajmxh7.js +0 -2
  207. package/dist/chunk-index-b9ny4623.js +0 -2
  208. package/dist/chunk-index-e1dr6g10.js +0 -2
  209. package/dist/chunk-index-gpkzhq1g.js +0 -2
  210. package/dist/chunk-index-hk3xyy20.js +0 -2
  211. package/dist/chunk-index-jm23vn03.js +0 -4
  212. package/dist/chunk-index-k7gh0jvz.js +0 -2
  213. package/dist/chunk-index-ky42ev0b.js +0 -2
  214. package/dist/chunk-index-pa2yyqh0.js +0 -2
  215. package/dist/chunk-index-pcvt668q.js +0 -2
  216. package/dist/chunk-index-pqw27eye.js +0 -1
  217. package/dist/chunk-index-wmbmmrd4.js +0 -302
  218. package/dist/chunk-index-ymbjrsp6.js +0 -2
  219. package/dist/chunk-lang-css-t85r8rz0.js +0 -1
  220. package/dist/chunk-lang-html-n6jparge.js +0 -1
  221. package/dist/chunk-lang-javascript-xj00cp97.js +0 -1
  222. package/dist/chunk-lang-markdown-zxx8eke8.js +0 -6
  223. package/dist/chunk-lang-typescript-8f6yywt3.js +0 -1
  224. package/dist/chunk-layout-actions-bv0chj41.js +0 -1
  225. package/dist/chunk-notes-9b7pgqfe.js +0 -1
  226. package/dist/chunk-overview-8yw71esz.js +0 -1
  227. package/dist/chunk-palette-frms7axe.js +0 -1
  228. package/dist/chunk-placement-items-fvfy9m0y.js +0 -1
  229. package/dist/chunk-prompt-history-yrqehads.js +0 -1
  230. package/dist/chunk-prompts-g6609tqx.js +0 -1
  231. package/dist/chunk-room-confirms-0a2y0925.js +0 -1
  232. package/dist/chunk-room-menu-g11q97br.js +0 -1
  233. package/dist/chunk-rooms-menu-button-h9qge48n.js +0 -1
  234. package/dist/chunk-schedules-ezmacrbj.js +0 -1
  235. package/dist/chunk-sheet-hosts-b0azyfhb.js +0 -1
  236. package/dist/chunk-skill-editor-h6k6whwg.js +0 -8
  237. package/dist/chunk-skills-gqcfhq56.js +0 -1
  238. package/dist/chunk-switcher-list-mcpamqnj.js +0 -1
  239. package/dist/chunk-table-s8cde1xz.js +0 -1
  240. package/dist/chunk-table-seats-wqkjn8bc.js +0 -1
  241. package/dist/chunk-transcript-c59c6mpm.js +0 -1
  242. package/dist/chunk-workspace-0cyspkk4.js +0 -1
  243. package/dist/chunk-zh-tw-nc93jm10.js +0 -1
package/src/api-types.ts CHANGED
@@ -16,9 +16,24 @@ export const PANES = [
16
16
  "schedules",
17
17
  "table",
18
18
  "workspace",
19
+ "profile",
19
20
  ] as const;
20
21
  export type PaneName = (typeof PANES)[number];
21
22
 
23
+ /**
24
+ * The panes only an owner is served: they show the whole host, which a member's view never does.
25
+ * The table is not among them: for a member it seats only the host rooms they may list.
26
+ */
27
+ export const OWNER_ONLY_PANES = [
28
+ "overview",
29
+ "skills",
30
+ "connectors",
31
+ "workspace",
32
+ ] as const satisfies readonly PaneName[];
33
+
34
+ /** A person's tier in the app, as `IDENTITY` gives it. */
35
+ export type AppTier = "owner" | "admin" | "member";
36
+
22
37
  /** What the page needs before it can draw anything. */
23
38
  export interface ConfigView {
24
39
  title: string;
@@ -41,7 +56,82 @@ export interface ConfigView {
41
56
  surface: string;
42
57
  /** The WebSocket subprotocol to offer. */
43
58
  protocol: string;
59
+ /** False when the host leaves the yolo and long-running switches out (`modes: false`). */
60
+ modes?: false;
44
61
  };
62
+ /** The visitor's tier. Sent only where the host admits more than its owners (`admission: "access"`). */
63
+ tier?: AppTier;
64
+ /** The steps still undone before the app opens; present only while the gate is closed. */
65
+ gate?: GateStepView[];
66
+ /** The host's pages that are not rooms, as far as this visitor may see them. */
67
+ pages?: PageLinkView[];
68
+ /** The kinds of host room this visitor may list. */
69
+ kinds?: KindLinkView[];
70
+ /** Web Push for this visitor's tier: who may subscribe, and (for an external sender) where. */
71
+ push?: { tiers: AppTier[]; key?: string; subscribe?: string };
72
+ }
73
+
74
+ /** A step of onboarding the visitor still owes. */
75
+ export interface GateStepView {
76
+ id: string;
77
+ label: string;
78
+ help?: string;
79
+ /**
80
+ * Set on the steps the app makes itself, so the page words them in its own language: `link`
81
+ * for `link:<provider>` (with the account's label in `label`), `push` for the notifications step.
82
+ */
83
+ builtin?: "link" | "push";
84
+ /** A required step gates the app; a nudge is shown and never gates. */
85
+ required: boolean;
86
+ /** The page where the person completes it. */
87
+ open: { page: string };
88
+ /** The person may waive it; the label and the confirmation are what they are shown. */
89
+ waiver?: { label: string; confirm: string };
90
+ }
91
+
92
+ /**
93
+ * The icons a host may give a page or a kind of room: names from the console's own icon set. A
94
+ * name outside the list, or none, shows the default (a list for a page, no icon for a kind).
95
+ */
96
+ export const HOST_ICONS = [
97
+ "chat",
98
+ "link",
99
+ "activity",
100
+ "users",
101
+ "megaphone",
102
+ "qr",
103
+ "settings",
104
+ "bell",
105
+ "file",
106
+ "list",
107
+ "shield",
108
+ "lock",
109
+ "sparkle",
110
+ ] as const;
111
+ export type HostIconName = (typeof HOST_ICONS)[number];
112
+
113
+ /**
114
+ * How a kind of host room words its two ways to write: `turn` is talking to the agent (the toggle's
115
+ * label, and the box's hint while it is on), `note` is a message for the room's people only.
116
+ */
117
+ export interface SendWording {
118
+ note?: { placeholder?: string };
119
+ turn?: { label?: string; placeholder?: string };
120
+ }
121
+
122
+ /** A host page that is not a room, in the places the shell lists it. */
123
+ export interface PageLinkView {
124
+ id: string;
125
+ label: string;
126
+ place: "main" | "settings" | "hidden";
127
+ icon?: HostIconName;
128
+ }
129
+
130
+ /** A kind of host room, listed by its label. */
131
+ export interface KindLinkView {
132
+ kind: string;
133
+ label: string;
134
+ icon?: HostIconName;
45
135
  }
46
136
 
47
137
  export type ChannelName =
@@ -300,6 +390,101 @@ export interface RoomMessage {
300
390
  /** ISO time. */
301
391
  at: string;
302
392
  live?: string;
393
+ /**
394
+ * Host rooms: what kind of author wrote it (`external` text is untrusted and shown as plain
395
+ * text) and the label the host gives that kind, such as "Customer". Absent on the app's own.
396
+ */
397
+ authorKind?: HostAuthorKind;
398
+ authorLabel?: string;
399
+ /** Host rooms: the author's picture, never an outside URL. */
400
+ picture?: PictureRef;
401
+ /** The text was changed after it was stored. */
402
+ edited?: true;
403
+ /**
404
+ * An internal note: written for the humans who read the room, never handed to the agent. Only
405
+ * an `owner` message of an agent or group room that has `notes` can be one.
406
+ */
407
+ note?: true;
408
+ /** Files of the message that were deleted by retention. */
409
+ expiredFiles?: number;
410
+ }
411
+
412
+ /** The kinds of author a host room's messages come from. */
413
+ export type HostAuthorKind = "external" | "member" | "assistant" | "notice";
414
+
415
+ /** A picture the page may draw: a stored file, a person's picture, or initials; never an outside URL. */
416
+ export type PictureRef =
417
+ | { file: string }
418
+ | { principal: string }
419
+ | { initials: string; color: string };
420
+
421
+ /** A button a host card or header offers, and the form it opens first. */
422
+ export interface HostActionView {
423
+ id: string;
424
+ label: string;
425
+ style?: "primary" | "secondary" | "danger";
426
+ confirm?: string;
427
+ form?: FormSpecView;
428
+ }
429
+
430
+ export interface FormSpecView {
431
+ title: string;
432
+ submit: string;
433
+ fields: FormFieldView[];
434
+ }
435
+
436
+ export type FormFieldView =
437
+ | {
438
+ name: string;
439
+ label: string;
440
+ type: "text" | "textarea" | "url";
441
+ required?: boolean;
442
+ max?: number;
443
+ initial?: string;
444
+ hint?: string;
445
+ }
446
+ | {
447
+ name: string;
448
+ label: string;
449
+ type: "select" | "multiselect";
450
+ required?: boolean;
451
+ options: { value: string; label: string }[];
452
+ /** The value or values chosen when the form opens; a `select` takes one. */
453
+ initial?: string | readonly string[];
454
+ /** The page offers a filter box over the options, for a long list. */
455
+ search?: boolean;
456
+ };
457
+
458
+ /** A card a host puts in its room; its buttons call the host's `act`. */
459
+ export interface HostCardView {
460
+ id: string;
461
+ room: string;
462
+ title: string;
463
+ body: string;
464
+ tone?: "note" | "ok" | "warn" | "risk";
465
+ state?: "open" | "working" | "done" | "superseded" | "expired";
466
+ links?: { label: string; url: string }[];
467
+ /** Only the buttons this viewer may press. */
468
+ buttons?: HostActionView[];
469
+ /** ISO times. */
470
+ at: string;
471
+ updatedAt: string;
472
+ }
473
+
474
+ /** A person-addressed notice, as the bell shows it. */
475
+ export interface NoticeView {
476
+ tag: string;
477
+ title: string;
478
+ body?: string;
479
+ open?:
480
+ | { room: string; message?: number }
481
+ | { page: string; query?: Record<string, string> };
482
+ urgency: "normal" | "high";
483
+ ackable: boolean;
484
+ /** ISO time. */
485
+ raisedAt: string;
486
+ /** This person has handled it. */
487
+ acked?: true;
303
488
  }
304
489
 
305
490
  /** One entry of the room list. */
@@ -324,6 +509,12 @@ export interface RoomView {
324
509
  parent?: string;
325
510
  /** A thread's room takes no messages from the page. */
326
511
  readOnly: boolean;
512
+ /**
513
+ * More than one person reads this agent or group room, so the composer offers `@AI` off: a
514
+ * message sent with `mode: "note"` is kept for them and not given to the agent. Absent in a
515
+ * room only one person reads.
516
+ */
517
+ notes?: true;
327
518
  /** A thread whose dispatch has ended; its room stays readable. */
328
519
  closed?: boolean;
329
520
  mode: RoomMode;
@@ -339,6 +530,18 @@ export interface RoomView {
339
530
  stoppable: boolean;
340
531
  /** The newest stored message, if any. */
341
532
  last?: RoomMessage;
533
+ /** Messages past this person's read cursor; absent when none. */
534
+ unread?: number;
535
+ }
536
+
537
+ /** Where one person has read a room up to, with the name the page shows for them. */
538
+ export interface ReadMarkView {
539
+ principal: string;
540
+ name: string;
541
+ /** The id of the newest message they have read. */
542
+ upTo: number;
543
+ /** ISO time. */
544
+ at: string;
342
545
  }
343
546
 
344
547
  /** An owner-made folder of rooms, with its rooms in the owner's order. */
@@ -360,6 +563,16 @@ export interface LayoutView {
360
563
  folders: FolderView[];
361
564
  }
362
565
 
566
+ /** `GET api/rooms/<key>` for a thread: its view, listed or dismissed from the list. */
567
+ export interface RoomOneView {
568
+ room: RoomView;
569
+ }
570
+
571
+ /** What a dismissal removed from the room list: the finished threads that were listed. */
572
+ export interface ThreadsDismissed {
573
+ dismissed: number;
574
+ }
575
+
363
576
  export interface RoomsView extends LayoutView {
364
577
  rooms: RoomView[];
365
578
  }
@@ -375,14 +588,22 @@ export interface MessagesView {
375
588
  * first; the page places each among the messages by `frame.at`.
376
589
  */
377
590
  cards: ClosedCard[];
591
+ /** The other readers' cursors: how far each has read the room (the viewer's own is `cursor`). */
592
+ reads?: ReadMarkView[];
593
+ /** The viewer's own read cursor before they opened the room; absent when they never read it. */
594
+ cursor?: number;
378
595
  }
379
596
 
380
597
  /** Who the page is signed in as. */
381
598
  export interface SessionView {
382
599
  principal: PrincipalName;
383
600
  surface: string;
384
- /** How the console signs the person in; the page offers Log out under `password`. */
385
- auth: "none" | "password" | "verifier";
601
+ /** How the console signs the person in; the page offers Log out under `password` and `oidc`. */
602
+ auth: "none" | "password" | "verifier" | "oidc";
603
+ /** The visitor's tier. Sent only where the host admits more than its owners (`admission: "access"`). */
604
+ tier?: AppTier;
605
+ /** The steps still undone before the app opens; present only while the gate is closed. */
606
+ gate?: GateStepView[];
386
607
  /** When the credential lapses, if it does. */
387
608
  expiresAt?: string;
388
609
  /** Web Push is available: the app serves the rooms and a key for it. */
@@ -419,6 +640,85 @@ export interface PushDevicesView {
419
640
  devices: PushDeviceView[];
420
641
  }
421
642
 
643
+ /** A test push was queued; the device's receipt for `tag` completes the push step. */
644
+ export interface PushTestView {
645
+ tag: string;
646
+ }
647
+
648
+ /** The person's own push preferences. */
649
+ export interface PushPrefsView {
650
+ /** No push for a normal notice from `start` to `end` on the clock of `timeZone`; absent = none set. */
651
+ quiet?: { start: string; end: string; timeZone: string };
652
+ }
653
+
654
+ /** The person's notices that are not resolved, newest first, and the count the app icon shows. */
655
+ export interface NoticesView {
656
+ notices: NoticeView[];
657
+ badge: number;
658
+ }
659
+
660
+ /** One account the person may link, as the profile page shows it. */
661
+ export interface LinkView {
662
+ provider: string;
663
+ label: string;
664
+ /** What linking it is for this deployment: `required` gates the app, `nudge` asks; absent = optional. */
665
+ step?: "required" | "nudge";
666
+ /** Providers to link first, and those of them not linked yet (`issue` is refused until none is left). */
667
+ requires: string[];
668
+ blockedBy: string[];
669
+ linked?: {
670
+ displayName?: string;
671
+ /** ISO time. */
672
+ linkedAt: string;
673
+ /** The configuration or the CLI made the link, so it cannot be removed here. */
674
+ locked?: true;
675
+ };
676
+ pending?: {
677
+ request: string;
678
+ /** ISO time. */
679
+ expiresAt: string;
680
+ redeemedBy?: { displayName: string; picture?: PictureRef };
681
+ };
682
+ }
683
+
684
+ export interface LinksView {
685
+ links: LinkView[];
686
+ }
687
+
688
+ /** The code a person puts into the other service to prove an account. */
689
+ export interface LinkIssuedView {
690
+ code: string;
691
+ request: string;
692
+ /** ISO time. */
693
+ expiresAt: string;
694
+ instructions: string;
695
+ }
696
+
697
+ /** How the person is shown, and which of their accounts they may pick to show. */
698
+ export interface ProfileView {
699
+ name: string;
700
+ /** The account the name comes from; absent when it is the person's own name. */
701
+ source?: string;
702
+ /** A picture is served at `api/people/<principal>/picture`. */
703
+ picture: boolean;
704
+ principal: string;
705
+ tier?: AppTier;
706
+ /** The accounts the person linked that can name them; the page shows these as the choice. */
707
+ sources: { provider: string; label: string }[];
708
+ }
709
+
710
+ /** A step of onboarding as the page of steps shows it. */
711
+ export interface OnboardingStepView extends GateStepView {
712
+ done: boolean;
713
+ waived: boolean;
714
+ }
715
+
716
+ export interface OnboardingView {
717
+ steps: OnboardingStepView[];
718
+ /** Push on the person's devices: how many are subscribed and when one last reported back. */
719
+ push: { devices: number; lastReceiptAt?: string; waived: boolean };
720
+ }
721
+
422
722
  /** A schedule, labelled by the room it belongs to or else its channel. */
423
723
  export interface ScheduleView {
424
724
  id: number;
@@ -799,7 +1099,12 @@ export type RefusalCode =
799
1099
  | "unknown_upload"
800
1100
  | "empty"
801
1101
  | "too_long"
802
- | "not_accepted";
1102
+ | "not_accepted"
1103
+ /** A required onboarding step stands undone, so the frame is not taken yet. */
1104
+ | "gated";
1105
+
1106
+ /** The values of a form a host action opened. */
1107
+ export type FormInput = Readonly<Record<string, string | readonly string[]>>;
803
1108
 
804
1109
  /** What the page sends: one JSON object per WebSocket text message. */
805
1110
  export type ClientFrame =
@@ -816,8 +1121,27 @@ export type ClientFrame =
816
1121
  text: string;
817
1122
  /** Files uploaded with `POST api/uploads`, by the `id` each returned. */
818
1123
  uploads?: string[];
1124
+ /** Host rooms: a `note` only records, a `turn` is also delivered to the host's claim. Default `turn`. An agent or group room takes a `note` only where its view has `notes`. */
1125
+ mode?: "note" | "turn";
819
1126
  }
820
1127
  | { type: "stop"; room: string }
1128
+ /** Host rooms: follow a room's frames. At most 200 at once; the viewer must be able to read it. */
1129
+ | { type: "subscribe"; room: string }
1130
+ | { type: "unsubscribe"; room: string }
1131
+ /** A host room's or page's action: a card's button, a header action, a form. */
1132
+ | {
1133
+ type: "act";
1134
+ id: string;
1135
+ room?: string;
1136
+ page?: string;
1137
+ action: string;
1138
+ card?: string;
1139
+ input?: FormInput;
1140
+ }
1141
+ /** The person handled a notice. */
1142
+ | { type: "ack"; tag: string }
1143
+ /** The person has read a room up to this message (a cursor never moves back). */
1144
+ | { type: "read"; room: string; upTo: number }
821
1145
  | { type: "approval"; prompt: string; approved: boolean }
822
1146
  | { type: "answer"; prompt: string; answer: PromptAnswer }
823
1147
  | {
@@ -839,6 +1163,8 @@ export type ServerFrame =
839
1163
  name: string;
840
1164
  /** The most files one message carries and the most bytes of one. */
841
1165
  uploads: { perMessage: number; maxBytes: number };
1166
+ /** The required steps the person still owes, when there are any: the socket then carries only the gate and their notices. */
1167
+ gate?: GateStepView[];
842
1168
  }
843
1169
  /** The message `id` was taken into `room`; `message` is how it was stored. */
844
1170
  | { type: "accepted"; id: string; room: string; message: RoomMessage }
@@ -882,7 +1208,33 @@ export type ServerFrame =
882
1208
  /** Yolo mode approved a held call by itself. */
883
1209
  | { type: "auto_approved"; room: string; tool: string; action: string }
884
1210
  /** The team or the room list may differ: refetch. */
885
- | { type: "changed" };
1211
+ | { type: "changed" }
1212
+ /** A host room's message, edit or removal, and its cards; sent to the sockets subscribed to the room. */
1213
+ | { type: "host_message"; room: string; message: RoomMessage }
1214
+ | { type: "host_edited"; room: string; message: RoomMessage }
1215
+ | { type: "host_removed"; room: string; id: number }
1216
+ | { type: "host_card"; room: string; card: HostCardView }
1217
+ /** A host room's header or access may differ: refetch it. */
1218
+ | { type: "room_changed"; room: string }
1219
+ /** The list of a kind of host room may differ: refetch it. */
1220
+ | { type: "list_changed"; kind: string }
1221
+ | { type: "page_changed"; page: string }
1222
+ | { type: "notice"; notice: NoticeView }
1223
+ | { type: "notice_resolved"; tag: string }
1224
+ /** The count the app icon shows: notices not handled. */
1225
+ | { type: "badge"; count: number }
1226
+ /** The steps still undone; empty when the gate opened. */
1227
+ | { type: "gate"; steps: GateStepView[] }
1228
+ /** Someone read a room up to a message; `name` and `at` let the page show them without asking. */
1229
+ | {
1230
+ type: "read";
1231
+ room: string;
1232
+ principal: string;
1233
+ name: string;
1234
+ upTo: number;
1235
+ /** ISO time. */
1236
+ at: string;
1237
+ };
886
1238
 
887
1239
  /** A turn's live view, as the core reports it. */
888
1240
  export type AppProgress =