mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-06 05:35:46 +02:00
410d0abd9b
Chrome extension (Manifest V3, sideload): - Side Panel with live activity feed, @ref overlays, dark terminal aesthetic - Background worker: health polling, SSE relay, ref fetching - Popup: port config, connection status, side panel launcher - Content script: floating ref panel with @ref badges Conductor API proposal (docs/designs/CONDUCTOR_SESSION_API.md): - SSE endpoint for full Claude Code session mirroring in Side Panel - Discovery via HTTP endpoint (not filesystem — extensions can't read files) TODOS.md: add $B watch, multi-agent tabs, cross-platform CDP, Web Store publishing. Mark CDP mode as shipped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
109 lines
3.9 KiB
Markdown
109 lines
3.9 KiB
Markdown
# Conductor Session Streaming API Proposal
|
|
|
|
## Problem
|
|
|
|
When Claude controls your real browser via CDP (gstack `$B connect`), you look at two
|
|
windows: **Conductor** (to see Claude's thinking) and **Chrome** (to see Claude's actions).
|
|
|
|
gstack's Chrome extension Side Panel shows browse activity — every command, result,
|
|
and error. But for *full* session mirroring (Claude's thinking, tool calls, code edits),
|
|
the Side Panel needs Conductor to expose the conversation stream.
|
|
|
|
## What this enables
|
|
|
|
A "Session" tab in the gstack Chrome extension Side Panel that shows:
|
|
- Claude's thinking/content (truncated for performance)
|
|
- Tool call names + icons (Edit, Bash, Read, etc.)
|
|
- Turn boundaries with cost estimates
|
|
- Real-time updates as the conversation progresses
|
|
|
|
The user sees everything in one place — Claude's actions in their browser + Claude's
|
|
thinking in the Side Panel — without switching windows.
|
|
|
|
## Proposed API
|
|
|
|
### `GET http://127.0.0.1:{PORT}/workspace/{ID}/session/stream`
|
|
|
|
Server-Sent Events endpoint that re-emits Claude Code's conversation as NDJSON events.
|
|
|
|
**Event types** (reuse Claude Code's `--output-format stream-json` format):
|
|
|
|
```
|
|
event: assistant
|
|
data: {"type":"assistant","content":"Let me check that page...","truncated":true}
|
|
|
|
event: tool_use
|
|
data: {"type":"tool_use","name":"Bash","input":"$B snapshot","truncated_input":true}
|
|
|
|
event: tool_result
|
|
data: {"type":"tool_result","name":"Bash","output":"[snapshot output...]","truncated_output":true}
|
|
|
|
event: turn_complete
|
|
data: {"type":"turn_complete","input_tokens":1234,"output_tokens":567,"cost_usd":0.02}
|
|
```
|
|
|
|
**Content truncation:** Tool inputs/outputs capped at 500 chars in the stream. Full
|
|
data stays in Conductor's UI. The Side Panel is a summary view, not a replacement.
|
|
|
|
### `GET http://127.0.0.1:{PORT}/api/workspaces`
|
|
|
|
Discovery endpoint listing active workspaces.
|
|
|
|
```json
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"id": "abc123",
|
|
"name": "gstack",
|
|
"branch": "garrytan/chrome-extension-ctrl",
|
|
"directory": "/Users/garry/gstack",
|
|
"pid": 12345,
|
|
"active": true
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
The Chrome extension auto-selects a workspace by matching the browse server's git repo
|
|
(from `/health` response) to a workspace's directory or name.
|
|
|
|
## Security
|
|
|
|
- **Localhost-only.** Same trust model as Claude Code's own debug output.
|
|
- **No auth required.** If Conductor wants auth, include a Bearer token in the
|
|
workspace listing that the extension passes on SSE requests.
|
|
- **Content truncation** is a privacy feature — long code outputs, file contents, and
|
|
sensitive tool results never leave Conductor's full UI.
|
|
|
|
## What gstack builds (extension side)
|
|
|
|
Already scaffolded in the Side Panel "Session" tab (currently shows placeholder).
|
|
|
|
When Conductor's API is available:
|
|
1. Side Panel discovers Conductor via port probe or manual entry
|
|
2. Fetches `/api/workspaces`, matches to browse server's repo
|
|
3. Opens `EventSource` to `/workspace/{id}/session/stream`
|
|
4. Renders: assistant messages, tool names + icons, turn boundaries, cost
|
|
5. Falls back gracefully: "Connect Conductor for full session view"
|
|
|
|
Estimated effort: ~200 LOC in `sidepanel.js`.
|
|
|
|
## What Conductor builds (server side)
|
|
|
|
1. SSE endpoint that re-emits Claude Code's stream-json per workspace
|
|
2. `/api/workspaces` discovery endpoint with active workspace list
|
|
3. Content truncation (500 char cap on tool inputs/outputs)
|
|
|
|
Estimated effort: ~100-200 LOC if Conductor already captures the Claude Code stream
|
|
internally (which it does for its own UI rendering).
|
|
|
|
## Design decisions
|
|
|
|
| Decision | Choice | Rationale |
|
|
|----------|--------|-----------|
|
|
| Transport | SSE (not WebSocket) | Unidirectional, auto-reconnect, simpler |
|
|
| Format | Claude's stream-json | Conductor already parses this; no new schema |
|
|
| Discovery | HTTP endpoint (not file) | Chrome extensions can't read filesystem |
|
|
| Auth | None (localhost) | Same as browse server, CDP port, Claude Code |
|
|
| Truncation | 500 chars | Side Panel is ~300px wide; long content useless |
|