ConnectOnionAll Posts
Remote Browser

A Session ID Is Not a Work Room

Emit provider-owned identity, status, authority, continuation, and replay so a UUID inside a tool result becomes a usable Work Room.

By ConnectOnion Team · 3 min read · 516 words

Remote BrowserPermissionsRelease

The first Claude Code browser test appeared to pass. O Chat showed a claude_code tool card, the tool ran for six seconds, and the assistant returned the requested text. Expanding the card revealed an even stronger signal: a real Claude provider envelope with status: completed, exit_code: 0, and a UUID session ID.

There was still no Open Work Room button.

The temptation was to fix that in React. The browser had the tool name and the JSON result, so it could parse the envelope, recognize claude_code, manufacture a provider card, and infer which later calls belonged to it. That would make one screenshot look right. It would also put protocol reconstruction in the least authoritative layer.

Codex showed the intended boundary. co ai installed CodexPlugin, which owns a provider invocation from start to finish. It emits a stable invocation ID, the parent tool-call ID, provider name, permission mode, terminal status, elapsed time, result, error, and resumable session ID. Child commands carry the same correlation. React normalizes those events, and O Chat only presents them.

Claude had all the difficult pieces — a bounded streaming reader, structured results, cancellation, nested tool activity, and session resume — but co ai registered it as a plain function. The streaming reader could correlate child activity with the outer tool call. No owner existed to emit the parent provider lifecycle, so the browser correctly rendered the only contract it received: a generic tool card.

The fix was not a Claude-shaped frontend exception. co ai now installs ClaudeCodePlugin beside CodexPlugin. Both adapters emit the same provider lifecycle while keeping their provider-specific transports and policies. The model-visible Claude signature remains prompt, explicit cwd, optional session_id, model, and timeout. OIP still carries normalized events rather than provider CLI output.

That symmetry could not weaken the hosted security boundary. Claude's plan mode is provider behavior, not a process sandbox, so an invited contact still cannot start the operator's local Claude CLI. The plugin checks the signature-verified requester before resolving cwd; a non-admin therefore cannot launch Claude or probe operator paths. An admin's Read only, workspace, or bounded Full access choice maps to Claude manual, Accept Edits, or Auto mode. The browser never chooses those modes, and resuming reapplies the current Host ceiling.

The acceptance test measured the whole path, not just the presence of a button. A real admin browser sent one OIP request through the production relay. The card rendered Claude Code · Completed · Open Work Room. Opening the room showed the provider UUID as its target. A follow-up typed inside that room reached the same outer OIP session, caused co ai to call Claude with that exact UUID, and returned the second requested result. Ninety focused unit and security tests passed before the browser run.

The lesson is the same one that makes protocol adapters worth having: data being available is not the same as semantics being owned. A session ID inside an opaque result can be displayed. A Work Room needs a lifecycle — identity, parentage, status, authority, continuation, and replay — emitted by the layer that actually controls the provider.

Star us on GitHub

If ConnectOnion saves you time, a ⭐ goes a long way — and earns you a coffee chat with our founder.