mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-06 13:45:35 +02:00
feat: Chrome extension Side Panel + Conductor API proposal
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>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user