Initial import from garrytan/gstack@026751e (main snapshot via local relay)
Some checks failed
Workflow Lint / actionlint (push) Has been cancelled
Build CI Image / build (push) Has been cancelled
Skill Docs Freshness / check-freshness (push) Has been cancelled
Periodic Evals / build-image (push) Has been cancelled
Periodic Evals / evals (map[file:test/codex-e2e.test.ts name:e2e-codex]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/gemini-e2e.test.ts name:e2e-gemini]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-design.test.ts name:e2e-design]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-plan.test.ts name:e2e-plan]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-bugs.test.ts name:e2e-qa-bugs]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-workflow.test.ts name:e2e-qa-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-review.test.ts name:e2e-review]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-workflow.test.ts name:e2e-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-routing-e2e.test.ts name:e2e-routing]) (push) Has been cancelled
Some checks failed
Workflow Lint / actionlint (push) Has been cancelled
Build CI Image / build (push) Has been cancelled
Skill Docs Freshness / check-freshness (push) Has been cancelled
Periodic Evals / build-image (push) Has been cancelled
Periodic Evals / evals (map[file:test/codex-e2e.test.ts name:e2e-codex]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/gemini-e2e.test.ts name:e2e-gemini]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-design.test.ts name:e2e-design]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-plan.test.ts name:e2e-plan]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-bugs.test.ts name:e2e-qa-bugs]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-workflow.test.ts name:e2e-qa-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-review.test.ts name:e2e-review]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-workflow.test.ts name:e2e-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-routing-e2e.test.ts name:e2e-routing]) (push) Has been cancelled
Source: https://github.com/garrytan/gstack/commit/026751e
This commit is contained in:
108
docs/designs/CONDUCTOR_SESSION_API.md
Normal file
108
docs/designs/CONDUCTOR_SESSION_API.md
Normal file
@@ -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