@oar-sh/oar 0.9.14 → 0.9.16

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 (59) hide show
  1. package/CHANGELOG.md +179 -0
  2. package/README.md +9 -9
  3. package/bin/oar.js +525 -12
  4. package/package.json +3 -1
  5. package/server/claude-worker/claude-remote-relay-tool.mjs +36 -1
  6. package/server/claude-worker/claude-session-process.mjs +4 -4
  7. package/server/copilot-worker/copilot-sdk-session-process.mjs +2 -2
  8. package/server/db-schema.mjs +52 -0
  9. package/server/migrations/0019-relay-event-subscription-options.mjs +106 -0
  10. package/server/migrations/0020-conversation-may-create-sessions.mjs +67 -0
  11. package/server/migrations/0021-conversation-group-agent-marks.mjs +77 -0
  12. package/server/migrations/0022-relay-schedules.mjs +142 -0
  13. package/server/migrations/0023-relay-asks.mjs +141 -0
  14. package/server/public/app/ask-user-view.js +3 -0
  15. package/server/public/app/bootstrap.js +61 -3
  16. package/server/public/app/context-usage-view.mjs +17 -0
  17. package/server/public/app/conversation-group-order.mjs +35 -0
  18. package/server/public/app/inbox-ui.js +356 -0
  19. package/server/public/app/inbox-view.mjs +370 -0
  20. package/server/public/app/journal-view.js +23 -2
  21. package/server/public/app/relay-event-subscriptions-ui.js +4 -2
  22. package/server/public/app/relay-event-view.mjs +33 -7
  23. package/server/public/app/relay-schedule-view.mjs +119 -0
  24. package/server/public/app/relay-schedules-ui.js +172 -0
  25. package/server/public/app/settings-modal.js +17 -3
  26. package/server/public/app/socket-handlers.js +27 -3
  27. package/server/public/app/store.js +18 -5
  28. package/server/public/index.html +159 -2
  29. package/server/relay-tools.md +18 -3
  30. package/server/repositories/conversation-group-repository.mjs +97 -11
  31. package/server/repositories/remote-relay-repository.mjs +20 -2
  32. package/server/repositories/session-repository.mjs +7 -1
  33. package/server/routes/ask-user-routes.mjs +57 -3
  34. package/server/routes/cache-routes.mjs +6 -0
  35. package/server/routes/conversation-group-routes.mjs +17 -2
  36. package/server/routes/messages-routes.mjs +3 -3
  37. package/server/routes/relay-ask-routes.mjs +387 -0
  38. package/server/routes/relay-event-routes.mjs +3 -1
  39. package/server/routes/relay-schedule-routes.mjs +57 -0
  40. package/server/routes/sessions-routes.mjs +613 -56
  41. package/server/server-runtime.mjs +80 -1
  42. package/server/services/cache-rebuild-service.mjs +19 -2
  43. package/server/services/conversation-preferences-service.mjs +17 -0
  44. package/server/services/oar-cli-helpers.mjs +12 -4
  45. package/server/services/relay-ask-link-service.mjs +174 -0
  46. package/server/services/relay-ask-service.mjs +604 -0
  47. package/server/services/relay-event-service.mjs +589 -73
  48. package/server/services/relay-schedule-service.mjs +596 -0
  49. package/server/services/remote-relay-caller-context.mjs +89 -20
  50. package/server/services/remote-relay-dispatcher.mjs +956 -30
  51. package/server/services/windows-autostart-service.mjs +88 -16
  52. package/server/services/windows-boot-autostart-service.mjs +775 -126
  53. package/shared/relay-asks.mjs +145 -0
  54. package/shared/relay-events.mjs +268 -18
  55. package/shared/relay-schedules.mjs +128 -0
  56. package/shared/remote-relay-contract.mjs +553 -25
  57. package/shared/remote-relay-tool-core.mjs +16 -5
  58. package/.github/extensions/web-relay/README.md +0 -190
  59. package/server/README.md +0 -2334
package/CHANGELOG.md CHANGED
@@ -3,6 +3,185 @@
3
3
  All notable changes to OAR are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow semver.
5
5
 
6
+ ## [0.9.16] — 2026-10-24
7
+
8
+ Highlights: agents can file the sessions they start into your session
9
+ groups, change another session's model, mode or other settings, watch other
10
+ sessions with fewer wake-ups (digests, quiet hours, exclusions), and
11
+ schedule prompts that survive a relay restart. Agents can ask you a question
12
+ without stopping their work, and the new Inbox lists every open question
13
+ from this relay and its paired relays in one place. A new switch lets the
14
+ agents of a conversation start sessions themselves.
15
+
16
+ ### Added
17
+
18
+ - **Agents can put a new session into an existing session group.**
19
+ `remote_relay` create_session takes `group` (a group id, or its name in
20
+ any case) on this relay or a paired one, and `relay_info` lists the groups
21
+ there. An unknown group is refused with the groups listed, and nothing is
22
+ created. The approval card names the group, and the result carries it. A
23
+ relay too old for this is refused before anything is created. Renaming
24
+ and rearranging groups stays the owner's. An argument an action does not
25
+ take is no longer dropped without a word: create_session refuses it, and
26
+ the other actions list it in `ignored`.
27
+ - **Agents can change another session's settings.** `remote_relay`
28
+ update_session sets a session's model, reasoning effort, relay mode,
29
+ auto-compact window, title, group, thinking or working folder for its next
30
+ turns, on this relay or a paired one, and answers the settings and what
31
+ changed. An unknown model is refused with the close matches; a group name
32
+ that does not exist makes a new group, and `none` takes the session out (a
33
+ group you made is never removed this way: it stays, shown empty in the
34
+ sidebar for you to rename or dissolve); a new folder
35
+ restarts the session's CLI there and is refused while it works. Only a
36
+ session the agent's own conversation started may be changed freely; any
37
+ other, yours or another agent's, needs your Allow once per conversation and
38
+ relay. A failed change still lists what it wrote. An open page shows the
39
+ change at once.
40
+ - **"Agents in this conversation may start sessions."** A switch in the 🧠
41
+ settings of a session an agent started lets its agents start sessions
42
+ themselves, past the one-level rule; the limit of four at work and your
43
+ first Allow still apply. Only you can set it: agents and paired relays are
44
+ refused.
45
+ - **Fewer wake-ups for watching agents.** A `remote_relay` subscription takes
46
+ `digest_minutes` (its events come as one message every N minutes),
47
+ `quiet_hours` (a daily window in a time zone, crossing midnight and the
48
+ clock changes included, whose events come as one message when it ends) and
49
+ `exclude` (sessions a subscription to all leaves out). Questions and errors
50
+ still come at once, held events survive a restart, and the hourly limit
51
+ stays on top. A turn the watcher prompted itself and whose finished reply it
52
+ waited for no longer wakes it a second time with turn_end.
53
+ `list_subscriptions` shows how many events each subscription holds and when
54
+ they are due, and the watching chip shows a small digest or quiet-hours hint.
55
+ - **Scheduled prompts that survive a restart.** `remote_relay` schedule
56
+ queues a prompt at a time (`at`) or every N minutes (`every_minutes`, 5 to
57
+ 10080), into the agent's own conversation or, with the user's approval in
58
+ ask and plan mode, another session on this relay. The relay keeps it in its
59
+ database, so a nightly review or a sweep no longer has to be set up again
60
+ after a deploy. A time missed while the relay was down fires once when it is
61
+ back, and a repeat waits while the one before is still queued. The message
62
+ says it is automated and approves nothing. `list_schedules` and `unschedule`
63
+ manage them, archiving a session ends its schedules, and a conversation
64
+ holds at most 20. The sidebar marks a scheduled session, and its header
65
+ lists the schedules with a Cancel button each.
66
+ - **Questions that don't block, and the Inbox.** `remote_relay` ask puts a
67
+ question for you into the agent's session (up to eight options, a
68
+ recommendation, a folded detail, and urgency `now` for a push) and returns
69
+ at once, so the agent goes on with what does not depend on it. Your answer
70
+ or dismissal reaches it as a relay event, question_answered, without a
71
+ subscription, and does not count as your message for the agents' loop
72
+ guard. A lead can ask on behalf of another session, on this relay or a
73
+ paired one (kept where that session lives); `list_questions` and `withdraw`
74
+ manage them, and `read_session` lists them with their kind. The new
75
+ **Inbox** in the sidebar, with its count, lists every pending question
76
+ across this relay and the paired relays that answer, grouped by relay,
77
+ with a filter for your sessions or the agents', and what you answered in
78
+ the last day under a divider. An ask is answered there or in its session,
79
+ also one on a paired relay; a paired relay's cards open there, and the
80
+ pairing never carries an answer to a card. Agent text shows as plain text,
81
+ and on a phone the Inbox is one column with full-width buttons.
82
+
83
+ ### Fixed
84
+
85
+ - **The agents' loop guard no longer counts the relay's own messages as the
86
+ user's.** A relay event, the usage-limit follow-up or the note after a
87
+ restart reset the count of prompts an agent may send to other agents
88
+ before the user is asked, so two agents that watched each other could go
89
+ on without the user. Only a message the user wrote resets it now.
90
+
91
+ ## [0.9.15] — 2026-10-22
92
+
93
+ Highlights: `oar setup` asks how the relay starts on Windows, at sign-in or
94
+ at boot before anyone signs in, and `oar autostart` switches between them
95
+ later. `oar uninstall` takes OAR off the machine and keeps your data unless
96
+ you ask for `--purge`. A declined administrator prompt changes nothing, boot
97
+ tasks work in profile folders with spaces or non-ASCII names, and a
98
+ hand-made task, or one only an administrator can read, is never deleted
99
+ without a copy. The package is smaller.
100
+
101
+ ### Upgrade notes
102
+
103
+ - **From 0.9.14 with a hand-made autostart task:** switching to boot mode
104
+ in 0.9.14 could delete an existing task of the same name (`oar-relay` or
105
+ the pre-rebrand name) without a copy. 0.9.15 keeps such a task and asks
106
+ for `--replace`, which saves a copy first.
107
+
108
+ ### Added
109
+
110
+ - **`oar setup` asks how the relay starts** on Windows: at sign-in, at boot
111
+ (before anyone signs in; one administrator prompt) or not at all, with the
112
+ current mode as the default. `--autostart signin|boot|off` answers it
113
+ without a question.
114
+ - **`oar autostart signin|boot|off|status`.** Switching to or from boot mode
115
+ asks for an administrator once, only for the schtasks call; sign-in mode
116
+ needs none. A declined prompt changes nothing. `status` lists each entry,
117
+ whether OAR generated it, and which other OAR install a stale one starts.
118
+ `--replace` replaces hand-made entries with generated ones, keeping a copy
119
+ of each (`<name>.bak`: a launcher's beside it, a task's exported XML and a
120
+ Startup entry's in the OAR folder); nothing else ever does. On Linux it is
121
+ the systemd user service (`oar service`); elsewhere it says it is not
122
+ supported.
123
+ - **`oar uninstall [--purge]`** stops the relay, takes out the autostart
124
+ entries OAR generated and the Copilot extension wrapper OAR wrote for this
125
+ install (a changed one, or one of another install, stays and is named),
126
+ and has npm remove the package once `oar` has ended. **The data stays** (config,
127
+ database, uploads, logs in the state root), and the command says where.
128
+ `--purge` deletes the state root after you type `delete`; a data folder
129
+ outside it, one in a git checkout, and `rescued-package-data` are each
130
+ deleted only after a question of their own; a drive root, the home folder
131
+ or a folder above it, a system folder and a folder without OAR's config or
132
+ database in it are refused, whatever is typed. A relay that holds its lock
133
+ without answering (bringing over a database) stops the command before it
134
+ deletes anything. Programs that still run from the package (session
135
+ workers) are named: npm leaves the files they hold in a hidden `.oar-*`
136
+ folder, which the log names. A step
137
+ that fails stops the command, which says what is done and what is left.
138
+
139
+ ### Changed
140
+
141
+ - The two developer READMEs (`server/README.md` with the HTTP API, and the
142
+ web-relay extension's) are no longer in the npm package; they are on
143
+ [GitHub](https://github.com/oar-sh/oar).
144
+
145
+ ### Fixed
146
+
147
+ - **A hand-made autostart entry is never deleted or written over.** Leaving
148
+ boot mode deleted a boot task or launcher edited by hand, and *Off* also
149
+ a task OAR did not make; switching to sign-in replaced an edited Startup
150
+ entry. Only entries exactly as an OAR version generated them are changed
151
+ now, in the web UI as in `oar autostart`: a hand-made entry that would stay
152
+ beside the new mode, or be replaced by it, stops the switch with the same
153
+ message. Picking *At system startup* no longer replaces a hand-edited
154
+ launcher or a task someone else made, the pre-rebrand one included. A boot
155
+ task is OAR's own only while it is exactly the one OAR registers: the
156
+ account, the run level, one action, one boot trigger and its settings.
157
+ - **Boot mode switches on and off with a space, an apostrophe or non-ASCII
158
+ characters in the profile path.** The elevated step was a script file
159
+ passed unquoted, and read in the wrong encoding; it now travels as an
160
+ encoded command with every path quoted. A failed switch is no longer
161
+ reported as a declined prompt: it puts back the tasks it deleted from their
162
+ copies and keeps the copies, and a declined one leaves no file behind.
163
+ Windows PowerShell can report a declined prompt with an error that does not
164
+ stop it, or with no process at all; that read as confirmed, so leaving boot
165
+ mode deleted the launcher but kept the task, and switching it on removed
166
+ the sign-in entry without registering the task. Both now count as declined.
167
+ Leaving boot mode in the web UI switches the sign-in entry only after the
168
+ prompt was confirmed. Leaving boot mode removes the task XML and the record of
169
+ the sweep too, and the web UI names a Startup entry OAR did not make.
170
+ - **A boot task with non-ASCII characters in its paths reads right.**
171
+ schtasks writes its XML in the console's code page, so a profile path like
172
+ `C:\Users\Jürgen` came back garbled and OAR took its own task for a
173
+ hand-made one: switching boot on reported a failure and deleted the new
174
+ launcher, and *Off* refused to remove the task. Such a task is now read
175
+ again through PowerShell in UTF-8. A task that still cannot be read is
176
+ never taken as missing, removed, put back or someone else's, and never
177
+ deleted without a copy: nothing is changed while it cannot be read, and
178
+ after a confirmed prompt OAR says it could not check, and undoes nothing.
179
+ - **A boot task only an administrator can read is never deleted.** One that
180
+ stores another account's password answers "Access is denied" to OAR; that
181
+ read as no task, so `oar autostart boot` deleted it without a copy. Any
182
+ failed read of a task that is there now counts as unreadable: status says
183
+ so, and OAR changes nothing, `--replace` included.
184
+
6
185
  ## [0.9.14] — 2026-10-21
7
186
 
8
187
  Highlights: a relay started by Windows autostart, or by a plain
package/README.md CHANGED
@@ -45,29 +45,29 @@ flowchart LR
45
45
  <table>
46
46
  <tr>
47
47
  <td width="42%" rowspan="4" valign="top">
48
- <a href="https://oar.sh/assets/shots/cfmail-mobile.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-mobile.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/cfmail-mobile.png?v=0.9.14" alt="OAR on a phone: a finished agent turn in a conversation, with the composer below"></picture></a>
48
+ <a href="https://oar.sh/assets/shots/cfmail-mobile.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-mobile.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/cfmail-mobile.png?v=0.9.16" alt="OAR on a phone: a finished agent turn in a conversation, with the composer below"></picture></a>
49
49
  <br><sub>On a phone: the same conversations, installable as an app.</sub>
50
50
  </td>
51
51
  <td width="58%" valign="top">
52
- <a href="https://oar.sh/assets/shots/cfmail-agents.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-agents.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/cfmail-agents.png?v=0.9.14" alt="Background subagents running in parallel in the task panel, each with live token counts, elapsed time, and its own Stop button"></picture></a>
52
+ <a href="https://oar.sh/assets/shots/cfmail-agents.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-agents.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/cfmail-agents.png?v=0.9.16" alt="Background subagents running in parallel in the task panel, each with live token counts, elapsed time, and its own Stop button"></picture></a>
53
53
  <br><sub>Agents working in parallel, each with live token counts and its own Stop.</sub>
54
54
  </td>
55
55
  </tr>
56
56
  <tr>
57
57
  <td valign="top">
58
- <a href="https://oar.sh/assets/shots/cfmail-question.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-question.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/cfmail-question.png?v=0.9.14" alt="A question card in the middle of a turn: the agent offers several choices and a free-text reply"></picture></a>
58
+ <a href="https://oar.sh/assets/shots/cfmail-question.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-question.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/cfmail-question.png?v=0.9.16" alt="A question card in the middle of a turn: the agent offers several choices and a free-text reply"></picture></a>
59
59
  <br><sub>When the agent needs a decision, it asks, and waits for your answer.</sub>
60
60
  </td>
61
61
  </tr>
62
62
  <tr>
63
63
  <td valign="top">
64
- <a href="https://oar.sh/assets/shots/pingcf-thoughts.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/pingcf-thoughts.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/pingcf-thoughts.png?v=0.9.14" alt="An expanded Thoughts block showing the agent's reasoning above its reply"></picture></a>
64
+ <a href="https://oar.sh/assets/shots/pingcf-thoughts.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/pingcf-thoughts.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/pingcf-thoughts.png?v=0.9.16" alt="An expanded Thoughts block showing the agent's reasoning above its reply"></picture></a>
65
65
  <br><sub>Read the reasoning, not just the answer.</sub>
66
66
  </td>
67
67
  </tr>
68
68
  <tr>
69
69
  <td valign="top">
70
- <a href="https://oar.sh/assets/shots/pagewright-watching.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/pagewright-watching.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/pagewright-watching.png?v=0.9.14" alt="A session watching two other sessions: a finished reply arrives as a compact relay-event row, the watching 2 sessions list is open with Unsubscribe, and a request to also watch a session on a paired relay waits on an Allow / Deny card"></picture></a>
70
+ <a href="https://oar.sh/assets/shots/pagewright-watching.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/pagewright-watching.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/pagewright-watching.png?v=0.9.16" alt="A session watching two other sessions: a finished reply arrives as a compact relay-event row, the watching 2 sessions list is open with Unsubscribe, and a request to also watch a session on a paired relay waits on an Allow / Deny card"></picture></a>
71
71
  <br><sub>Agents that watch agents: woken by events, approving nothing.</sub>
72
72
  </td>
73
73
  </tr>
@@ -116,11 +116,11 @@ API keys are entered in **⚙️ Settings** and stay on the relay host. The Clau
116
116
  <table>
117
117
  <tr>
118
118
  <td width="62%" valign="top">
119
- <a href="https://oar.sh/assets/shots/cfmail-steering.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-steering.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/cfmail-steering.png?v=0.9.14" alt="A running Claude turn with a message steered into it mid-turn, the reply streaming with its tool calls, and the Steer button in the composer"></picture></a>
119
+ <a href="https://oar.sh/assets/shots/cfmail-steering.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/cfmail-steering.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/cfmail-steering.png?v=0.9.16" alt="A running Claude turn with a message steered into it mid-turn, the reply streaming with its tool calls, and the Steer button in the composer"></picture></a>
120
120
  <br><sub>Send a message while the agent works, and it steers the running turn.</sub>
121
121
  </td>
122
122
  <td width="38%" valign="top">
123
- <a href="https://oar.sh/assets/shots/usage-copilot-compact.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/usage-copilot-compact.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/usage-copilot-compact.png?v=0.9.14" alt="The GitHub Copilot card in Check Usage: premium requests and plan quota with reset dates, and the cost of the last turn"></picture></a>
123
+ <a href="https://oar.sh/assets/shots/usage-copilot-compact.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/usage-copilot-compact.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/usage-copilot-compact.png?v=0.9.16" alt="The GitHub Copilot card in Check Usage: premium requests and plan quota with reset dates, and the cost of the last turn"></picture></a>
124
124
  <br><sub>What each plan has left, in one place.</sub>
125
125
  </td>
126
126
  </tr>
@@ -137,7 +137,7 @@ API keys are entered in **⚙️ Settings** and stay on the relay host. The Clau
137
137
  - **Share** a conversation as a read-only link, hide single messages and the host's paths from it, and see when it was opened ([Sharing](docs/web-ui.md#sharing)).
138
138
  - **On your phone**: install OAR as an app and get push notifications ([Notifications and the app](docs/web-ui.md#notifications-and-the-app)).
139
139
 
140
- The full tour is in [Using the web UI](docs/web-ui.md); every setting and config key is in [Settings and configuration](docs/configuration.md). What changed in each release is in the [changelog](CHANGELOG.md), with [0.9.14](CHANGELOG.md#0914--2026-10-21) as the latest.
140
+ The full tour is in [Using the web UI](docs/web-ui.md); every setting and config key is in [Settings and configuration](docs/configuration.md). What changed in each release is in the [changelog](CHANGELOG.md), with [0.9.16](CHANGELOG.md#0916--2026-10-24) as the latest.
141
141
 
142
142
  ## Remote access
143
143
 
@@ -188,7 +188,7 @@ flowchart LR
188
188
 
189
189
  You stay in charge: per paired relay you decide whether agents may only read, also prompt, or do everything, and in the `ask` and `plan` modes every write asks you first. A subscription only notifies; it approves nothing.
190
190
 
191
- <p><a href="https://oar.sh/assets/shots/pagewright-cross-relay.png?v=0.9.14"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/pagewright-cross-relay.light.png?v=0.9.14"><img src="https://oar.sh/assets/shots/pagewright-cross-relay.png?v=0.9.14" alt="A session watching two sessions on a paired relay: a reply arrives as a relay-event row, and after a short outage the events the other relay kept arrive as one replayed row" width="720"></picture></a></p>
191
+ <p><a href="https://oar.sh/assets/shots/pagewright-cross-relay.png?v=0.9.16"><picture><source media="(prefers-color-scheme: light)" srcset="https://oar.sh/assets/shots/pagewright-cross-relay.light.png?v=0.9.16"><img src="https://oar.sh/assets/shots/pagewright-cross-relay.png?v=0.9.16" alt="A session watching two sessions on a paired relay: a reply arrives as a relay-event row, and after a short outage the events the other relay kept arrive as one replayed row" width="720"></picture></a></p>
192
192
 
193
193
  How pairing, permissions and limits work is in [Agents working together](docs/agents-together.md).
194
194