agent-workbench 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,413 +1,426 @@
1
- # Agent Workbench
2
-
3
- Una interfaz visual local para las CLIs de agentes de código. Funciona con la
4
- CLI de Claude Code, con la de Codex, con la de OpenCode y con Antigravity CLI.
5
-
6
- No habla con ninguna API. Lanza la CLI que ya tenés instalada y logueada
7
- —`claude`, `codex`, `opencode` o `agy`— dentro de una pseudo-terminal, y le
8
- agrega alrededor lo que una terminal sola no da: pestañas, historial navegable,
9
- la conversación como tarjetas, un medidor de contexto, el estado de git y un
10
- árbol de archivos.
11
-
12
- La terminal sigue siendo la terminal. Todo lo que escribís le llega a la CLI sin
13
- que la aplicación lo toque.
14
-
15
- ![La conversación al centro; alrededor, los proyectos con su historial, las pestañas de las cuatro CLIs y el árbol de archivos](https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-conversacion.png)
16
-
17
- ---
18
-
19
- ## Qué hace
20
-
21
- | | |
22
- |---|---|
23
- | **Pestañas** | Varias sesiones vivas a la vez, de cualquiera de las CLIs, cada una en su directorio. Sobreviven a un `F5`: los procesos viven en el servidor, no en la pestaña del navegador. El punto de cada una dice si el agente está trabajando, parado o esperando una respuesta, en las CLIs que publican su estado ([abajo](#varias-clis)). |
24
- | **Arranque sin gastar nada** | Al abrir la app las pestañas vuelven **dormidas**: se leen enteras y no lanzan ninguna CLI. La abrís con un botón cuando quieras escribirle al agente. |
25
- | **Historial** | Tus proyectos y conversaciones anteriores en la barra lateral, con filtro, y las de las cuatro CLIs juntas bajo cada proyecto, cada una con su insignia. Abrir una la retoma con su CLI, en la misma sesión. **Archivar historial…** esconde de una vez las sesiones de una CLI anteriores a hoy, y cada proyecto se archiva entero con un botón: sin borrar nada, y las dos cosas se deshacen. |
26
- | **Conversación** | Los mensajes de la sesión activa, en vivo, con las herramientas plegadas y su resultado adentro. Búsqueda, salto entre resultados, copiado por mensaje y, según la CLI, las preguntas del agente se contestan desde el chat. |
27
- | **Continuar con…** | Con más de una CLI instalada, una conversación se sigue con otra CLI en la misma carpeta. El agente nuevo arranca de un recorte de los últimos turnos, no del contexto que tenía el anterior. |
28
- | **Buscar en todo** | Con más de una CLI y algo guardado en la copia propia, el filtro de la barra busca también en el texto de todas las conversaciones guardadas, no sólo en sus títulos. |
29
- | **Medidor de contexto** | Tokens de la última petición contra la ventana del modelo. Tokens, nunca dinero. |
30
- | **Cambios** | Rama, adelanto y atraso contra la rama de seguimiento, worktrees, y los archivos tocados con su diff. **Solo lectura.** |
31
- | **Archivos** | El árbol del directorio de la pestaña, con buscador por nombre y previsualización con resaltado de sintaxis. Menú contextual para copiar rutas, insertarlas como `@ruta` o abrir el archivo con la app del sistema. |
32
- | **Planes** | Los documentos que escribió esa conversación, renderizados: los planes del modo plan y también los `.md` que el agente creó dentro del proyecto o en la carpeta temporal de la sesión. Sólo los que la conversación que estás mirando nombró. |
33
- | **Memoria compartida** | Lo que los agentes aprenden de un proyecto, en `.agents/memory/`, y lo leen y escriben las cuatro CLIs ([abajo](#memoria-compartida)). |
34
- | **Copia propia** | Opcional. El historial de las cuatro CLIs en una carpeta tuya y en un formato de la aplicación, para no perderlo si una CLI cambia de formato, lo borra o la desinstalás ([abajo](#copia-propia-opcional)). |
35
- | **Tema** | Claro, oscuro, o el del sistema. |
36
-
37
- <p>
38
- <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-cambios.png" width="49%" alt="El panel de cambios: rama y archivos tocados, por grupo">
39
- <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-diff.png" width="49%" alt="El diff de uno de esos archivos, en el mismo panel">
40
- </p>
41
-
42
- ### Varias CLIs
43
-
44
- Con más de una CLI instalada, cada sesión de la barra y cada pestaña lleva la
45
- insignia de su CLI, y el `+` de nueva pestaña abre con la que usaste en ese
46
- proyecto; su flecha te deja elegir otra. Con una sola, no ves nada de esto.
47
-
48
- <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-clis.png" width="45%" alt="La barra de proyectos con sesiones de varias CLIs, cada una con su insignia, y el menú del + con las cuatro CLIs y sus versiones">
49
-
50
- **No todas las CLIs dan lo mismo.** Claude Code deja en sus archivos todo lo que
51
- la aplicación necesita. Codex deja el historial y los tokens del medidor, pero no
52
- su estado, ni los permisos pendientes, ni sus preguntas, ni el modelo: su punto
53
- dice que no se sabe, no hay aviso de "esperando" y las preguntas se contestan en
54
- su terminal. Con OpenCode, la aplicación arranca un servidor local de OpenCode
55
- cuando abrís una pestaña, y de ahí salen su estado, el aviso de que espera un
56
- permiso y las preguntas que se contestan desde el chat. Antigravity CLI publica
57
- su estado y sus tokens sólo si configurás su status line
58
- ([abajo](#antigravity-cli-estado-y-medidor-opcional)).
59
-
60
- ---
61
-
62
- ## Requisitos
63
-
64
- | | |
65
- |---|---|
66
- | **Node.js** | 20 o superior. **Para ver el historial de OpenCode y los títulos de Antigravity CLI, 22.13 o posterior**: se leen con el SQLite que trae Node desde esa versión. Con uno anterior todo lo demás funciona igual; el arranque avisa lo de OpenCode, y Antigravity CLI lista sus conversaciones sin los títulos ni las carpetas de su índice |
67
- | **git** | para el panel de cambios; el resto funciona sin él |
68
- | **Al menos una CLI** | instalada y con sesión iniciada (tabla de abajo) |
69
-
70
- | CLI | Comando | Instalación |
71
- |---|---|---|
72
- | Claude Code | `claude` | [guía de instalación](https://docs.claude.com/en/docs/claude-code/setup) |
73
- | Codex | `codex` | [guía](https://learn.chatgpt.com/docs/codex/cli) |
74
- | OpenCode | `opencode` | [documentación](https://opencode.ai/docs/) |
75
- | Antigravity CLI | `agy` | [guía](https://antigravity.google/docs/cli/getting-started). Para su estado y su medidor, además, `node` en el `PATH` de la CLI |
76
-
77
- Agent Workbench **no** incluye ninguna CLI ni la descarga: usa las que ya tenés
78
- en el `PATH`. Si no encuentra ninguna, te lo dice y no abre sesiones.
79
-
80
- Probado sobre Windows 11 con PowerShell, que es la plataforma principal.
81
- macOS y Linux funcionan igual. En Linux, la dependencia `node-pty` no trae
82
- binario precompilado y se compila al instalar: hacen falta `python3`, `make` y
83
- un compilador de C++ (`build-essential` en Debian y Ubuntu).
84
-
85
- ---
86
-
87
- ## Instalar
88
-
89
- ```bash
90
- npm install -g agent-workbench
91
- ```
92
-
93
- Después, parado en el proyecto en el que quieras trabajar:
94
-
95
- ```bash
96
- agent-workbench
97
- ```
98
-
99
- Para probarlo una vez sin instalarlo, `npx agent-workbench` — baja unos 60 MB
100
- cada vez que la caché de npm está fría, casi todo del binario de la terminal.
101
- Para uso diario conviene la instalación global.
102
-
103
- El servidor imprime una URL con un token y la abre en el navegador:
104
-
105
- ```
106
- URL http://127.0.0.1:52341/?token=…
107
- ```
108
-
109
- Esa URL es la única forma de entrar. El token es distinto en cada arranque, y el
110
- servidor escucha solo en `127.0.0.1`.
111
-
112
- ### Memoria compartida
113
-
114
- Cada CLI guarda lo que aprende de un proyecto en su propia carpeta, y las demás
115
- no lo ven. La solapa **Memoria** instala un puente para que las cuatro usen la
116
- misma: notas en `.agents/memory/` del proyecto, que cada CLI lee y escribe
117
- —desde acá o desde su propia terminal— a través de `AGENTS.md` y `CLAUDE.md`.
118
-
119
- **Ver cambios** muestra archivo por archivo qué se va a escribir, y nada se toca
120
- hasta que confirmás. Al instalar importa la memoria que ya tenía Claude Code de
121
- ese proyecto. La memoria global de cada CLI no la escribe la aplicación: te da
122
- el fragmento para que lo pegues vos.
123
-
124
- <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-memoria.png" width="70%" alt="La solapa Memoria con el puente instalado para las cuatro CLIs y las notas importadas">
125
-
126
- ### Antigravity CLI: estado y medidor (opcional)
127
-
128
- Antigravity CLI no deja en ningún archivo si está trabajando, esperando que
129
- autorices una herramienta o libre, ni cuántos tokens lleva: eso lo publica sólo
130
- por su *status line*. Sin configurarla, sus pestañas funcionan igual —historial,
131
- conversación, modo, modelo— pero el punto de la pestaña dice que no se sabe y el
132
- medidor queda sin medir. Para activarlo:
133
-
134
- 1. Abrí una pestaña de Antigravity y tocá **Configurar**, al lado del medidor.
135
- 2. Copiá la línea que muestra el diálogo y fusionala con lo que ya tenga
136
- `~/.gemini/antigravity-cli/settings.json`. La aplicación no toca ese archivo:
137
- lo editás vos.
138
- 3. El diálogo pasa a **Configurada** solo en un par de segundos, o con
139
- **Comprobar**.
140
-
141
- La línea corre un script que la aplicación deja en su propia carpeta. Guarda sólo
142
- el estado, el modo, el modelo y los tokens de cada conversación, en esa misma
143
- carpeta; no guarda tu email, tu cuota, tu plan ni el costo, que la CLI también le
144
- pasa, y no imprime nada, así que la línea propia de la CLI queda como está. Una
145
- vez puesta, la corre **toda** sesión de `agy`, también las que abras fuera de la
146
- aplicación, y necesita `node` en el `PATH`. En Windows la línea entra a la
147
- carpeta del script en vez de nombrarlo entre comillas: la CLI la ejecuta con
148
- `cmd /c`, y ninguna comilla le llega viva a `node`.
149
-
150
- ### Copia propia (opcional)
151
-
152
- El historial de cada conversación es de su CLI, en su formato, y una CLI puede
153
- cambiarlo, podarlo o dejar de existir. La copia propia guarda lo mismo que ese
154
- historial —mensajes, entradas y resultados de herramientas, imágenes y la memoria
155
- de cada proyecto— en una carpeta tuya, en archivos que se leen sin la
156
- aplicación. **Arranca apagada.** El botón de la copia, en la cabecera de la barra
157
- de proyectos, abre un diálogo: primero **Medir** te dice cuánto ocuparía por CLI,
158
- sin escribir nada, y después **Activar** la enciende. Encendida, copia todo lo
159
- que la barra lista y no está archivado, y cada sesión que cambia la vuelve a
160
- copiar un minuto después de que quede quieta. Las archivadas no se copian, y
161
- archivar no borra lo ya copiado: la aplicación nunca borra nada de esa carpeta.
162
-
163
- Lo que la CLI ya no tiene sigue en la barra, marcado como copia, y se abre en
164
- Markdown; cada proyecto se exporta a Markdown. Y con la copia encendida y más de
165
- una CLI, el filtro de la barra ofrece **En conversaciones**: busca en el texto de
166
- todo lo copiado, de todas las CLIs.
167
-
168
- <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-buscador.png" width="40%" alt="El buscador en conversaciones: un acierto en una sesión de cada CLI, con su fragmento">
169
-
170
- Por defecto va dentro de la carpeta de configuración de la aplicación
171
- (`%APPDATA%\agent-workbench\vault` en Windows). **Cambiar carpeta…** la copia
172
- entera a otra —una sincronizada, otra unidad— sin pisar nada, y la anterior queda
173
- como estaba. Si la ponés en una carpeta sincronizada o en un repositorio, lo que
174
- guarda viaja con ella.
175
-
176
- Dos importadores de un solo uso traen historial de herramientas que la
177
- aplicación no lee. Se corren desde el código ([abajo](#desde-el-código)) y **no
178
- escriben nada sin `--write`**: sin él, dicen qué importarían.
179
-
180
- - `pnpm vault:import gemini-cli [--cwd <carpeta>]` — los chats que quedaron de
181
- Gemini CLI; `--cwd` nombra la carpeta donde lo usabas, para ubicarlos en su
182
- proyecto.
183
- - `pnpm vault:import antigravity-ide --workspace <carpeta>` — lo legible de las
184
- conversaciones del IDE de Antigravity en esa carpeta: la ficha de cada una y
185
- sus documentos `.md`. El contenido de la conversación está cifrado y queda
186
- marcada como historial parcial.
187
-
188
- ---
189
-
190
- ## Desde el código
191
-
192
- Para trabajar en la aplicación, o si preferís no instalar nada global:
193
-
194
- ```bash
195
- corepack enable pnpm
196
- pnpm install
197
- pnpm dev # Vite con recarga en caliente
198
- ```
199
-
200
- ```bash
201
- pnpm build # compila la interfaz una vez
202
- pnpm start # la sirve ya compilada, sin Vite
203
- ```
204
-
205
- ### Arranque de un clic en Windows
206
-
207
- ```bash
208
- pnpm package
209
- ```
210
-
211
- Compila la interfaz y deja un **`Agent Workbench.cmd`** en la raíz. Doble clic y
212
- listo: instala lo que falte, compila si hace falta y abre el navegador. Es un
213
- archivo de texto de veinte líneas; se puede leer entero antes de ejecutarlo.
214
-
215
- ---
216
-
217
- ## Atajos
218
-
219
- `Alt+T` nueva pestaña · `Alt+W` cerrar · `Alt+←/→` (o `Alt+RePág/AvPág`)
220
- cambiar de pestaña · `Alt+P` mostrar u ocultar el panel derecho · `Shift+Tab`,
221
- fuera de la terminal, volver a la pestaña anterior.
222
-
223
- El botón `?` de la barra superior los lista todos, junto con los de la CLI de la
224
- pestaña.
225
-
226
- **Por qué `Alt` y no `Ctrl`:** el navegador se queda con `Ctrl+T`, `Ctrl+W` y
227
- `Ctrl+Tab` para sus propias pestañas y el evento nunca llega a la página. No es
228
- algo que se arregle con `preventDefault`: no hay evento que prevenir.
229
-
230
- La aplicación captura exactamente esas combinaciones y ninguna más. `Shift+Tab`
231
- sólo cuando el foco no está en la terminal, porque adentro es la tecla con la que
232
- la CLI cambia de modo. Todo lo demás —`Esc`, `Esc Esc`, `Ctrl+C`, `Ctrl+R`,
233
- `Ctrl+O`, las flechas y sobre todo `Alt+V`, que es el pegado de imágenes— le
234
- llega intacto a la CLI.
235
-
236
- ---
237
-
238
- ## Qué hace la aplicación con tus datos
239
-
240
- Nada sale de tu máquina. Sin telemetría, sin analítica, sin ninguna llamada de
241
- red saliente. La excepción es la propia CLI trabajando: la que abrís en una
242
- pestaña, y el servidor de OpenCode de abajo, hablan con el proveedor del modelo
243
- como lo harían abiertas a mano.
244
-
245
- **Nunca toca tus credenciales.** No hay login en la interfaz: si no iniciaste
246
- sesión, lo hacés dentro de la terminal de la CLI y la aplicación ni se entera.
247
-
248
- **De cada CLI lee sólo esto, y en su carpeta no escribe nada.** Los
249
- importadores de la copia propia, cuando los corrés vos, leen además lo que dice
250
- [su sección](#copia-propia-opcional).
251
-
252
- | CLI | Lee | No abre nunca |
253
- |---|---|---|
254
- | Claude Code | de `~/.claude/`: `projects/` (el historial, y la memoria de cada proyecto para importarla), `sessions/` (si la CLI está esperando una respuesta) y `plans/`. Y para la solapa Planes, los `.md` que la conversación escribió dentro del proyecto o en la carpeta temporal de esa sesión: **sólo los que la conversación que estás mirando nombró**, sin recorrer ninguna carpeta | `.credentials.json` ni ningún token |
255
- | Codex | de `~/.codex/` (o `CODEX_HOME`): `sessions/` y `archived_sessions/` | `auth.json`, `config.toml` ni sus bases `*.sqlite` |
256
- | OpenCode | su base `opencode.db`, abierta en sólo lectura, y de ella sólo las tablas de sesiones, mensajes y partes; y su catálogo de modelos, para el tamaño de la ventana | `auth.json`, `opencode.json`, ni las tablas de cuentas, credenciales, permisos y sesiones compartidas |
257
- | Antigravity CLI | de `~/.gemini/antigravity-cli/`: los transcripts de cada conversación, `history.jsonl`, la última conversación de cada carpeta, de `settings.json` sólo el modelo y la status line, y su índice de conversaciones, de una **copia** temporal; de `~/.gemini/config/projects/`, la carpeta de cada proyecto | la configuración de MCP, su entrada en el llavero del sistema, el contenido de `conversations/`, ni `~/.gemini/antigravity/`, que es su IDE |
258
-
259
- Tres huellas que conviene saber:
260
-
261
- - **Leer la base de OpenCode** hace lo que SQLite hace con cualquier lector: crea
262
- sus archivos `-wal` y `-shm` si faltan y le cambia la fecha a `-shm`. Para
263
- leerla nunca corre un comando de OpenCode.
264
- - **Si el log propio de una pestaña de Antigravity no aparece**, lee los
265
- `log/cli-*.log` de la CLI, que traen tus mensajes y el email de la cuenta, sólo
266
- para encontrar el id de la conversación y sin guardar ninguna línea.
267
- - **Con OpenCode, la aplicación corre su servidor local**, `opencode serve`: uno
268
- solo, desde que abrís la primera pestaña de OpenCode hasta cinco minutos
269
- después de cerrar la última, o hasta que cerrás la aplicación. Escucha en
270
- `127.0.0.1`, con un puerto efímero y una contraseña distinta en cada arranque,
271
- aunque tu configuración de OpenCode diga otra cosa. La aplicación le pide sólo
272
- el estado de las sesiones, los permisos y preguntas pendientes, crear una
273
- sesión, contestar una pregunta y cortar una sesión: nada de tu configuración ni
274
- de tus cuentas.
275
-
276
- **No agrega variables de autenticación** al entorno de las CLIs que lanza. El
277
- entorno se hereda tal cual, con dos excepciones: **quita**
278
- `CLAUDE_CODE_CHILD_SESSION` —que apaga el guardado del historial— y te avisa con
279
- un cartel cuando lo hace; y al servidor de OpenCode le **agrega** una sola
280
- variable, `OPENCODE_SERVER_PASSWORD`, con esa contraseña de cada arranque. No es
281
- la de ninguna cuenta, y la variable no llega a ninguna pestaña: cada pestaña de
282
- OpenCode recibe la contraseña en su línea de comando (`attach --password`), donde
283
- la ven los demás procesos de tu usuario. Sólo sirve para ese servidor y deja de
284
- valer al cerrar la aplicación.
285
-
286
- **Lo que escribe la aplicación:**
287
-
288
- - **En su propio directorio de configuración:** las pestañas abiertas, la caché
289
- del índice, las notas, las sesiones archivadas, el script de la status line de
290
- Antigravity y, si la encendés, la copia propia (o en la carpeta que elijas).
291
- - **En la carpeta temporal:** las imágenes que pegás; el log de cada pestaña de
292
- Antigravity, que trae tus mensajes, con permisos sólo tuyos y borrado en el
293
- primer arranque pasadas 24 horas; y el transcript de una conversación que
294
- continuás en otra CLI, que se borra al cerrar esa pestaña o a las 24 horas.
295
- - **En tus proyectos, una sola cosa y sólo si confirmás:** la memoria
296
- compartida. Se limita a `.agents/memory/`, a lo que está entre sus marcas en
297
- `AGENTS.md` y `CLAUDE.md`, y a unas líneas al final de `.gitignore`.
298
-
299
- **El servidor escucha solo en `127.0.0.1`**, en un puerto efímero, con un token
300
- aleatorio por arranque que exigen el WebSocket y todas las rutas HTTP, y rechaza
301
- peticiones cuyo `Origin` no sea el propio.
302
-
303
- **El panel de git es de solo lectura.** No hay commit, stage ni push. Con un
304
- agente editando archivos, un botón que escribe historia es exactamente lo que
305
- después nadie sabe quién disparó.
306
-
307
- ![Un archivo del árbol, previsualizado con resaltado de sintaxis](https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/captura-archivos.png)
308
-
309
- ---
310
-
311
- ## Si algo falla
312
-
313
- **"No se encontró el comando `claude` en el PATH"**, seguido de "También
314
- funciona con: …" — la aplicación no encontró ninguna de las cuatro CLIs en el
315
- `PATH` del proceso que la corre. Comprobalo con `where claude` (o `which claude`),
316
- y lo mismo con `codex`, `opencode` o `agy`. Las CLIs se buscan al arrancar: si
317
- instalaste una con la aplicación abierta, volvé a arrancarla.
318
-
319
- **No aparece el historial de OpenCode.** Mirá la línea `Historial` del arranque.
320
- Si dice que esa versión de Node no trae `node:sqlite`, actualizá Node a la 22.13
321
- o posterior. Si no hay línea, no encontró la base: está en
322
- `~/.local/share/opencode/opencode.db`, o donde diga `OPENCODE_DB` o
323
- `XDG_DATA_HOME`.
324
-
325
- **Una pestaña de OpenCode no abre y dice "No se pudo arrancar el servidor de
326
- OpenCode".** La pestaña se engancha a un `opencode serve` que la aplicación
327
- lanza, y el motivo va después de los dos puntos. Si no queda claro, abrí
328
- `opencode` en una terminal común: si tampoco arranca, el problema es de esa
329
- instalación de OpenCode.
330
-
331
- **Una pestaña de OpenCode dice que el servidor se cerró.** El `opencode serve`
332
- terminó y la terminal de la pestaña quedó sin conexión. **Relanzar**, en la misma
333
- barra, abre otro servidor y vuelve a enganchar la pestaña a la misma sesión.
334
-
335
- **Una pestaña de Antigravity no muestra su estado ni el medidor.** Mirá la línea
336
- `Status line` del arranque, debajo de la CLI: si dice que no está configurada, o
337
- que hay otra, seguí los pasos de
338
- [arriba](#antigravity-cli-estado-y-medidor-opcional). Si la configuraste y la
339
- terminal de la CLI muestra `Statusline Error`, lo más probable es que `node` no
340
- esté en el `PATH` de esa sesión. Mientras la línea no publique nada, la pestaña
341
- se trata como si no la hubieras configurado.
342
-
343
- **`node-pty` no compila al instalar.** Es un módulo nativo. Normalmente baja un
344
- binario precompilado y no hace falta nada; si tu combinación de Node y
345
- plataforma no tiene uno, hay que compilarlo:
346
-
347
- - **Windows:** Visual Studio Build Tools con la carga de trabajo *Desarrollo
348
- para el escritorio con C++*, y Python 3.
349
- `npm install --global windows-build-tools` ya no se mantiene: instalá los
350
- Build Tools desde el instalador de Visual Studio.
351
- - **macOS:** `xcode-select --install`.
352
- - **Linux:** `build-essential` y `python3`.
353
-
354
- **La terminal se queda en blanco.** El renderer por defecto es canvas a
355
- propósito: con el addon WebGL la pestaña se congela en Windows 11 + Chrome
356
- aunque los datos lleguen. Si querés probarlo igual, agregá `?renderer=webgl` a
357
- la URL.
358
-
359
- **Un cartel dice que se quitó `CLAUDE_CODE_CHILD_SESSION`.** Pasa cuando
360
- arrancás la aplicación desde adentro de una sesión de la CLI de Claude Code. Esa
361
- variable apaga el guardado del historial, y sin historial no hay conversación ni
362
- medidor. La aplicación la quita y te avisa. En uso normal —una terminal común—
363
- ni aparece.
364
-
365
- **El panel de cambios dice que la carpeta no es un repositorio git** y sí lo es.
366
- Fijate que `git` esté en el `PATH`. Si el mensaje es otro, es el error que
367
- devolvió git, tal cual.
368
-
369
- ---
370
-
371
- ## Cómo está hecho
372
-
373
- Monorepo con pnpm, TypeScript en todo.
374
-
375
- ```
376
- packages/
377
- server/ Node, Express, ws, node-pty, chokidar — sirve la interfaz y hospeda las pty
378
- src/agents/ un adaptador por CLI: lo único del servidor que conoce a cada una
379
- web/ Vite, React, xterm.js, highlight.js
380
- shared/ los tipos del protocolo, sin `any` en los bordes
381
- ```
382
-
383
- Un solo proceso sirve la interfaz y el WebSocket en el mismo puerto: con un
384
- único origen, el chequeo de `Origin` y el token funcionan igual en desarrollo y
385
- en producción, sin excepciones que después nadie se acuerda de sacar.
386
-
387
- La decisión de arquitectura que ordena el resto: **las pty viven en un registro
388
- del servidor y el WebSocket es solo transporte.** Si el proceso muriera con el
389
- socket, un `Ctrl+R` sin querer borraría la sesión de trabajo. Cada terminal
390
- guarda un buffer de su salida reciente para repintar la pantalla cuando el
391
- cliente vuelve.
392
-
393
- La otra: **el servidor genérico no nombra ninguna CLI.** Lo que sabe de cada una
394
- —dónde guarda, cómo se lanza, qué se lee y qué no se abre nunca— vive en su
395
- adaptador, y la interfaz dibuja cada control según lo que esa CLI declara.
396
-
397
- [`CLAUDE.md`](CLAUDE.md) tiene las reglas y el mapa, y su índice lleva a
398
- [`docs/`](docs), donde vive el detalle de cada CLI: el formato real de su
399
- historial —que difiere de lo que uno esperaría—, qué se lee y qué no, y las
400
- trampas ya pisadas. [`CHECKLIST.md`](CHECKLIST.md) es lo que falta y la deuda
401
- abierta; [`docs/bitacora.md`](https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/docs/bitacora.md), la crónica hito por hito.
402
- [`CONTRIBUTING.md`](CONTRIBUTING.md), cómo trabajar en el repositorio. Las
403
- capturas de este README salen de `pnpm demo:shots`, sobre datos inventados.
404
-
405
- ---
406
-
407
- ## Licencia
408
-
409
- MIT. Ver [`LICENSE`](LICENSE).
410
-
411
- Agent Workbench es un proyecto independiente. Funciona con las CLIs de Claude
412
- Code, de Codex, de OpenCode y de Antigravity, pero no está afiliado a Anthropic,
413
- a OpenAI, a los autores de OpenCode ni a Google, ni respaldado por ellos.
1
+ # Agent Workbench
2
+
3
+ [![npm](https://img.shields.io/npm/v/agent-workbench)](https://www.npmjs.com/package/agent-workbench)
4
+ [![CI](https://github.com/cvelasquez/agent-workbench/actions/workflows/ci.yml/badge.svg)](https://github.com/cvelasquez/agent-workbench/actions/workflows/ci.yml)
5
+ [![license: MIT](https://img.shields.io/npm/l/agent-workbench)](LICENSE)
6
+
7
+ **One local interface for the Claude Code, Codex, OpenCode and Antigravity
8
+ CLIs.** It uses the CLIs you already have logged in, never touches your
9
+ credentials, and makes no network calls of its own.
10
+
11
+ ```bash
12
+ npx agent-workbench
13
+ ```
14
+
15
+ ![A tour: the conversation as cards, the changed files and a diff, one tab per CLI, and continuing a conversation with another CLI](https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/demo.webp)
16
+
17
+ It doesn't talk to any API. It launches the CLI you already have installed and
18
+ logged in —`claude`, `codex`, `opencode` or `agy`— inside a pseudo-terminal, and
19
+ adds around it what a terminal alone doesn't give you: tabs, browsable history,
20
+ the conversation as cards, a context meter, git status and a file tree.
21
+
22
+ The terminal is still the terminal. Everything you type reaches the CLI without
23
+ the app touching it.
24
+
25
+ ---
26
+
27
+ ## What it does
28
+
29
+ | | |
30
+ |---|---|
31
+ | **Tabs** | Several live sessions at once, from any of the CLIs, each in its own directory. They survive an `F5`: the processes live on the server, not in the browser tab. Each tab's dot tells you whether the agent is working, idle or waiting for an answer, on the CLIs that publish their status ([below](#multiple-clis)). |
32
+ | **Zero-cost startup** | When you open the app, tabs come back as **sleeping tabs**: you can read them in full, and they don't launch any CLI. You open the CLI with a button when you want to write to the agent. |
33
+ | **History** | Your projects and past conversations in the sidebar, with a filter, and those of all four CLIs together under each project, each with its badge. Opening one resumes it with its CLI, in the same session. **Archive history…** hides a CLI's sessions from before today in one go, and each project can be archived whole with one button: nothing is deleted, and both can be undone. |
34
+ | **Conversation** | The active session's messages, live, with tool calls collapsed and their results inside. Search, jump between matches, copy any message and, depending on the CLI, answer the agent's questions from the chat. |
35
+ | **Continue with…** | With more than one CLI installed, a conversation can be continued with another CLI in the same folder. The new agent starts from a transcript of the last turns, not from the context the previous one had. |
36
+ | **Search everything** | With more than one CLI and something saved in the local copy, the sidebar filter also searches the text of every saved conversation, not just their titles. |
37
+ | **Context meter** | Tokens from the last request against the model's context window. Tokens, never money. |
38
+ | **Changes** | Branch, ahead and behind against the upstream branch, worktrees, and the changed files with their diff. **Read-only.** |
39
+ | **Files** | The tree of the tab's directory, with search by name and a preview with syntax highlighting. A context menu to copy paths, insert them as `@path` or open the file with the system's default app. |
40
+ | **Plans** | The documents written by that conversation, rendered: the plans from plan mode, and also the `.md` files the agent created inside the project or in the session's temp folder. Only those named by the conversation you're viewing. |
41
+ | **Shared memory** | What agents learn about a project, in `.agents/memory/`, read and written by all four CLIs ([below](#shared-memory)). |
42
+ | **Local copy** | Optional. The history of all four CLIs in a folder of yours, in the app's own format, so you don't lose it if a CLI changes its format, deletes it, or you uninstall the CLI ([below](#local-copy-optional)). |
43
+ | **Nine languages** | The interface in English, Español, 简体中文, 日本語, Português (Brasil), Русский, 한국어, Français and Deutsch. It follows the browser's language and can be changed from the header, without reloading. |
44
+ | **Theme** | Light, dark, or the system's. |
45
+
46
+ <p>
47
+ <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/captura-cambios.png" width="49%" alt="The Changes panel: branch and changed files, by group">
48
+ <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/captura-diff.png" width="49%" alt="The diff of one of those files, in the same panel">
49
+ </p>
50
+
51
+ ### Multiple CLIs
52
+
53
+ With more than one CLI installed, every session in the sidebar and every tab
54
+ carries its CLI's badge, and the new-tab `+` opens with the one you used in that
55
+ project; its arrow lets you pick another. With just one, you see none of this.
56
+
57
+ <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/captura-clis.png" width="45%" alt="The projects sidebar with sessions from several CLIs, each with its badge, and the + menu with the four CLIs and their versions">
58
+
59
+ **Not every CLI exposes the same things.** Claude Code leaves everything the app
60
+ needs in its files. Codex leaves the history and the meter's tokens, but not its
61
+ status, its pending permissions, its questions or the model: its dot says the
62
+ status is unknown, there's no "waiting" notice and questions are answered in its
63
+ terminal. With OpenCode, the app starts a local OpenCode server when you open a
64
+ tab, and that's where its status, the notice that it's waiting for a permission
65
+ and the questions you answer from the chat come from. Antigravity CLI publishes
66
+ its status and tokens only if you configure its status line
67
+ ([below](#antigravity-cli-status-and-meter-optional)).
68
+
69
+ ---
70
+
71
+ ## Requirements
72
+
73
+ | | |
74
+ |---|---|
75
+ | **Node.js** | 20 or later. **To see the OpenCode history and the Antigravity CLI titles, 22.13 or later**: they're read with the SQLite that Node ships since that version. With an older one everything else works the same; the startup output warns about OpenCode, and Antigravity CLI lists its conversations without the titles or folders from its index |
76
+ | **git** | for the Changes panel; everything else works without it |
77
+ | **At least one CLI** | installed and logged in (table below) |
78
+
79
+ | CLI | Command | Installation |
80
+ |---|---|---|
81
+ | Claude Code | `claude` | [installation guide](https://docs.claude.com/en/docs/claude-code/setup) |
82
+ | Codex | `codex` | [guide](https://learn.chatgpt.com/docs/codex/cli) |
83
+ | OpenCode | `opencode` | [documentation](https://opencode.ai/docs/) |
84
+ | Antigravity CLI | `agy` | [guide](https://antigravity.google/docs/cli/getting-started). For its status and meter, also `node` in the CLI's `PATH` |
85
+
86
+ Agent Workbench does **not** bundle or download any CLI: it uses the ones you
87
+ already have in your `PATH`. If it doesn't find any, it tells you so and doesn't
88
+ open sessions.
89
+
90
+ Developed and used daily on Windows 11 with PowerShell, which is the main
91
+ platform. On macOS and Linux, CI installs the package and starts it on every
92
+ push —server up, a pseudo-terminal spawning a process—, but it sees less daily
93
+ use there: reports are welcome. On Linux, the `node-pty` dependency doesn't ship a prebuilt
94
+ binary and is compiled on install: you need `python3`, `make` and a C++ compiler
95
+ (`build-essential` on Debian and Ubuntu).
96
+
97
+ ---
98
+
99
+ ## Install
100
+
101
+ ```bash
102
+ npm install -g agent-workbench
103
+ ```
104
+
105
+ Then, from the folder of the project you want to work on:
106
+
107
+ ```bash
108
+ agent-workbench
109
+ ```
110
+
111
+ To try it once without installing it, `npx agent-workbench` — it downloads about
112
+ 60 MB whenever the npm cache is cold, mostly the terminal's native binary. For
113
+ daily use, the global install is the better choice.
114
+
115
+ The server prints a URL with a token and opens it in the browser:
116
+
117
+ ```
118
+ URL http://127.0.0.1:52341/?token=…
119
+ ```
120
+
121
+ That URL is the only way in. The token is different on every start, and the
122
+ server listens only on `127.0.0.1`.
123
+
124
+ ### Shared memory
125
+
126
+ Each CLI keeps what it learns about a project in its own folder, and the others
127
+ can't see it. The **Memory** tab installs a bridge so all four use the same one:
128
+ notes in the project's `.agents/memory/`, which each CLI reads and writes —from
129
+ here or from its own terminal— through `AGENTS.md` and `CLAUDE.md`.
130
+
131
+ **Preview changes** shows, file by file, what will be written, and nothing is
132
+ touched until you confirm. Installing imports the memory Claude Code already had
133
+ for that project. The app doesn't write each CLI's global memory: it gives you
134
+ the snippet to paste yourself.
135
+
136
+ <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/captura-memoria.png" width="70%" alt="The Memory tab with the bridge installed for the four CLIs and the imported notes">
137
+
138
+ ### Antigravity CLI: status and meter (optional)
139
+
140
+ Antigravity CLI doesn't record in any file whether it's working, waiting for you
141
+ to authorize a tool or idle, nor how many tokens it has used: it only publishes
142
+ that through its *status line*. Without it configured, its tabs work the same
143
+ —history, conversation, mode, model— but the tab's dot says the status is
144
+ unknown and the meter stays empty. To turn it on:
145
+
146
+ 1. Open an Antigravity tab and click **Configure**, next to the meter.
147
+ 2. Copy the line the dialog shows and merge it into whatever
148
+ `~/.gemini/antigravity-cli/settings.json` already has. The app doesn't touch
149
+ that file: you edit it.
150
+ 3. The dialog switches to **Configured** on its own within a couple of seconds,
151
+ or with **Check**.
152
+
153
+ The line runs a script the app keeps in its own folder. It saves only each
154
+ conversation's status, mode, model and tokens, in that same folder; it doesn't
155
+ save your email, quota, plan or cost, which the CLI also passes to it, and it
156
+ prints nothing, so the CLI's own status line stays as it is. Once set, **every**
157
+ `agy` session runs it, including those you open outside the app, and it needs
158
+ `node` in the `PATH`. On Windows the line changes into the script's folder
159
+ instead of naming the script in quotes: the CLI runs it with `cmd /c`, and no
160
+ quote reaches `node` intact.
161
+
162
+ ### Local copy (optional)
163
+
164
+ Each conversation's history belongs to its CLI, in its format, and a CLI can
165
+ change it, prune it or cease to exist. The local copy keeps the same as that
166
+ history —messages, tool inputs and results, images and each project's memory—
167
+ in a folder of yours, in files you can read without the app. **It's off by
168
+ default.** The local copy button, in the header of the projects sidebar, opens a
169
+ dialog: first **Measure** tells you how much space it would take per CLI,
170
+ without writing anything, and then **Turn on** enables it. Once on, it copies
171
+ everything the sidebar lists that isn't archived, and copies each session that
172
+ changes again a minute after it goes quiet. Archived sessions aren't copied, and
173
+ archiving doesn't delete what was already copied: the app never deletes anything
174
+ from that folder.
175
+
176
+ Whatever the CLI no longer has stays in the sidebar, marked as a copy, and opens
177
+ in Markdown; each project can be exported to Markdown. And with the copy on and
178
+ more than one CLI, the sidebar filter offers **In conversations**: it searches
179
+ the text of everything copied, from every CLI.
180
+
181
+ <img src="https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/captura-buscador.png" width="40%" alt="Search in conversations: a match in one session of each CLI, with its snippet">
182
+
183
+ By default it lives inside the app's configuration folder
184
+ (`%APPDATA%\agent-workbench\vault` on Windows). **Change folder…** copies all of
185
+ it to another one —a synced folder, another drive— without overwriting anything,
186
+ and the previous one stays as it was. If you put it in a synced folder or in a
187
+ repository, what it keeps travels with it.
188
+
189
+ Two one-off importers bring in history from tools the app doesn't read. They run
190
+ from source ([below](#from-source)) and **write nothing without `--write`**:
191
+ without it, they tell you what they would import.
192
+
193
+ - `pnpm vault:import gemini-cli [--cwd <folder>]` — the chats left over from
194
+ Gemini CLI; `--cwd` names the folder where you used it, to place them in their
195
+ project.
196
+ - `pnpm vault:import antigravity-ide --workspace <folder>` — whatever is
197
+ readable from the Antigravity IDE conversations in that folder: each one's
198
+ summary and its `.md` documents. The conversation content is encrypted, so it
199
+ is marked as partial history.
200
+
201
+ ---
202
+
203
+ ## From source
204
+
205
+ To work on the app, or if you'd rather not install anything globally:
206
+
207
+ ```bash
208
+ corepack enable pnpm
209
+ pnpm install
210
+ pnpm dev # Vite with hot reload
211
+ ```
212
+
213
+ ```bash
214
+ pnpm build # builds the interface once
215
+ pnpm start # serves the built interface, without Vite
216
+ ```
217
+
218
+ ### One-click start on Windows
219
+
220
+ ```bash
221
+ pnpm package
222
+ ```
223
+
224
+ It builds the interface and leaves an **`Agent Workbench.cmd`** in the root.
225
+ Double-click it and you're done: it installs whatever is missing, builds if
226
+ needed and opens the browser. It's a twenty-line text file; you can read all of
227
+ it before running it.
228
+
229
+ ---
230
+
231
+ ## Keyboard shortcuts
232
+
233
+ `Alt+T` new tab · `Alt+W` close · `Alt+←/→` (or `Alt+PgUp/PgDn`) switch tabs ·
234
+ `Alt+P` show or hide the right panel · `Shift+Tab`, outside the terminal, go
235
+ back to the previous tab.
236
+
237
+ The `?` button in the top bar lists them all, along with the shortcuts of the
238
+ tab's CLI.
239
+
240
+ **Why `Alt` and not `Ctrl`:** the browser keeps `Ctrl+T`, `Ctrl+W` and
241
+ `Ctrl+Tab` for its own tabs and the event never reaches the page. It's not
242
+ something `preventDefault` can fix: there's no event to prevent.
243
+
244
+ The app captures exactly those combinations and no others. `Shift+Tab` only
245
+ when focus isn't on the terminal, because inside it's the key the CLI uses to
246
+ switch modes. Everything else —`Esc`, `Esc Esc`, `Ctrl+C`, `Ctrl+R`, `Ctrl+O`,
247
+ the arrow keys and above all `Alt+V`, which pastes images— reaches the CLI
248
+ untouched.
249
+
250
+ ---
251
+
252
+ ## What the app does with your data
253
+
254
+ Nothing leaves your machine. No telemetry, no analytics, no outgoing network
255
+ calls at all. The exception is the CLI itself at work: the one you open in a
256
+ tab, and the OpenCode server described below, talk to the model provider just
257
+ as they would if you opened them by hand.
258
+
259
+ **It never touches your credentials.** There's no login in the interface: if
260
+ you aren't logged in, you log in inside the CLI's terminal and the app doesn't
261
+ even notice.
262
+
263
+ **From each CLI it reads only this, and it writes nothing in the CLI's
264
+ folder.** The local copy importers, when you run them, also read what
265
+ [their section](#local-copy-optional) says.
266
+
267
+ | CLI | Reads | Never opens |
268
+ |---|---|---|
269
+ | Claude Code | from `~/.claude/`: `projects/` (the history, and each project's memory, to import it), `sessions/` (whether the CLI is waiting for an answer) and `plans/`. And for the Plans tab, the `.md` files the conversation wrote inside the project or in that session's temp folder: **only those named by the conversation you're viewing**, without walking any folder | `.credentials.json` or any token |
270
+ | Codex | from `~/.codex/` (or `CODEX_HOME`): `sessions/` and `archived_sessions/` | `auth.json`, `config.toml` or its `*.sqlite` databases |
271
+ | OpenCode | its `opencode.db` database, opened read-only, and from it only the sessions, messages and parts tables; and its model catalog, for the context window size | `auth.json`, `opencode.json`, or the accounts, credentials, permissions and shared-sessions tables |
272
+ | Antigravity CLI | from `~/.gemini/antigravity-cli/`: each conversation's transcripts, `history.jsonl`, the last conversation of each folder, from `settings.json` only the model and the status line, and its conversation index, from a temporary **copy**; from `~/.gemini/config/projects/`, each project's folder | the MCP configuration, its entry in the system keychain, the contents of `conversations/`, or `~/.gemini/antigravity/`, which is its IDE |
273
+
274
+ Three footprints worth knowing about:
275
+
276
+ - **Reading the OpenCode database** does what SQLite does with any reader: it
277
+ creates its `-wal` and `-shm` files if they're missing and updates the
278
+ timestamp of `-shm`. It never runs an OpenCode command to read it.
279
+ - **If an Antigravity tab's own log doesn't show up**, it reads the CLI's
280
+ `log/cli-*.log` files, which contain your messages and the account's email,
281
+ only to find the conversation id, and without keeping any line.
282
+ - **With OpenCode, the app runs its local server**, `opencode serve`: just one,
283
+ from when you open the first OpenCode tab until five minutes after you close
284
+ the last one, or until you close the app. It listens on `127.0.0.1`, with an
285
+ ephemeral port and a different password on every start, even if your OpenCode
286
+ configuration says otherwise. The app only asks it for the sessions' status,
287
+ pending permissions and questions, to create a session, to answer a question
288
+ and to abort a session: nothing about your configuration or your accounts.
289
+
290
+ **It adds no authentication variables** to the environment of the CLIs it
291
+ launches. The environment is inherited as is, with two exceptions: it
292
+ **removes** `CLAUDE_CODE_CHILD_SESSION` —which turns off history saving— and
293
+ tells you with a banner when it does; and it **adds** a single variable to the
294
+ OpenCode server, `OPENCODE_SERVER_PASSWORD`, holding that per-start password. It
295
+ isn't any account's password, and the variable doesn't reach any tab: each
296
+ OpenCode tab gets the password on its command line (`attach --password`), where
297
+ other processes running as your user can see it. It only works for that server
298
+ and stops being valid when you close the app.
299
+
300
+ **What the app writes:**
301
+
302
+ - **In its own configuration directory:** the open tabs, the index cache, the
303
+ notes, the archived sessions, the Antigravity status line script and, if you
304
+ turn it on, the local copy (or in the folder you choose).
305
+ - **In the temp folder:** the images you paste; each Antigravity tab's log,
306
+ which contains your messages, readable only by you and deleted on the first
307
+ start once it's more than 24 hours old; and the transcript of a conversation
308
+ you continue in another CLI, deleted when you close that tab or after 24
309
+ hours.
310
+ - **In your projects, one thing only, and only if you confirm:** the shared
311
+ memory. It's limited to `.agents/memory/`, to what's between its markers in
312
+ `AGENTS.md` and `CLAUDE.md`, and to a few lines at the end of `.gitignore`.
313
+
314
+ **The server listens only on `127.0.0.1`**, on an ephemeral port, with a random
315
+ per-start token that the WebSocket and every HTTP route require, and it rejects
316
+ requests whose `Origin` isn't its own.
317
+
318
+ **The git panel is read-only.** No commit, stage or push. With an agent editing
319
+ files, a button that writes history is exactly the kind of thing where, later,
320
+ nobody knows who pressed it.
321
+
322
+ ![A file from the tree, previewed with syntax highlighting](https://raw.githubusercontent.com/cvelasquez/agent-workbench/main/assets/captura-archivos.png)
323
+
324
+ ---
325
+
326
+ ## Troubleshooting
327
+
328
+ **The "claude" command wasn't found in the PATH**, followed by "Also works
329
+ with: …" — the app didn't find any of the four CLIs in the `PATH` of the process
330
+ running it. Check with `where claude` (or `which claude`), and the same with
331
+ `codex`, `opencode` or `agy`. CLIs are looked up at startup: if you installed
332
+ one while the app was open, restart it.
333
+
334
+ **The OpenCode history doesn't show up.** Look at the `History` line in the
335
+ startup output. If it says that Node version doesn't include `node:sqlite`,
336
+ update Node to 22.13 or later. If there's no such line, it didn't find the
337
+ database: it's at `~/.local/share/opencode/opencode.db`, or wherever
338
+ `OPENCODE_DB` or `XDG_DATA_HOME` points.
339
+
340
+ **An OpenCode tab won't open and says "Couldn't start the OpenCode server".**
341
+ The tab attaches to an `opencode serve` the app launches, and the reason comes
342
+ after the colon. If it isn't clear, open `opencode` in a regular terminal: if it
343
+ doesn't start there either, the problem is with that OpenCode installation.
344
+
345
+ **An OpenCode tab says the server closed.** The `opencode serve` process ended
346
+ and the tab's terminal was left without a connection. **Relaunch**, in the same
347
+ bar, starts another server and reattaches the tab to the same session.
348
+
349
+ **An Antigravity tab doesn't show its status or the meter.** Look at the
350
+ `Status line` entry in the startup output, under the CLI: if it says it isn't
351
+ configured, or that there's another one, follow the steps
352
+ [above](#antigravity-cli-status-and-meter-optional). If you configured it and
353
+ the CLI's terminal shows `Statusline Error`, `node` is most likely not in that
354
+ session's `PATH`. Until the line publishes anything, the tab is treated as if
355
+ you hadn't configured it.
356
+
357
+ **`node-pty` doesn't compile on install.** It's a native module. It usually
358
+ downloads a prebuilt binary and nothing else is needed; if your combination of
359
+ Node and platform doesn't have one, it has to be compiled:
360
+
361
+ - **Windows:** Visual Studio Build Tools with the *Desktop development with C++*
362
+ workload, and Python 3.
363
+ `npm install --global windows-build-tools` is no longer maintained: install
364
+ the Build Tools from the Visual Studio installer.
365
+ - **macOS:** `xcode-select --install`.
366
+ - **Linux:** `build-essential` and `python3`.
367
+
368
+ **The terminal stays blank.** The default renderer is canvas on purpose: with
369
+ the WebGL addon the tab freezes on Windows 11 + Chrome even though the data
370
+ arrives. If you want to try it anyway, add `?renderer=webgl` to the URL.
371
+
372
+ **A banner says `CLAUDE_CODE_CHILD_SESSION` was removed.** It happens when you
373
+ start the app from inside a Claude Code CLI session. That variable turns off
374
+ history saving, and without history there's no conversation or meter. The app
375
+ removes it and lets you know. In normal use —a regular terminal— it never shows
376
+ up.
377
+
378
+ **The Changes panel says the folder isn't a git repository** and it is one.
379
+ Make sure `git` is in the `PATH`. If the message is a different one, it's the
380
+ error git returned, verbatim.
381
+
382
+ ---
383
+
384
+ ## How it's built
385
+
386
+ A pnpm monorepo, TypeScript throughout.
387
+
388
+ ```
389
+ packages/
390
+ server/ Node, Express, ws, node-pty, chokidar — serves the interface and hosts the ptys
391
+ src/agents/ one adapter per CLI: the only part of the server that knows each one
392
+ web/ Vite, React, xterm.js, highlight.js
393
+ shared/ the protocol types, with no `any` at the edges
394
+ ```
395
+
396
+ A single process serves the interface and the WebSocket on the same port: with
397
+ a single origin, the `Origin` check and the token work the same in development
398
+ and in production, with no exceptions that nobody remembers to remove later.
399
+
400
+ The architectural decision that shapes the rest: **the ptys live in a server
401
+ registry and the WebSocket is just transport.** If the process died with the
402
+ socket, an accidental `Ctrl+R` would wipe out the working session. Each terminal
403
+ keeps a buffer of its recent output to repaint the screen when the client comes
404
+ back.
405
+
406
+ The other one: **the generic server doesn't name any CLI.** What it knows about
407
+ each one —where it stores things, how it's launched, what is read and what is
408
+ never opened— lives in its adapter, and the interface draws each control based
409
+ on what that CLI declares.
410
+
411
+ [`ARCHITECTURE.md`](ARCHITECTURE.md) has the hard rules, the code map, what is
412
+ read from each CLI and what is never opened. [`CONTRIBUTING.md`](CONTRIBUTING.md)
413
+ covers how to work on the repository, [`SECURITY.md`](SECURITY.md) how to report
414
+ a vulnerability, and [`CHANGELOG.md`](CHANGELOG.md) what changed in each
415
+ version. Code comments are in Spanish. The screenshots in this README come from
416
+ `pnpm demo:shots`, on made-up data.
417
+
418
+ ---
419
+
420
+ ## License
421
+
422
+ MIT. See [`LICENSE`](LICENSE).
423
+
424
+ Agent Workbench is an independent project. It works with the Claude Code,
425
+ Codex, OpenCode and Antigravity CLIs, but it is not affiliated with or endorsed
426
+ by Anthropic, OpenAI, the OpenCode authors or Google.