@oar-sh/oar 0.9.6 → 0.9.7

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 (81) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/README.md +176 -22
  3. package/package.json +1 -1
  4. package/server/README.md +174 -7
  5. package/server/claude-cloud-worker/claude-cloud-event-normalizer.mjs +340 -0
  6. package/server/claude-cloud-worker/claude-cloud-session-process.mjs +1325 -0
  7. package/server/claude-cloud-worker/claude-cloud-session-worker.mjs +155 -0
  8. package/server/claude-worker/claude-remote-relay-tool.mjs +2 -0
  9. package/server/claude-worker/claude-sdk-adapter.mjs +18 -2
  10. package/server/claude-worker/claude-session-process.mjs +33 -0
  11. package/server/claude-worker/claude-session-worker.mjs +6 -0
  12. package/server/db-schema.mjs +17 -0
  13. package/server/migrations/0006-workspace-root-settings.mjs +67 -0
  14. package/server/migrations/0007-claude-cloud.mjs +82 -0
  15. package/server/public/app/agent-sessions-settings-ui.js +197 -0
  16. package/server/public/app/agent-sessions-settings.mjs +134 -0
  17. package/server/public/app/api-client.js +143 -4
  18. package/server/public/app/attachments-view.js +20 -1
  19. package/server/public/app/attribution-control.mjs +46 -0
  20. package/server/public/app/bootstrap.js +344 -31
  21. package/server/public/app/claude-cloud-conversation-ui.js +110 -0
  22. package/server/public/app/claude-cloud-settings-ui.js +374 -0
  23. package/server/public/app/claude-cloud-ui.mjs +611 -0
  24. package/server/public/app/composer-control-state.mjs +11 -0
  25. package/server/public/app/context-menu.mjs +140 -0
  26. package/server/public/app/context-tier-options.mjs +4 -0
  27. package/server/public/app/conversation-origin-ui.js +27 -0
  28. package/server/public/app/conversation-provider-indicator.mjs +22 -4
  29. package/server/public/app/conversation-view.js +83 -4
  30. package/server/public/app/cwd-picker.js +12 -0
  31. package/server/public/app/journal-view.js +698 -28
  32. package/server/public/app/math-dollars.mjs +89 -0
  33. package/server/public/app/model-selector-options.mjs +1 -1
  34. package/server/public/app/plan-usage-view.mjs +36 -8
  35. package/server/public/app/relay-error-ctas.mjs +16 -2
  36. package/server/public/app/remote-relay-origin-view.mjs +120 -4
  37. package/server/public/app/router.js +49 -12
  38. package/server/public/app/settings-modal.js +33 -2
  39. package/server/public/app/settings-tabs.js +1 -1
  40. package/server/public/app/socket-handlers.js +51 -0
  41. package/server/public/index.html +381 -7
  42. package/server/relay-tools.md +13 -1
  43. package/server/repositories/remote-relay-repository.mjs +42 -1
  44. package/server/repositories/session-repository.mjs +47 -1
  45. package/server/routes/claude-cloud-routes.mjs +140 -0
  46. package/server/routes/git-routes.mjs +37 -0
  47. package/server/routes/messages-routes.mjs +120 -15
  48. package/server/routes/remote-relay-routes.mjs +15 -1
  49. package/server/routes/sessions-routes.mjs +502 -72
  50. package/server/server-runtime.mjs +258 -25
  51. package/server/services/claude-account-usage-service.mjs +176 -0
  52. package/server/services/claude-cloud-repo-service.mjs +408 -0
  53. package/server/services/claude-cloud-session-service.mjs +326 -0
  54. package/server/services/claude-cloud-settings-service.mjs +269 -0
  55. package/server/services/git-remote-service.mjs +115 -0
  56. package/server/services/plan-usage-claude-cloud.mjs +211 -0
  57. package/server/services/plan-usage-claude.mjs +202 -40
  58. package/server/services/plan-usage-contract.mjs +39 -3
  59. package/server/services/plan-usage-service.mjs +82 -2
  60. package/server/services/provider-reasoning-effort.mjs +3 -0
  61. package/server/services/remote-relay-caller-context.mjs +49 -10
  62. package/server/services/remote-relay-client.mjs +9 -0
  63. package/server/services/remote-relay-dispatcher.mjs +383 -35
  64. package/server/services/remote-relay-inbound.mjs +49 -2
  65. package/server/services/remote-relay-loopback.mjs +245 -0
  66. package/server/services/remote-relay-registry-service.mjs +52 -0
  67. package/server/services/session-worker-launch-service.mjs +100 -15
  68. package/server/services/session-worker-process-service.mjs +348 -129
  69. package/server/services/session-worker-stop-service.mjs +24 -13
  70. package/server/services/session-worker-supervisor-service.mjs +56 -1
  71. package/server/services/usage-limit-pause-service.mjs +3 -1
  72. package/server/services/worker-launch-note-service.mjs +151 -0
  73. package/shared/claude-attribution.mjs +117 -0
  74. package/shared/claude-cloud/api-client.mjs +809 -0
  75. package/shared/claude-cloud/base-url.mjs +47 -0
  76. package/shared/claude-cloud/credentials.mjs +221 -0
  77. package/shared/claude-cloud/repo-url.mjs +111 -0
  78. package/shared/provider-routing.mjs +4 -2
  79. package/shared/remote-relay-contract.mjs +153 -22
  80. package/shared/remote-relay-tool-core.mjs +11 -8
  81. package/shared/steer-settle-failure.mjs +1 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,178 @@ All notable changes to OAR are documented here. The format follows
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.9.7] — 2026-10-03
9
+
10
+ Highlights: Claude Cloud chats (experimental, off by default) run Claude Code
11
+ in a sandbox at Anthropic on a GitHub repository; conversations can be
12
+ archived and have a context menu in the list; agents can start and use
13
+ sessions on the relay they run on; commits of Claude sessions say "Open
14
+ Agent Relay"; Check Usage opens at once.
15
+
16
+ ### Added
17
+
18
+ - **Archive conversations, and a context menu in the list.** Every
19
+ conversation row has an **Archive** button beside Delete (and the chat's
20
+ `⋯` menu an **Archive conversation** entry). An archived chat leaves the
21
+ list and its session worker is stopped; the 🗄 toggle at the top of the
22
+ sidebar shows the archived chats, each with **Unarchive**. A Claude Cloud
23
+ chat's cloud session is archived and unarchived at Anthropic with it. A
24
+ message into an archived chat (an agent's, say) brings it back by itself;
25
+ the composer of an archived chat says so instead of sending. A right-click
26
+ on a row — a long press on a phone — opens a menu with Open, Edit title,
27
+ Stop turn, Kill session, Archive/Unarchive and Delete.
28
+ - **Commits made from OAR say so.** Claude sessions now end their commit
29
+ messages with `Co-authored-by: Open Agent Relay (<model>) <no-reply@oar.sh>`
30
+ — the model's name in the parentheses, e.g. `Claude Fable 5.1` — and pull
31
+ request bodies with `🤖 Generated with [Open Agent Relay](https://oar.sh)`,
32
+ instead of Claude Code's own lines. Settings → Providers → Claude has the
33
+ choice: **OAR** (the default), **vanilla** (Claude Code's own attribution)
34
+ or **off** (none); a repo folder can override it from the 🧠 context modal
35
+ of any of its Claude sessions. A change reaches running sessions with their
36
+ next message. Claude Cloud chats follow the same setting: the sandbox gets
37
+ it with the first message and again when it changes, and in OAR mode the
38
+ `Claude-Session` link is left out of the commit as well. Other providers
39
+ are not touched: their tools have no such setting.
40
+ - **Claude Cloud (experimental): chats that run in a sandbox at Anthropic.**
41
+ A new provider, off by default. A Claude Cloud chat runs Claude Code in
42
+ Anthropic's cloud, on its own clone of a GitHub repository instead of on
43
+ the relay host. It is billed to the Claude account the host's Claude CLI
44
+ is logged in to, and its results come back as branches the agent pushes.
45
+ Switch it on in Settings → Providers → Claude Cloud and choose the cloud
46
+ environment and a default model there; it needs the Claude CLI logged in
47
+ with a claude.ai account on the relay host, GitHub connected to that
48
+ account, and the Claude GitHub app allowed on the repository.
49
+ - **New Chat** fills **Repository** and **Branch** from the folder you
50
+ pick, offers the repositories the Claude GitHub app can reach (the ones
51
+ used here before first) and the branches of the picked repository, lets
52
+ you type both, and warns about commits that are not pushed, changes
53
+ that are not committed and a repository the app cannot reach.
54
+ - **In the chat** the reply streams in live, the agent's questions and
55
+ permission prompts arrive as cards, **Stop** interrupts the turn, images
56
+ can be attached, and the model can be changed between turns. A line
57
+ above the composer links the session on claude.ai and every branch the
58
+ agent pushed to its comparison on GitHub, and shows the cost so far.
59
+ - **Turns** survive a restart of the worker or the relay without sending
60
+ your message twice. A turn stays open while the agent's background work
61
+ runs, a turn the session starts by itself (after long background work,
62
+ or from a message sent on claude.ai) appears as a reply of its own, and
63
+ a turn refused at the usage limit is paused until the reset like a
64
+ local Claude turn.
65
+ - **Commits** follow the relay's attribution setting (see above), and
66
+ deleting or archiving the chat archives the cloud session.
67
+ - **Not there:** relay modes, a reasoning effort, steering during a turn,
68
+ files other than images and anything else from the relay host, and the
69
+ relay's tools and previews inside the sandbox.
70
+ - **Before you switch it on:** the provider uses the Claude CLI's stored
71
+ login to call the Anthropic API endpoints the CLI itself uses. These
72
+ are not a documented public API and may change. OAR only reads the
73
+ token: it never stores or logs it and sends it nowhere but to
74
+ Anthropic; when it has run out, OAR lets the CLI refresh it. While the
75
+ provider is off the relay fetches nothing with that login, except for
76
+ cloud chats you created before. See "Claude Cloud" in the README.
77
+ `scripts/claude-cloud-live-check.mjs` checks a running relay's Claude
78
+ Cloud end to end.
79
+ - **Check Usage: live Claude limits and a Claude Cloud card.** With Claude
80
+ Cloud switched on, the Claude card reads the 5-hour, weekly and per-model
81
+ limits live from the account when you open the modal, instead of showing
82
+ the reading of your last Claude turn, and a limit that is getting close
83
+ carries Anthropic's warning. The card also shows which product the week
84
+ went to (Claude Code, chats and the others) and the organisation's prepaid
85
+ credits. The new Claude Cloud card shows the account's cloud credit (used,
86
+ left, and when it expires) and what the cloud chats on this relay have
87
+ cost as Anthropic reports it, in total and for the chat you opened the
88
+ modal from; a credit that is offered but not yet claimed is mentioned with
89
+ a link. The limit-reset vouchers (full reset, 5-hour reset) stay
90
+ claude.ai-only: no endpoint the CLI's login reaches carries them, so the
91
+ card links to the usage page instead. With Claude Cloud off, the Claude
92
+ card is what it was.
93
+ - **Agent sessions: an agent can hand parts of its task to other sessions on
94
+ the same relay.** The `remote_relay` tool now also works on the relay the
95
+ agent runs on: it starts sessions there, waits for them and reads their
96
+ replies, and each one is an ordinary conversation in your list. Off by
97
+ default; switch it on in Settings → Relays → Agent sessions (**Agents may
98
+ start and use sessions on this relay**). No relay has to be paired. The
99
+ first time the agent of a conversation starts a session, a card asks you
100
+ once for that conversation. At most 4 sessions it started may be at work at
101
+ the same time, a session that an agent created cannot start sessions
102
+ itself, and an agent cannot prompt, stop or archive the conversation it
103
+ runs in. A session can use any provider that is enabled on the relay
104
+ (image chats excepted); a Claude Cloud chat is started with the new `repo`
105
+ and `branch` arguments, and an agent on a paired relay can now start a
106
+ cloud chat here the same way. Sessions an agent starts use this relay's
107
+ accounts, show **via agent** with the title of the conversation they came
108
+ from in the sidebar and the header (a click opens it), and are never
109
+ archived automatically. The new
110
+ **Longest wait per tool call** slider in the same place sets how long one
111
+ call may wait for a reply: 10 minutes as before, up to 60; it applies to
112
+ waits on paired relays too. See "Agent sessions" in the README.
113
+
114
+ ### Changed
115
+
116
+ - **Check Usage opens at once.** The modal shows the reading it showed last
117
+ time immediately and reads only the open tab's provider live (the card says
118
+ "updating…" meanwhile), instead of fetching every provider and showing a
119
+ spinner until the slowest answered. A tab you switch to is read live when
120
+ its reading is older than a minute; **Refresh** reads the open tab only.
121
+ The relay keeps the last live answer of every provider, so the other cards
122
+ stay filled (`GET /api/usage?providers=…`).
123
+ - **Windows: the relay no longer stops while it reads the process list.**
124
+ Before every launch, every kill and every check of a worker that went
125
+ quiet, the relay reads the list of all processes through PowerShell. It
126
+ did so synchronously: half a second to a second and a half on an idle
127
+ machine, several seconds under load, during which the relay answered
128
+ nothing — under CI load that was enough for the tunnel to report 502 for
129
+ the whole relay. The list is now read off the relay's thread; callers that
130
+ ask at the same time share one read, and a read is reused for 1.5 s. A
131
+ worker that went quiet is checked by its pid first and by the list last.
132
+ `GET /api/status` → `sessionWorker.processList` shows when the list was
133
+ last read, how long it took and whether it failed; a read slower than two
134
+ seconds is logged. A kill or a workspace relaunch that cannot read the
135
+ list answers 409 with the reason instead of failing with 500 or stopping
136
+ blind.
137
+
138
+ ### Fixed
139
+
140
+ - **A reply that names an error code is a reply.** A reply a session
141
+ worker published was read as a failed turn when its one paragraph led up
142
+ to "Error code: relay.…" — a short report on a test that had failed with
143
+ that code, for instance. Workers always send the failure as a record, so
144
+ their replies are no longer read for one; the page's fix buttons under a
145
+ failure follow the same rule and no longer appear under a reply that
146
+ mentions a code in a quotation, a code span, a table or a list.
147
+ - **Two prices in one paragraph were shown as a formula.** In a reply such
148
+ as `this run cost $4.20, the earlier one $3.80`, everything between the
149
+ two dollar signs was rendered as maths. A dollar sign now starts a formula
150
+ only when it is written the way inline maths is: no space after the
151
+ opening sign, no space before the closing one, and no digit right after
152
+ it. Prices stay text; `$x^2$` is still maths. A wide inline formula also
153
+ no longer makes the whole message scroll sideways: it stays inside the
154
+ bubble and scrolls within itself.
155
+
156
+ - **Windows: no worker could start once an agent had run a command with an
157
+ arrow or a bullet in it.** Before every launch the relay reads the list of
158
+ all processes through PowerShell. Under the console's OEM code page
159
+ PowerShell wrote characters such as `→` and `•` as control bytes, the list
160
+ stopped being valid JSON, and every launch on the relay failed: each session
161
+ you wrote to turned yellow after six tries and stayed so, for every
162
+ provider, until the relay was restarted. The list is now written as UTF-8, a
163
+ control byte that still gets through is tolerated, a list the relay cannot
164
+ read no longer stops a launch, and a session whose launches were exhausted
165
+ is tried once more every minute instead of waiting for a restart.
166
+ - **A session whose worker cannot be started now says so.** Until now such a
167
+ session showed a yellow dot and nothing else. The relay now writes one note
168
+ into the conversation — why the worker could not be started, in one
169
+ sentence plus the cause — and keeps that same note up to date: it tries
170
+ again every minute for ten minutes, then stops and the note gets a
171
+ **Retry** button for once the cause is fixed; when the worker starts, the
172
+ note says so. Your message stays queued the whole time, and a queued
173
+ restart of the relay no longer waits for a message the relay has stopped
174
+ trying to deliver.
175
+ - **The Claude usage card showed extra-usage credits 100 times too high.**
176
+ Claude reports these amounts in the currency's minor units (cents), and
177
+ the card showed them as dollars: 12.50 used of a 50.00 limit read as 1250
178
+ of 5000. The percentage was right.
179
+
8
180
  ## [0.9.6] — 2026-09-29
9
181
 
10
182
  Highlights: a Claude turn pauses at the usage limit and carries on after the
package/README.md CHANGED
@@ -8,13 +8,14 @@ curl -fsSL oar.sh/install | sh
8
8
 
9
9
  On Windows, run `irm oar.sh/install.ps1 | iex` in PowerShell. Landing page: [oar.sh](https://oar.sh). npm and git-checkout installs are covered under [Install](#install).
10
10
 
11
- OAR relays six runtimes: **GitHub Copilot**, **OpenAI (BYOK)**, **OpenAI Image (BYOK)**, **Claude (Agent SDK)**, **Cursor (Agent SDK)**, and **Grok (CLI ACP)**. You pick one per conversation, and all of them share the same chat UI, queue, history, file browser, and question cards.
11
+ OAR relays seven runtimes: **GitHub Copilot**, **OpenAI (BYOK)**, **OpenAI Image (BYOK)**, **Claude (Agent SDK)**, **Claude Cloud**, **Cursor (Agent SDK)**, and **Grok (CLI ACP)**. You pick one per conversation, and all of them share the same chat UI, queue, history, file browser, and question cards.
12
12
 
13
13
  ```text
14
14
  ┌── Copilot SDK worker, or Copilot CLI + extension
15
15
  ├── OpenAI Copilot runtime, your API key
16
- [Browser] <--WebSocket--> [OAR relay :3333] ┼── OpenAI Image Images API, called by the relay
17
- ├── Claude Agent SDK worker, host's Claude login
16
+ ├── OpenAI Image Images API, called by the relay
17
+ [Browser] <--WebSocket--> [OAR relay :3333] ┼── Claude Agent SDK worker, host's Claude login
18
+ ├── Claude Cloud sandbox at Anthropic, host's Claude login
18
19
  ├── Cursor Agent SDK worker, your Cursor API key
19
20
  └── Grok Grok CLI over ACP, host's Grok login
20
21
  ```
@@ -65,6 +66,7 @@ You need Node.js plus whatever the runtimes you actually use need. Nothing else
65
66
  | GitHub CLI (`gh`), signed in | the `oar` launcher command; Extension-engine sessions on Windows; the Copilot card in **Check Usage** | `gh copilot` is built into current GitHub CLI releases, so there is no extension to install. The usage card also accepts a token in `GH_TOKEN` or `GITHUB_TOKEN` |
66
67
  | OpenAI API key | OpenAI and OpenAI Image chats | Entered in **⚙️ Settings**, stored in the relay database |
67
68
  | A Claude login on the relay host | Claude chats | Log in from **⚙️ Settings → Providers → Claude → Relogin** (the panel can install the Claude Code CLI first), or run `claude` once on the host. The relay stores no Claude key |
69
+ | The same Claude login, from a claude.ai account with GitHub connected | Claude Cloud chats | The Claude GitHub app must be allowed on each repository a cloud chat works on (see [Claude Cloud](#claude-cloud)) |
68
70
  | Cursor API key | Cursor chats | Entered in **⚙️ Settings**, stored in the relay database |
69
71
  | Grok CLI, signed in | Grok chats | Install it and sign in from **⚙️ Settings → Providers → Grok**, or set `XAI_API_KEY` in the relay's environment |
70
72
  | tmux (optional) | Linux and macOS | Session workers run in detached tmux sessions you can watch from the browser (**🖥️ Inspect tmux console**). Without tmux they run as plain background processes |
@@ -172,9 +174,9 @@ A global install keeps its state in `~/.oar` (`%APPDATA%\oar` on Windows; `OAR_S
172
174
 
173
175
  ## Runtimes
174
176
 
175
- The runtime (called the *provider* in the UI) is chosen in **New Chat** and then fixed for that conversation: once a conversation has sent its first message it keeps that provider, and its composer is locked to that provider's models. The composer states this above the input — `🔒 Session locked to GitHub Copilot / OpenAI / OpenAI Image / Claude SDK / Cursor SDK / Grok models.`, colour-coded per provider. OpenAI sessions also pin one exact model, which the note names in parentheses and the model dropdown shows as a disabled `🔒` entry.
177
+ The runtime (called the *provider* in the UI) is chosen in **New Chat** and then fixed for that conversation: once a conversation has sent its first message it keeps that provider, and its composer is locked to that provider's models. The composer states this above the input — `🔒 Session locked to GitHub Copilot / OpenAI / OpenAI Image / Claude SDK / ☁ Claude Cloud / Cursor SDK / Grok models.`, colour-coded per provider. OpenAI sessions also pin one exact model, which the note names in parentheses and the model dropdown shows as a disabled `🔒` entry.
176
178
 
177
- Turning a provider **off** (or removing the OpenAI key) rebinds conversations that have not sent a message yet back to Copilot, so you are never left with a conversation pointing at a runtime that can no longer start. Conversations already in flight, and conversations belonging to a different provider, are left alone.
179
+ Turning a provider **off** (or removing the OpenAI key) rebinds conversations that have not sent a message yet back to Copilot, so you are never left with a conversation pointing at a runtime that can no longer start. Conversations already in flight, and conversations belonging to a different provider, are left alone. Claude Cloud is the exception: switching it off only takes it out of **New Chat**, and its conversations stay as they are.
178
180
 
179
181
  | Runtime | Enable via | Auth | Notes |
180
182
  | ------- | ---------- | ---- | ----- |
@@ -182,6 +184,7 @@ Turning a provider **off** (or removing the OpenAI key) rebinds conversations th
182
184
  | **OpenAI (BYOK)** | ⚙️ Settings → Providers → OpenAI | your API key, stored in the relay database | Runs the Copilot runtime, on either engine, against an OpenAI-compatible endpoint |
183
185
  | **OpenAI Image (BYOK)** | ⚙️ Settings → Providers → OpenAI | the same key | The relay calls the OpenAI Images API itself; a chat whose replies are images |
184
186
  | **Claude (Agent SDK)** | ⚙️ Settings → Providers → Claude | the relay host's Claude login, **switchable from the panel** | A dedicated Node worker per conversation. The Claude Code CLI can be installed and updated from the panel |
187
+ | **Claude Cloud** | ⚙️ Settings → Providers → Claude Cloud (off by default) | the relay host's Claude login (a claude.ai account), read from the Claude CLI | Claude Code in a sandbox at Anthropic, on a clone of a GitHub repository. Results come back as pushed branches; billed to that Claude account. Uses API endpoints that are not a documented public API (see [Claude Cloud](#claude-cloud)) |
185
188
  | **Cursor (Agent SDK)** | ⚙️ Settings → Providers → Cursor | your Cursor API key, stored in the relay database | A dedicated Node worker per conversation through the Cursor Agent SDK |
186
189
  | **Grok (CLI ACP)** | ⚙️ Settings → Providers → Grok | the relay host's Grok CLI login, **sign in and out from the panel** | Drives the Grok CLI's `grok agent stdio` over ACP. The CLI can be installed and updated from the panel |
187
190
 
@@ -214,6 +217,8 @@ Save your key in **⚙️ Settings → Providers → OpenAI**, together with the
214
217
 
215
218
  Turn on **⚙️ Settings → Providers → Claude → Enable Claude for New Chat model selection**. The relay authenticates through the Claude credentials on the host machine (`~/.claude`), so there is no key to enter.
216
219
 
220
+ **Commit attribution.** Commits an agent makes in a Claude session end with `Co-authored-by: Open Agent Relay (<model>) <no-reply@oar.sh>` — the model's name in the parentheses, e.g. `Claude Fable 5.1` — and pull request bodies with `🤖 Generated with [Open Agent Relay](https://oar.sh)`. The same tab has the choice: **OAR** (default), **vanilla** (Claude Code's own `Co-Authored-By: Claude …` lines) or **off** (no attribution). A repo folder can override it for all of its Claude sessions from the **🧠** context modal. A change reaches a running session with its next message (a switch back to vanilla restarts the session's CLI between turns). [Claude Cloud](#claude-cloud) chats follow the same setting. Other providers are not affected: their tools have no such setting.
221
+
217
222
  The same panel manages the account itself. The row at the top names the signed-in account and plan, and:
218
223
 
219
224
  - **Relogin** runs the Claude CLI's login on the relay host and brings the flow to the browser: the authorize link appears inline with a **Copy link** button — open it on any device, authorize on claude.ai, then paste the returned code back into the field. The relay holds no Claude secret; the CLI rewrites the host credentials, and a fresh model discovery runs straight after, so switching accounts needs no relay restart. The flow is pushed over the socket, so you can start it on one device and finish it on another, and closing the modal does not lose it.
@@ -240,6 +245,69 @@ Differences from Copilot conversations:
240
245
  - Claude turns are not included in the Copilot usage line, and no usage line is attached to their replies (Claude's own plan limits appear in **Check Usage**)
241
246
  - The browsable **Session** root points at the Agent SDK's project directory rather than a Copilot session-state folder
242
247
 
248
+ ### Claude Cloud
249
+
250
+ **Experimental**, and off by default.
251
+
252
+ A Claude Cloud chat runs Claude Code in a sandbox at Anthropic instead of on the relay host. The sandbox works on its own clone of a GitHub repository: it sees what is pushed to GitHub and nothing on the host, and its results come back as branches the agent pushes. The chat is billed to the Claude account the relay host's Claude CLI is logged in to. In OAR it is a conversation like the others: the reply streams in, questions arrive as cards, and it works from the phone.
253
+
254
+ **What it needs.**
255
+
256
+ - The Claude CLI on the relay host, logged in with a claude.ai account (**⚙️ Settings → Providers → Claude → Relogin**, or `claude` on the host). The same login serves Claude chats.
257
+ - GitHub connected to that Claude account: [claude.ai/connect-github](https://claude.ai/connect-github).
258
+ - The Claude GitHub app allowed on every repository a cloud chat should work on (GitHub → Settings → Applications → Claude → Configure).
259
+
260
+ **Enabling.** Turn on **⚙️ Settings → Providers → Claude Cloud → Enable Claude Cloud for New Chat**. It is off by default, and it is refused while the host has no Claude login. The tab then shows:
261
+
262
+ - the account the chats are billed to, and where the relay reads the login from and until when it is valid. The login itself is changed on the Claude tab (**Claude login** jumps there);
263
+ - **Cloud environment**: the environments of the account. With none saved, the relay takes the first active one and saves it. An account without any gets its default one when you open [claude.ai/code](https://claude.ai/code) once;
264
+ - **Default model** for new cloud chats (`claude-sonnet-5-5` until you change it). The list is the Claude provider's models without their `[1m]` variants, plus the default.
265
+
266
+ Switching Claude Cloud off takes it out of **New Chat**. Cloud conversations that already exist keep working.
267
+
268
+ **Starting a chat.** Choose **+ New Chat → Provider → Claude Cloud**. The folder picker stays, but here it only fills in two fields, which you can also pick from a list or type yourself:
269
+
270
+ - **Repository**: read from the folder's `origin` remote (or the remote of its upstream branch). With the field focused, OAR lists the repositories the Claude GitHub app can reach for the account (read from Anthropic, kept for a minute; **↻** next to the label reads it again), the ones used in earlier cloud chats on this relay first and marked "used here"; typing filters the list by `owner/name`, arrow keys and Enter pick, Escape closes. `owner/repo` or a GitHub URL, https or ssh, can still be typed or pasted; only GitHub repositories are accepted.
271
+ - **Branch**: the folder's current branch; a repository picked from the list brings its default branch. With the field focused, OAR offers the repository's branches as the relay host's git sees them (`git ls-remote`, with the host's own GitHub login; the host's `OAR_CLAUDE_CLOUD_BRANCH_LOOKUP=off` turns this off). When the host cannot read them the field is a plain text field. Leave it empty for the repository's default branch.
272
+
273
+ Under the fields OAR warns about what the cloud clone will not have: commits that are not pushed, a branch without an upstream, uncommitted changes. It also says when the folder is no git repository or has no GitHub remote, when the Claude GitHub app has no access to the repository in the field (the cloud would refuse the first message), and when no cloud environment is set. There is no reasoning effort to choose. The cloud session itself is created by the first message.
274
+
275
+ **What works.**
276
+
277
+ - The reply streams in as the agent writes it, with thoughts, tool activity, subagent bubbles and the steps of the sandbox starting up
278
+ - Questions from the agent (`AskUserQuestion`) as question cards, multi-select included; a tool that asks for permission gets an **Allow** / **Deny** card. A card answered on claude.ai closes in OAR
279
+ - **Stop** interrupts the cloud turn. If the cloud does not confirm within 30 seconds, the turn ends in OAR with a note that the agent may still be working there
280
+ - Image attachments (JPEG, PNG, GIF or WebP, up to 5 MB each), sent inline
281
+ - Follow-up messages go into the same cloud session, also after it has been idle for a long time
282
+ - A restart of the worker or the relay in the middle of a turn does not send your message twice: the new worker finds the turn in the session's event log and follows it, and a turn that finished in the meantime is answered from the log. A dropped connection to the session is reopened where it broke off
283
+ - The **cloud line** above the composer: the repository, the branch, a link to the session on claude.ai, one **⇡ branch** link per branch the agent pushed (it opens GitHub's comparison with the branch the chat started from) and what the session has cost so far. The `⋯` menu has **☁️ Open on claude.ai**
284
+ - [Commit attribution](#claude-agent-sdk): commits and pull requests the agent makes in the sandbox end with what the Claude tab's setting says (**OAR**, **vanilla** or **off**), from the first message on, and a change reaches the sandbox with the next message. In OAR mode the `Claude-Session` link to claude.ai is left out too. A chat started from a folder follows that folder's override, and its **🧠** modal has the select. The commit's author is still the sandbox's git identity (`Claude`); the setting covers the lines at the end
285
+ - A turn the session starts by itself — the agent's closing turn when its background work outlived the hold, or a message you sent on claude.ai — appears in the chat as a continuation reply, with a line saying where it came from; the worker keeps the session's event stream open for that
286
+ - A turn the cloud refuses at the Claude usage limit is paused like a local Claude turn (a note with the reset time, the banner, and the work carries on by itself after the reset); the limit warning before it appears in the tool activity
287
+ - Deleting or archiving the conversation archives the cloud session at Anthropic; nothing is deleted there
288
+ - A **Claude Cloud** card in **Check Usage** with the account's cloud credit and the cost Anthropic reports for this relay's cloud sessions, and the **🧠** button for the session's context use (see [Usage and context](#usage-and-context))
289
+ - A failure the relay can name says what to do: log in again, connect GitHub, give the Claude GitHub app access to the repository, choose an environment
290
+
291
+ **What does not.**
292
+
293
+ - No relay modes, no reasoning effort and no context size: the three selectors are hidden. The model is chosen in **New Chat** and can be changed between turns in the composer like a local Claude chat's (the sandbox switches before the next message)
294
+ - No mid-turn steering: a message sent during a turn waits for the turn to end
295
+ - Nothing from the relay host reaches the sandbox: attachments other than images are refused, there is no working directory to change and no **Session** folder to browse
296
+ - No relay tools inside the sandbox: no `preview`, no `remote_relay`, no media embedded by host path
297
+ - No background task panel
298
+
299
+ **Started by an agent.** An agent in another session can start a cloud chat with the `remote_relay` tool, naming the repository and, if it wants one, the branch (`repo` and `branch`): an agent on a [paired relay](#remote-relays), under the rules for starting any session from there, or an agent on this relay once [agent sessions](#agent-sessions) are switched on. The same checks apply as in **New Chat** (the provider is on, an environment is set, the repository is on GitHub), and a chat without a requested model starts with the tab's default model. It can also read, prompt, wait for and stop a cloud chat you created.
300
+
301
+ **What OAR does with the Claude login.** Claude Cloud uses the login the Claude CLI keeps on the relay host (`.credentials.json` in `~/.claude`, or in `CLAUDE_CONFIG_DIR`) to call the Anthropic API endpoints the Claude CLI itself uses for cloud sessions and account usage. **These endpoints are not a documented public API.** Anthropic can change them without notice; cloud chats and the live usage figures then fail with a note until OAR is updated. If you are not comfortable with a program other than the CLI using its login this way, leave the provider off.
302
+
303
+ - The relay and its cloud workers only **read** the access token. It is sent as the bearer token to `https://api.anthropic.com` and to no other host. (OAR's own tests point the client at a fake API on the same machine; that setting accepts a loopback address and nothing else.)
304
+ - It is held in memory only. It is never written to the database or to a log, never sent to the browser and never put into an error message. Each cloud worker reads the credentials file itself, so nothing is passed along at launch.
305
+ - It is never refreshed by OAR, and the refresh token is never used. The CLI keeps its own login fresh; when the token has run out, the relay — and a cloud chat's worker, through the relay — reads the file again and at most once in five minutes has the CLI check its own login (`claude auth status`, which refreshes a login whose refresh token is still good), then retries. A login that is still expired ends the turn with a note to log in again.
306
+ - While the switch is off, the relay asks Anthropic for nothing with this login: it lists no environments and reads no account usage. Only a cloud conversation from before still talks to its session, when you write to it, delete it or archive it.
307
+ - The provider is off by default. Switching it on is the consent for all of the above.
308
+
309
+ `CLAUDE_CODE_OAUTH_TOKEN` in the relay's environment is used instead of the credentials file when it is set. That is the one case in which the relay passes the login on: a cloud worker started under tmux gets the variable through a file only the relay's user can read, which the worker's shell reads once and deletes; workers of other providers are not given it that way (see [Environment variables](#environment-variables)).
310
+
243
311
  ### Cursor (Agent SDK)
244
312
 
245
313
  Turn on **⚙️ Settings → Providers → Cursor**, paste your Cursor API key, and enable it for New Chat model selection. Saving the key runs model discovery and also discovers each model's supported reasoning-effort tiers; use **🤗 Select Models → Cursor SDK** to choose which models appear in the composer (the configured default model, `composer-2.5` unless you change it, always stays enabled).
@@ -319,13 +387,23 @@ The composer's model picker is the union of every enabled provider's catalog, fi
319
387
  - **Copilot** models are discovered from the installed Copilot CLI runtime a few seconds after the relay starts, and refreshed by the sessions that run on it. Each model shows the reasoning efforts and context window the runtime reports. The list starts with `auto`, then groups models by vendor (OpenAI, Anthropic, Google, xAI, Microsoft, Azure OpenAI, Moonshot AI, then any others alphabetically), newest version first. Before the first discovery, a fresh relay offers a curated set: `gpt-5.4`, `gpt-5.4-mini` (the default), `gpt-5.3-codex`, `claude-sonnet-4.6`, and `claude-haiku-4.5`.
320
388
  - **OpenAI (BYOK)** models are discovered from `/v1/models` when the key is saved or re-enabled.
321
389
  - **Claude** models are discovered from the Agent SDK when the provider is enabled. Bracketed `[1m]` long-context variants (such as `claude-opus-5[1m]`) do not appear as separate entries; they surface as a 1M option in the composer's context-size dropdown for the base model.
390
+ - **Claude Cloud** has no discovery of its own: its picker offers the Claude provider's models under their plain ids, plus the tab's default model.
322
391
  - **Cursor** models (and their per-model reasoning-effort tiers) are discovered when the API key is saved or the provider is re-enabled.
323
392
  - **Grok** models are discovered from the Grok CLI over ACP when the provider is enabled, after a sign-in, and after a CLI install from the panel.
324
393
 
325
- Use **🤗 Select Models** to choose which variants show up in the composer, then **💾 Save enabled models**; **Refresh** reruns discovery for every enabled runtime. The modal has one tab per runtime — **Copilot**, **OpenAI**, **Claude SDK**, **Cursor SDK**, **Grok** — and each tab lists only the models that runtime serves; there is no cross-runtime switching inside a conversation.
394
+ Use **🤗 Select Models** to choose which variants show up in the composer, then **💾 Save enabled models**; **Refresh** reruns discovery for every enabled runtime. The modal has one tab per runtime — **Copilot**, **OpenAI**, **Claude SDK**, **Cursor SDK**, **Grok** — and each tab lists only the models that runtime serves; there is no cross-runtime switching inside a conversation. Claude Cloud has no tab there.
326
395
 
327
396
  ## Highlights
328
397
 
398
+ ### New in 0.9.7
399
+
400
+ - **Claude Cloud (experimental, off by default)**: a chat that runs Claude Code in a sandbox at Anthropic, on its own clone of a GitHub repository. Pick the repository and branch from a list, follow the turn live, answer its questions, stop it, change the model between turns; the results come back as pushed branches. See [Claude Cloud](#claude-cloud) for what it needs and what it does with the Claude login.
401
+ - **Archive, and a menu on every conversation**: archive a conversation instead of deleting it (🗄 shows the archived ones), and right-click a row, or long-press it on a phone, to open, rename, stop, kill, archive or delete it.
402
+ - **Agent sessions**: an agent can start other sessions on the relay it runs on, wait for them and read their results, once you switch it on under Settings → Relays.
403
+ - **Commits say Open Agent Relay**: commits and pull requests of Claude sessions carry `Co-authored-by: Open Agent Relay (<model>)`; choose OAR, Claude Code's own lines or none, per relay and per folder.
404
+ - **Check Usage opens at once**: the last reading shows immediately and only the open tab is read live.
405
+ - **Fixes**: two prices in one paragraph are no longer shown as a formula, a reply that names an error code is no longer stored as a failed turn, and on Windows the relay no longer stalls or fails to start workers while it reads the process list.
406
+
329
407
  ### New in 0.9.6
330
408
 
331
409
  - **Claude pauses at the usage limit**: a turn that runs into the subscription's usage limit is paused instead of failed. A banner above the composer says when it carries on, with **Resume now** and **Cancel**; after the reset the relay sends a message of its own that quotes what was refused. The pause survives a relay restart, and a reset more than six hours away waits for you. A second banner warns when the usage passes 90 % of a limit.
@@ -360,10 +438,10 @@ Use **🤗 Select Models** to choose which variants show up in the composer, the
360
438
  - Nested **subagent bubbles**: each subagent gets its own live bubble with its own thoughts, activity, and streamed text, kept as collapsible sections after the turn finishes
361
439
  - **Background task panel** with live per-task state, model, and token use; Claude workflow tasks fold out into a progress tree of phases and agents, and leave a *Finished background task* card in the transcript when they complete
362
440
  - Question cards for clarification: one-click choices, multi-select checkmarks, free text, and multi-field structured forms validated against their JSON schema
363
- - Mathematical and scientific notation rendering for TeX/LaTeX equations and chemical formulas
441
+ - Mathematical and scientific notation rendering for TeX/LaTeX equations and chemical formulas, written as `$…$`, `\(…\)`, `$$…$$` or `\[…\]`. A single `$` opens a formula only when a non-space character follows it directly and the next `$` has a non-space character directly before it and no digit directly after it (a digit is allowed after something that looks like TeX, as in `$x^2$3`), so prices such as `$5 and $9` stay text
364
442
  - **Context usage** modal with a per-category token breakdown of the model's context window, plus a per-conversation **auto-compact window** slider for Claude sessions
365
443
  - **Transcript breaks**: day separators, a marker where a Claude session auto-compacted its context, and matching dots beside the scrollbar
366
- - **Plan usage** modal with subscription credits, rate-limit windows, and reset countdowns for Copilot, Claude, Cursor, and Grok
444
+ - **Plan usage** modal with subscription credits, rate-limit windows, and reset countdowns for Copilot, Claude, Claude Cloud, Cursor, and Grok
367
445
  - **Image conversations** (OpenAI Image): generate images in chat and iterate on a generated image with **Edit this image**
368
446
  - Agents can embed **images, video, and audio** in a reply by their absolute path, on every runtime; clicking an embedded image opens the file viewer with zoom, download, and copy
369
447
  - **Screenshot annotations**: mark up an uploaded screenshot with highlighter strokes before or after sending; the original upload is never modified
@@ -380,7 +458,7 @@ Use **🤗 Select Models** to choose which variants show up in the composer, the
380
458
 
381
459
  ### Starting a conversation
382
460
 
383
- - Start a chat with **+ New Chat**, which asks for the **Working directory**, **Provider**, **Model**, and **Reasoning effort** (or **Quality** and **Size**, for image chats; **Context window** where a model offers several) before the conversation exists. The working-directory list offers the known directories (current session, relay workspace, browser folder, recent roots), a **Custom path…** entry, and a 📁 folder picker; it defaults to the directory you picked last, and the chosen directory is applied before the session worker first launches. With Copilot as the only provider the provider row is hidden.
461
+ - Start a chat with **+ New Chat**, which asks for the **Working directory**, **Provider**, **Model**, and **Reasoning effort** (or **Quality** and **Size**, for image chats; **Context window** where a model offers several) before the conversation exists. The working-directory list offers the known directories (current session, relay workspace, browser folder, recent roots), a **Custom path…** entry, and a 📁 folder picker; it defaults to the directory you picked last, and the chosen directory is applied before the session worker first launches. With Copilot as the only provider the provider row is hidden. For **Claude Cloud** the modal asks for a **Repository** and a **Branch** instead of a reasoning effort, filled in from the chosen folder (see [Claude Cloud](#claude-cloud)).
384
462
  - Choose the **mode** and **model** per message in the composer.
385
463
  - The composer knows two slash commands, with autocomplete: **`/compact`** branches to a fresh conversation seeded with summary context, and **`/preview`** publishes a local dev server or directory on the public preview host without involving the agent (`/preview 5173 [label]`, `/preview ./dist [label]`, `/preview list`, `/preview close`). Agents can do the same through the `preview` tool (Claude and Cursor) or the documented API (see [docs/preview-servers.md](docs/preview-servers.md)). Any other single-line text starting with `/` is held back once with an *Unknown command* notice; press send again to send it as text.
386
464
 
@@ -402,7 +480,7 @@ Use **🤗 Select Models** to choose which variants show up in the composer, the
402
480
 
403
481
  ### Question cards
404
482
 
405
- - Agents ask clarifying questions through question cards: `ask_user` on Copilot and Cursor, `AskUserQuestion` on Claude. A choice answers with one click; a question that allows several answers shows checkmarks and one **Reply with selection** button, whose reply lists every ticked choice plus anything you typed. Structured requests render as multi-field forms.
483
+ - Agents ask clarifying questions through question cards: `ask_user` on Copilot and Cursor, `AskUserQuestion` on Claude and Claude Cloud. A choice answers with one click; a question that allows several answers shows checkmarks and one **Reply with selection** button, whose reply lists every ticked choice plus anything you typed. Structured requests render as multi-field forms.
406
484
  - On Copilot's SDK engine, the model gets OAR's own `ask_user` tool, which can mark a question as multi-select; a question worded "select all that apply" counts too, and every Copilot choice card that accepts free text has a **Select several** switch.
407
485
  - A card waits 8 hours for an answer (2 hours on Copilot's Extension engine). After that the agent is told nobody answered and continues according to the conversation's mode. A turn that is waiting on a card is never treated as stuck.
408
486
  - Grok has no question cards: ACP has no ask-user surface.
@@ -423,13 +501,15 @@ The composer draft, attachments included, is saved per conversation on the relay
423
501
  - **Filter conversations…** above the list matches titles, ignoring case. It clears with **×** or Escape, and while it is active it loads older pages, so it searches every conversation, not just the loaded ones.
424
502
  - **🔍** in the conversation header searches message text across all conversations.
425
503
  - On startup, the relay imports the Copilot sessions stored on the host (through the installed Copilot runtime) into its database, so they appear in the list with their history. If the runtime is unavailable, the import is reported as failed rather than guessed from the filesystem.
426
- - Deleting a conversation stops its session worker and removes its CLI session too (Copilot through the runtime, Claude by deleting that session's transcript). An imported Copilot session the relay never ran is only hidden: its CLI session stays, and nothing is stopped for it. A conversation that is still working — a running turn, one waiting on a question card or approval, or live background tasks — is not deleted, and the sidebar says why so you can stop it first.
504
+ - **Archive** (🗄 on the row, or **Archive conversation** in the `⋯` menu) takes a conversation out of the list without deleting anything: its session worker is stopped, and a Claude Cloud chat's session at Anthropic is archived with it. The 🗄 toggle above the list shows the archived conversations; **Unarchive** (📂) brings one back, cloud session included. An archived chat that is opened cannot be sent to until it is unarchived; a message that reaches it anyway (an agent's through a paired relay, say) unarchives it. A conversation that is still working is not archived — stop it first.
505
+ - A **right-click on a row** (a long press on a phone) opens a menu with Open, Edit title, Stop turn, Kill session, Archive or Unarchive, and Delete, so a session can be stopped or killed without opening it.
506
+ - Deleting a conversation stops its session worker and removes its CLI session too (Copilot through the runtime, Claude by deleting that session's transcript). A Claude Cloud conversation's session at Anthropic is archived, not deleted. An imported Copilot session the relay never ran is only hidden: its CLI session stays, and nothing is stopped for it. A conversation that is still working — a running turn, one waiting on a question card or approval, or live background tasks — is not deleted, and the sidebar says why so you can stop it first.
427
507
 
428
508
  ### Files, git, and previews
429
509
 
430
510
  - Use **📁 Browse files** to inspect the workspace (💼), drives (📀), or the session's own folder (🕵️), and to open previews. The **Hidden** and **Heavy** toolbar filters are remembered per browser, and a refresh re-opens the folders you had expanded.
431
511
  - Click the file and folder copy controls to insert `@file:...` / `@folder:...` tokens.
432
- - Workspace browsing follows the selected session's effective working directory. Running sessions keep their learned runtime directory, **🗂️ Change CWD** in the `⋯` menu changes the directory for the next launch, and `cd ...` typed in chat does not retarget the browser.
512
+ - Workspace browsing follows the selected session's effective working directory. Running sessions keep their learned runtime directory, **🗂️ Change CWD** in the `⋯` menu changes the directory for the next launch, and `cd ...` typed in chat does not retarget the browser. A Claude Cloud chat has no **Change CWD**: it works on a clone at Anthropic.
433
513
  - Use **🌿 Git changes** in the conversation `⋯` menu to review the workspace repository: the header shows the branch with ahead/behind counts and a **⬇ Pull** button, and the list shows every staged, unstaged, and untracked file (deleted files struck through). Clicking a file opens a diff viewer with **Changes** and **Full file** modes; closing it returns to the still-open list.
434
514
  - Agents can embed images, video, and audio in a reply by absolute path; they render inline.
435
515
  - Tap an image attachment in the composer (it carries a 🖍️ badge), or use **🖍️ Annotate** in the file viewer, to mark it up with highlighter strokes. The annotated copy is uploaded; the original stays untouched.
@@ -437,13 +517,14 @@ The composer draft, attachments included, is saved per conversation on the relay
437
517
 
438
518
  ### Usage and context
439
519
 
440
- - Use **📊 Check Usage** in the conversation `⋯` menu for plan usage across every configured provider: remaining credits, rate-limit windows, reset countdowns, and collapsible cost/token detail. Each provider gets its own tab, opening on the conversation's own provider, and the card names the signed-in account (email and plan) beneath its title. Sources differ per provider:
520
+ - Use **📊 Check Usage** in the conversation `⋯` menu for plan usage across every configured provider: remaining credits, rate-limit windows, reset countdowns, and collapsible cost/token detail. Each provider gets its own tab, opening on the conversation's own provider, and the card names the signed-in account (email and plan) beneath its title. The modal opens on the reading it showed last time and reads only the open tab's provider live (its card says "updating…" until the answer is in); a tab you switch to is read live when its reading is older than a minute, **Refresh** reads the open tab, and the relay keeps the last live answer of every provider so the other cards are never empty. Sources differ per provider:
441
521
  - **Copilot** — live quota (AI credits or premium requests, chat, plan), plus per-model/product billed cost when your GitHub token can read personal billing. Conversations on the SDK engine add a **Last SDK worker turn** section (AI credits actually spent, tokens, model calls, overage) with the model and how long ago it was captured; it is one turn's numbers rather than a running total, and it stops being shown once it is more than seven days old.
442
- - **Claude** — subscription limit windows (5-hour, weekly, per-model), extra-usage credits, session cost, and local usage attribution. Read from the live session at the end of a turn; the relay never starts a hidden turn to refresh it, so the newest reading is from your last Claude turn.
522
+ - **Claude** — subscription limit windows (5-hour, weekly, per-model), extra-usage credits, session cost, and local usage attribution. Read from the live session at the end of a turn; the relay never starts a hidden turn to refresh it, so the newest reading is from your last Claude turn. With **Claude Cloud** switched on, the limits are read live from the account each time the modal opens (kept for a minute), with no turn involved: the card then carries a **Live** badge, a limit that is getting close carries Anthropic's own warning word, and it adds **This week by product** (Claude Code, chats and the other products as shares of the week) and the organisation's **Prepaid credits** when there are any. Limit resets (full and 5-hour) are shown on claude.ai only; the card links there. When the live read fails, the card falls back to the last turn's reading and says why.
523
+ - **Claude Cloud** — shown while the provider is on. A meter per dollar credit the account holds, with what is used, what is left and when it expires; **Cloud spend (OAR sessions)**, the cost Anthropic reports per cloud session, summed over the cloud conversations this relay still has, with this conversation's own cost when the modal was opened from a cloud chat; and the latest cloud session report (its cost, and cost and tokens by model). These figures are Anthropic's reported cost, not a billing statement, and sessions started elsewhere are not counted. A credit that is offered but not yet claimed is mentioned with a link to claude.ai. Cloud turns spend the cloud credit first; without a credit they count against the Claude limits above.
443
524
  - **Cursor** — spend from the Cursor SDK measured against the monthly allowances you enter in Settings, split into the Cursor Models and Other Models pools; these figures are estimates, and Cursor's Spending dashboard remains authoritative. With a dashboard session token, the card adds live *Included in plan* bars.
444
525
  - **Grok** — the live weekly subscription quota, read with the host's Grok CLI login, plus per-turn tokens and estimated cost from the agent's prompt result. An optional monthly USD allowance in Settings adds an estimated remaining meter; the card is hidden when Grok is disabled. Billing: [console.x.ai](https://console.x.ai).
445
- - Per-reply usage lines are recorded only for Copilot turns — OpenAI, Claude, Cursor, and Grok turns do not consume Copilot premium requests, and no usage line is attached to them.
446
- - Use the **🧠** context button for a per-category breakdown of the conversation's context window: a usage bar, a token/percentage table, and free space. Claude sessions report exact SDK categories; Copilot sessions show the coarser system/tools + messages + buffer split, labelled as a lower-bound estimate when the runtime no longer emits full buckets.
526
+ - Per-reply usage lines are recorded only for Copilot turns — OpenAI, Claude, Claude Cloud, Cursor, and Grok turns do not consume Copilot premium requests, and no usage line is attached to them.
527
+ - Use the **🧠** context button for a per-category breakdown of the conversation's context window (Claude sessions also show the auto-compact window, the thinking controls and the folder's commit attribution there): a usage bar, a token/percentage table, and free space. Claude sessions report exact SDK categories; Copilot sessions show the coarser system/tools + messages + buffer split, labelled as a lower-bound estimate when the runtime no longer emits full buckets. A Claude Cloud session reports how much of its window is used after each turn, without categories.
447
528
  - Claude conversations additionally get an **auto-compact window** slider in that modal. Claude Code compacts a session once it approaches a model-tuned window (around 967k tokens on a 1M-context model), which is why long conversations rarely compact at all; setting a smaller window makes it happen sooner and keeps turns cheaper. *Auto* hands the choice back to the CLI. The smallest window is 100k, because the CLI silently ignores anything below that and falls back to its own default. The line beneath the slider reports the window actually in force and where it came from — your setting, the model default, or the `CLAUDE_CODE_AUTO_COMPACT_WINDOW` environment override — and fills in once the conversation's first turn completes. The change reaches a running session on its next message.
448
529
  - The transcript marks day boundaries, and marks the point where a Claude session compacted its context with the tokens before and after. Both appear as dots beside the scrollbar for the messages currently loaded.
449
530
 
@@ -458,7 +539,7 @@ Use **➡️ Share conversation** in the `⋯` menu to publish a read-only link.
458
539
 
459
540
  ### The conversation menu
460
541
 
461
- Besides the entries above, the `⋯` menu holds **✍️ Edit conversation title**, **🖥️ Inspect tmux console** (a read-only view of the session's tmux pane), **🤗 Select Models**, **⚙️ Settings**, **🌄 Restart web relay** (queued until the current turn is idle), **💤 Suspend host** (Windows; see below), and **☠️ Kill session** (stops the conversation's worker; an active turn then needs a retry or a new message). Its header shows the queue counts with **🚮 Empty queue**.
542
+ Besides the entries above, the `⋯` menu holds **✍️ Edit conversation title**, **🗄 Archive conversation** (**📂 Unarchive** on an archived chat), **🖥️ Inspect tmux console** (a read-only view of the session's tmux pane), **🤗 Select Models**, **☁️ Open on claude.ai** (Claude Cloud chats, once their session exists), **⚙️ Settings**, **🌄 Restart web relay** (queued until the current turn is idle), **💤 Suspend host** (Windows; see below), and **☠️ Kill session** (stops the conversation's worker; an active turn then needs a retry or a new message). Its header shows the queue counts with **🚮 Empty queue**.
462
543
 
463
544
  **💤 Suspend host** puts the machine the relay runs on to sleep, once the work is done. The confirmation lists what is still active. The relay then queues the suspend and fires it after 2 minutes with nothing active: no queued, running or parked turn, no background task of a live worker, and no open GitHub Actions run in the repository of a conversation that was busy since the request (read through `gh`; a repository whose state cannot be read blocks for 15 minutes, then is ignored). With nothing running when you confirm, it fires after a 30-second countdown. While a suspend is queued, every device shows a banner with the blockers or the countdown and a **Cancel** button, and a push notification reports the suspend. A relay restart drops a queued suspend and says so. **Show Suspend host action** in Settings hides the entry per browser.
464
545
 
@@ -466,7 +547,7 @@ Besides the entries above, the `⋯` menu holds **✍️ Edit conversation title
466
547
 
467
548
  ### Settings (⚙️ in the web UI)
468
549
 
469
- The modal is organised into six tabs — **General**, **Providers** (with a **Copilot**, **OpenAI**, **Claude**, **Grok**, and **Cursor** sub-tab), **Relays**, **Previews**, **Notifications**, and **Features** — and reopens on the tab you used last. Unless noted as per browser, these settings live in the relay database rather than the config file, and apply to every browser that connects:
550
+ The modal is organised into six tabs — **General**, **Providers** (with a **Copilot**, **OpenAI**, **Claude**, **Claude Cloud**, **Grok**, and **Cursor** sub-tab), **Relays**, **Previews**, **Notifications**, and **Features** — and reopens on the tab you used last. Unless noted as per browser, these settings live in the relay database rather than the config file, and apply to every browser that connects:
470
551
 
471
552
  | Tab | Setting | Default | What it does |
472
553
  | --- | ------- | ------- | ------------ |
@@ -482,9 +563,13 @@ The modal is organised into six tabs — **General**, **Providers** (with a **Co
482
563
  | Providers | OpenAI API key / model / base URL | — / `gpt-4o` / `https://api.openai.com/v1` | Enables the OpenAI and OpenAI Image providers |
483
564
  | Providers | Claude (Agent SDK) | off | Enables Claude as a New Chat provider and runs model discovery; default model `claude-sonnet-5` |
484
565
  | Providers | Claude account (Relogin / Logout) | host login | Switches the Claude account the relay host's CLI uses, from the browser (see [Claude (Agent SDK)](#claude-agent-sdk)) |
566
+ | Providers | Claude Cloud | off | Enables Claude Cloud as a New Chat provider, and the live account figures in **Check Usage**; the switch is the consent to use the Claude CLI's login (see [Claude Cloud](#claude-cloud)) |
567
+ | Providers | Claude Cloud environment / default model | first active environment of the account / `claude-sonnet-5-5` | The cloud environment new cloud sessions run in, and the model a new cloud chat starts with |
485
568
  | Providers | Cursor API key / model | — / `composer-2.5` | Enables Cursor; plus monthly plan allowances and the optional dashboard session token |
486
569
  | Providers | Grok | off | Enables Grok; default model `grok-4.5`; **Sign in** / **Sign out**; optional monthly allowance |
487
570
  | Relays | Public address, Accept prompts from other relays' agents | browser address / on | How paired relays reach this one, and whether their agents may prompt sessions here (see [Remote relays](#remote-relays)) |
571
+ | Relays | Agent sessions: Agents may start and use sessions on this relay | off | Lets agents on this relay start and use other sessions here with the `remote_relay` tool; the first session an agent starts in a conversation asks for your approval (see [Agent sessions](#agent-sessions)) |
572
+ | Relays | Agent sessions: Longest wait per tool call | `10 min` | How long one `remote_relay` call may wait for a reply (2 to 60 minutes), on this relay and on paired ones; adjustable whether or not the switch above is on |
488
573
  | Relays | Remote relays | — | Pair a relay by pasting its web address; per relay **Agents may** read only, read and prompt, or do everything |
489
574
  | Previews | Live previews | — | Lists the published previews, each of which you can close |
490
575
  | Notifications | Push notifications | off | Per device: which events notify, and whether titles and message previews are included |
@@ -564,7 +649,8 @@ The config file is `server/config.json` in a git checkout and `~/.oar/config.jso
564
649
  | `GH_TOKEN`, `GITHUB_TOKEN` | GitHub token for the Copilot usage card, instead of `gh auth token` |
565
650
  | `XAI_API_KEY` | Grok authentication instead of the Grok CLI login |
566
651
  | `CURSOR_SESSION_TOKEN` | Cursor dashboard session token for live plan bars |
567
- | `CLAUDE_CONFIG_DIR` | Claude configuration directory, instead of `~/.claude` |
652
+ | `CLAUDE_CONFIG_DIR` | Claude configuration directory, instead of `~/.claude`; Claude Cloud reads the CLI's login (`.credentials.json`) from it |
653
+ | `CLAUDE_CODE_OAUTH_TOKEN` | A Claude login token for Claude Cloud, used instead of the CLI's credentials file, by the relay (settings tab, **Check Usage**, archiving) and by its cloud workers. Under tmux the relay hands it to cloud workers only, through an owner-only file; a worker started without tmux inherits the relay's environment as it is |
568
654
  | `CLAUDE_CODE_AUTO_COMPACT_WINDOW` | Overrides the Claude auto-compact window |
569
655
  | `COPILOT_CLOUDFLARED_MODE`, `COPILOT_CLOUDFLARED_TOKEN`, `COPILOT_CLOUDFLARED_BINARY` | Override `cloudflaredTunnel.mode`, `.token`, and `.binary` |
570
656
  | `COPILOT_WORKSPACE_ROOT_ALLOW_LIST` | Same as `workspaceRootAllowList` |
@@ -697,12 +783,22 @@ conversation has sent 30 prompts to agents on other relays without a message fro
697
783
  one asks you first with a question card; **Allow** starts the count again.
698
784
 
699
785
  **What agents can do.** Every provider gets the same `remote_relay` tool (Claude, Cursor and
700
- Copilot directly; Grok and the Copilot extension engine through OAR's MCP server). Per paired
786
+ Copilot directly; Grok and the Copilot extension engine through OAR's MCP server). Sessions get it
787
+ while at least one relay is paired or [agent sessions](#agent-sessions) are switched on. Per paired
701
788
  relay, **Agents may** limits it to *read only*, *read and prompt* (existing sessions) or *full*
702
789
  (also create sessions, answer questions, stop turns, archive). In the *ask* and *plan* relay
703
790
  modes, every write action first asks you with a question card. For a session it starts, an agent
704
791
  can set the provider, model, relay mode and reasoning effort; what it leaves out follows the
705
- session it works in, as far as the other relay offers it.
792
+ session it works in, as far as the other relay offers it. A [Claude Cloud](#claude-cloud) session
793
+ is started with `provider: "claude-cloud"`, a `repo` (a GitHub URL or `owner/repo`, for example
794
+ `example-org/sample-repo`) and an optional `branch` instead of a folder; without a model it gets
795
+ the default model of the other relay's Claude Cloud tab. Claude Cloud must be switched on there.
796
+ A cloud session that exists can be read, prompted, waited for and stopped like any other.
797
+
798
+ A `send`, `create_session` or `wait` call waits for the reply for as long as the agent asks, up to
799
+ **Longest wait per tool call** of the relay the agent runs on (10 minutes unless you changed it,
800
+ see [Agent sessions](#agent-sessions)). When the time is up the agent gets what there is so far
801
+ and can call `wait` again.
706
802
 
707
803
  When an agent prompts a session on another relay, that relay shows a **↗ from …** badge with the
708
804
  sending relay, session and model on the message, and marks sessions an agent created in the
@@ -715,6 +811,58 @@ The calls go through your own relay, which holds the other relay's token: agents
715
811
  token. Remote addresses must use `https://`; plain `http://` is accepted only for loopback (an
716
812
  SSH port forward, for example) and private network ranges.
717
813
 
814
+ ### Agent sessions
815
+
816
+ The same `remote_relay` tool can also work on the relay the agent itself runs on. An agent can
817
+ then hand parts of its task to other sessions: it starts them, waits for them and reads their
818
+ replies. Every session it starts is an ordinary conversation in your list. No relay has to be
819
+ paired for this.
820
+
821
+ **Switching it on.** It is off by default. Turn on **Settings → Relays → Agent sessions →
822
+ Agents may start and use sessions on this relay**. From then on this relay is the first entry of
823
+ the relay list an agent sees, marked as its own; the agent names it by its **Relay name** or as
824
+ `this`. It needs no mention, and **Agents may** and **Accept prompts from other relays' agents**
825
+ do not apply to it. On this relay an agent can do what *full* allows on a paired one: list and
826
+ read every session here, prompt one, start one, wait for it, answer its question, stop its turn
827
+ and archive it. Switching the setting off closes this relay to the tool again.
828
+
829
+ **The rules.**
830
+
831
+ - **Approval once per conversation.** The first time the agent of a conversation wants to start
832
+ a session here, a question card (**Agent sessions**) shows the provider, the folder or
833
+ repository and the prompt. **Allow** covers every session that conversation's agent starts
834
+ later, also after a relay restart; **Deny** refuses that one call. In the *ask* and *plan*
835
+ relay modes, every other write action still asks, as it does for a paired relay.
836
+ - **At most 4 at work.** Of the sessions one conversation's agent started, 4 may have a turn
837
+ queued or running at the same time. A fifth is refused until one of them has finished.
838
+ - **One level only.** A session that an agent created, here or from a paired relay, cannot start
839
+ sessions on this relay.
840
+ - **Not on itself.** An agent cannot prompt, stop, archive, wait for or answer the conversation
841
+ it runs in.
842
+ - The count of 30 prompts without a message from you (see above) includes prompts to sessions
843
+ on this relay.
844
+
845
+ **What it can start.** A session with any provider that is enabled on this relay (Copilot,
846
+ OpenAI, Claude, Cursor, Grok or Claude Cloud; not an OpenAI Image chat): in a folder
847
+ (the relay's default folder when the agent names none), or a [Claude Cloud](#claude-cloud) chat
848
+ with `provider: "claude-cloud"`, `repo` and an optional `branch`. A new session knows nothing of
849
+ the conversation it was started from. Sessions an agent starts use this relay's accounts and
850
+ count against their usage.
851
+
852
+ **In the conversation list.** A session an agent on this relay started carries **via agent ·
853
+ “title”** in the sidebar and under the title in the header, with the title of the conversation
854
+ the agent runs in; clicking it opens that conversation while it is still in the list. The
855
+ agent's prompts carry the same marker, with its model, as a badge on the message. The relay never
856
+ archives these sessions by itself: they stay in the list until you archive or delete them, or the
857
+ agent archives one with the tool.
858
+
859
+ **Longest wait per tool call.** The slider under the switch sets how long one `send`,
860
+ `create_session` or `wait` call may wait for a reply: 10 minutes by default, from 2 to 60 minutes
861
+ in steps of one minute. The agent can call `wait` again to keep waiting. The limit also applies
862
+ to this relay's agents when they wait for a session on a paired relay, so the slider can be moved
863
+ whether or not the switch above it is on. A turn that waits is still subject to **Max turn duration**
864
+ under **General** (60 minutes by default), which does not know about the wait.
865
+
718
866
  ## Security notes
719
867
 
720
868
  - The auth token guards the API and the Socket.IO channel. A browser signs in once, with the token or with a URL carrying `?token=` (such as the one `oar setup` prints and puts in its QR code), and then holds an HttpOnly cookie for 30 days, marked `Secure` when the relay is reached over HTTPS. Treat the token, and that URL, like a password.
@@ -724,6 +872,7 @@ SSH port forward, for example) and private network ranges.
724
872
  - Shared conversation links and preview links are public by design: anyone with the URL can read the shared transcript or reach the previewed app, without signing in.
725
873
  - A [paired relay](#remote-relays) holds a token that opens the other relay completely. The per-relay "Agents may" limit and the "Accept prompts from other relays' agents" switch are honoured by OAR's own traffic, but anyone holding the token can still use the full API: the token is the real boundary. A token entered for a paired relay is stored like the API keys below and never sent to browsers or agents.
726
874
  - API keys you enter (OpenAI, Cursor) are stored in the relay database on the host and never sent to browsers. Claude and Grok credentials stay with their CLIs on the host.
875
+ - Claude Cloud, when you switch it on, reads the Claude CLI's login and uses it against Anthropic API endpoints that are not a documented public API. The token is only read and held in memory, and goes to `api.anthropic.com` only (see [Claude Cloud](#claude-cloud)). A cloud agent works in Anthropic's sandbox, not on your host.
727
876
  - OAR has no telemetry. Its only request to oar.sh is the update check, which is off until you enable it.
728
877
 
729
878
  ## Troubleshooting
@@ -739,6 +888,9 @@ SSH port forward, for example) and private network ranges.
739
888
  | File links fail | Verify auth token/cookie and that paths are inside allowed workspace/drive roots |
740
889
  | Claude missing from New Chat | Enable it in **⚙️ Settings → Providers → Claude**; the toggle is off by default |
741
890
  | Claude reply says it cannot authenticate | Press **Claude settings** on the failed reply, then **Relogin** (or run `claude` on the relay host), and retry the turn |
891
+ | Claude Cloud missing from New Chat | Enable it in **⚙️ Settings → Providers → Claude Cloud**; it is off by default and needs a Claude login on the relay host |
892
+ | Claude Cloud reply says GitHub is not connected, or the Claude GitHub app has no access | Connect GitHub to the Claude account at [claude.ai/connect-github](https://claude.ai/connect-github), or add the repository to the Claude GitHub app's repository access on GitHub; then send the message again |
893
+ | New Chat says *No cloud environment is set* | Choose one in **⚙️ Settings → Providers → Claude Cloud**; an account without any gets its default one when you open claude.ai/code once |
742
894
  | Grok reply says the CLI was not found | Press **Install Grok CLI** on the failed reply, or install it from **⚙️ Settings → Providers → Grok**; no relay restart is needed afterwards |
743
895
  | Grok reply says authentication failed | Press **Sign in to Grok** on the failed reply and confirm the device code in a browser |
744
896
  | Long turn requeued unexpectedly | Raise or clear **Max turn duration** in Settings (0 = no limit) |
@@ -747,7 +899,7 @@ SSH port forward, for example) and private network ranges.
747
899
  | A conversation seems wedged | **☠️ Kill session** in the `⋯` menu stops its worker; retry the turn or send a new message |
748
900
  | **🌄 Restart web relay** fails with *localhost-only* | The restart endpoint accepts loopback connections only: use it on the relay host or through a tunnel, not over a direct LAN connection |
749
901
  | `npm install -g @oar-sh/oar` fails with node-gyp or prebuild errors | `better-sqlite3` has no prebuilt binary for your platform; install a C/C++ build toolchain and Python, then retry |
750
- | No usage line under a reply | Expected for OpenAI, Claude, Cursor, and Grok turns; only Copilot turns record plan usage |
902
+ | No usage line under a reply | Expected for OpenAI, Claude, Claude Cloud, Cursor, and Grok turns; only Copilot turns record plan usage |
751
903
 
752
904
  ## Repository layout
753
905
 
@@ -757,6 +909,7 @@ oar/
757
909
  ├── bin/ # The `oar` command (oar.js) and a Windows cmd shim for checkouts (bat/oar.bat)
758
910
  ├── docs/ # Preview-server guide, Copilot BYOK notes, SDK feature tracker
759
911
  ├── server/
912
+ │ ├── claude-cloud-worker/ # Claude Cloud session worker (follows a cloud session's event stream; runs no agent itself)
760
913
  │ ├── claude-worker/ # Claude Agent SDK session worker (turn runner, ask-user bridge, attachments)
761
914
  │ ├── copilot-worker/ # Copilot SDK engine session worker (steering, background tasks, questions)
762
915
  │ ├── cursor-worker/ # Cursor Agent SDK session worker (turn runner, mode nudges, auth retry)
@@ -770,6 +923,7 @@ oar/
770
923
  │ ├── server.js # Entry point: supervisor plus relay runtime
771
924
  │ └── server-runtime.mjs # Express + Socket.IO relay server
772
925
  ├── shared/ # Code shared by the server, the extension, and the workers
926
+ │ ├── claude-cloud/ # Claude Cloud API client, credentials reader, repository and branch rules
773
927
  │ └── worker-runtime/ # Common worker plumbing (relay API client, heartbeat, worker link)
774
928
  ├── tests/ # Playwright end-to-end suite and its isolated relay harness
775
929
  ├── CHANGELOG.md