mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-05 05:05:08 +02:00
docs: update BROWSER.md and TODO.md for project-local state
Replace /tmp paths with .gstack/, remove CONDUCTOR_PORT docs, document random port selection and per-project isolation. Add server bundling TODO. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+15
-23
@@ -33,7 +33,7 @@ gstack's browser is a compiled CLI binary that talks to a persistent local Chrom
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ HTTP POST ┌──────────────┐ │
|
||||
│ │ browse │ ──────────────── │ Bun HTTP │ │
|
||||
│ │ CLI │ localhost:9400 │ server │ │
|
||||
│ │ CLI │ localhost:rand │ server │ │
|
||||
│ │ │ Bearer token │ │ │
|
||||
│ │ compiled │ ◄────────────── │ Playwright │──── Chromium │
|
||||
│ │ binary │ plain text │ API calls │ (headless) │
|
||||
@@ -46,7 +46,7 @@ gstack's browser is a compiled CLI binary that talks to a persistent local Chrom
|
||||
|
||||
### Lifecycle
|
||||
|
||||
1. **First call**: CLI checks `/tmp/browse-server.json` for a running server. None found — it spawns `bun run browse/src/server.ts` in the background. The server launches headless Chromium via Playwright, picks a port (9400-9410), generates a bearer token, writes the state file, and starts accepting HTTP requests. This takes ~3 seconds.
|
||||
1. **First call**: CLI checks `.gstack/browse.json` (in the project root) for a running server. None found — it spawns `bun run browse/src/server.ts` in the background. The server launches headless Chromium via Playwright, picks a random port (10000-60000), generates a bearer token, writes the state file, and starts accepting HTTP requests. This takes ~3 seconds.
|
||||
|
||||
2. **Subsequent calls**: CLI reads the state file, sends an HTTP POST with the bearer token, prints the response. ~100-200ms round trip.
|
||||
|
||||
@@ -94,15 +94,15 @@ No DOM mutation. No injected scripts. Just Playwright's native accessibility API
|
||||
|
||||
### Authentication
|
||||
|
||||
Each server session generates a random UUID as a bearer token. The token is written to the state file (`/tmp/browse-server.json`) with chmod 600. Every HTTP request must include `Authorization: Bearer <token>`. This prevents other processes on the machine from controlling the browser.
|
||||
Each server session generates a random UUID as a bearer token. The token is written to the state file (`.gstack/browse.json`) with chmod 600. Every HTTP request must include `Authorization: Bearer <token>`. This prevents other processes on the machine from controlling the browser.
|
||||
|
||||
### Console, network, and dialog capture
|
||||
|
||||
The server hooks into Playwright's `page.on('console')`, `page.on('response')`, and `page.on('dialog')` events. All entries are kept in O(1) circular buffers (50,000 capacity each) and flushed to disk asynchronously via `Bun.write()`:
|
||||
|
||||
- Console: `/tmp/browse-console.log`
|
||||
- Network: `/tmp/browse-network.log`
|
||||
- Dialog: `/tmp/browse-dialog.log`
|
||||
- Console: `.gstack/browse-console.log`
|
||||
- Network: `.gstack/browse-network.log`
|
||||
- Dialog: `.gstack/browse-dialog.log`
|
||||
|
||||
The `console`, `network`, and `dialog` commands read from the in-memory buffers, not disk.
|
||||
|
||||
@@ -112,30 +112,22 @@ Dialogs (alert, confirm, prompt) are auto-accepted by default to prevent browser
|
||||
|
||||
### Multi-workspace support
|
||||
|
||||
Each workspace gets its own isolated browser instance with its own Chromium process, tabs, cookies, and logs.
|
||||
Each workspace gets its own isolated browser instance with its own Chromium process, tabs, cookies, and logs. State is stored in `.gstack/` inside the project root (detected via `git rev-parse --show-toplevel`).
|
||||
|
||||
If `CONDUCTOR_PORT` is set (e.g., by [Conductor](https://conductor.dev)), the browse port is derived deterministically:
|
||||
| Workspace | State file | Port |
|
||||
|-----------|------------|------|
|
||||
| `/code/project-a` | `/code/project-a/.gstack/browse.json` | random (10000-60000) |
|
||||
| `/code/project-b` | `/code/project-b/.gstack/browse.json` | random (10000-60000) |
|
||||
|
||||
```
|
||||
browse_port = CONDUCTOR_PORT - 45600
|
||||
```
|
||||
|
||||
| Workspace | CONDUCTOR_PORT | Browse port | State file |
|
||||
|-----------|---------------|-------------|------------|
|
||||
| Workspace A | 55040 | 9440 | `/tmp/browse-server-9440.json` |
|
||||
| Workspace B | 55041 | 9441 | `/tmp/browse-server-9441.json` |
|
||||
| No Conductor | — | 9400 (scan) | `/tmp/browse-server.json` |
|
||||
|
||||
You can also set `BROWSE_PORT` directly.
|
||||
No port collisions. No shared state. Each project is fully isolated.
|
||||
|
||||
### Environment variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BROWSE_PORT` | 0 (auto-scan 9400-9410) | Fixed port for the HTTP server |
|
||||
| `CONDUCTOR_PORT` | — | If set, browse port = this - 45600 |
|
||||
| `BROWSE_PORT` | 0 (random 10000-60000) | Fixed port for the HTTP server (debug override) |
|
||||
| `BROWSE_IDLE_TIMEOUT` | 1800000 (30 min) | Idle shutdown timeout in ms |
|
||||
| `BROWSE_STATE_FILE` | `/tmp/browse-server.json` | Path to state file |
|
||||
| `BROWSE_STATE_FILE` | `.gstack/browse.json` | Path to state file (CLI passes to server) |
|
||||
| `BROWSE_SERVER_SCRIPT` | auto-detected | Path to server.ts |
|
||||
|
||||
### Performance
|
||||
@@ -206,7 +198,7 @@ Tests spin up a local HTTP server (`browse/test/test-server.ts`) serving HTML fi
|
||||
|
||||
| File | Role |
|
||||
|------|------|
|
||||
| `browse/src/cli.ts` | Entry point. Reads `/tmp/browse-server.json`, sends HTTP to the server, prints response. |
|
||||
| `browse/src/cli.ts` | Entry point. Reads `.gstack/browse.json`, sends HTTP to the server, prints response. |
|
||||
| `browse/src/server.ts` | Bun HTTP server. Routes commands to the right handler. Manages idle timeout. |
|
||||
| `browse/src/browser-manager.ts` | Chromium lifecycle — launch, tab management, ref map, crash detection. |
|
||||
| `browse/src/snapshot.ts` | Parses accessibility tree, assigns `@e`/`@c` refs, builds Locator map. Handles `--diff`, `--annotate`, `-C`. |
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
- Pass/fail with evidence
|
||||
|
||||
## Phase 5: State & Sessions
|
||||
- [ ] Bundle server.ts into compiled binary (eliminate resolveServerScript() fallback chain entirely) (P2, M)
|
||||
- [ ] v20 encryption format support (AES-256-GCM) — future Chromium versions may change from v10
|
||||
- [ ] Sessions (isolated browser instances with separate cookies/storage/history)
|
||||
- [ ] State persistence (save/load cookies + localStorage to JSON files)
|
||||
|
||||
Reference in New Issue
Block a user