ai-browser-bridge 0.1.1 → 0.3.0
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.es.md +49 -1
- package/README.he.md +57 -1
- package/README.md +120 -30
- package/README.zh.md +49 -1
- package/dist/bridge.js +11911 -7095
- package/dist/bridge.js.map +1 -1
- package/package.json +6 -6
package/README.es.md
CHANGED
|
@@ -55,7 +55,7 @@ Cuatro capas, cada una con un solo trabajo:
|
|
|
55
55
|
|------|------------|-----------------|
|
|
56
56
|
| **CLI** | Ink / React | Interfaz de terminal: panel de mensajes, barra de estado, menciones `@file`, comandos `/`. |
|
|
57
57
|
| **Navegador** | Playwright + Chrome DevTools Protocol | Controla la pestaña real de ChatGPT y captura respuestas. Los selectores están aislados en `src/browser/chatgpt-page.ts` para que los cambios de UI sean fáciles de arreglar. |
|
|
58
|
-
| **Servidor MCP** | MCP SDK +
|
|
58
|
+
| **Servidor MCP** | MCP SDK + Effect Schema | Expone las herramientas locales del repositorio a ChatGPT como handlers validados por esquema y en sandbox. |
|
|
59
59
|
| **Túnel** | Cloudflare Tunnel (`cloudflared`) | Da al servidor MCP local una URL HTTPS pública temporal que el conector de ChatGPT puede alcanzar — sin despliegue. |
|
|
60
60
|
|
|
61
61
|
**¿Por qué un túnel?** El conector MCP de ChatGPT llama a las herramientas por HTTPS, pero el servidor de herramientas se ejecuta en tu máquina. En lugar de desplegar nada, el bridge levanta un túnel efímero de Cloudflare (`*.trycloudflare.com`) frente al puerto local y sincroniza esa URL `…/mcp` con la app de ChatGPT al iniciar. (ngrok resolvería el mismo problema de alcance; se usa `cloudflared` de Cloudflare porque sus túneles rápidos no requieren cuenta ni token.)
|
|
@@ -116,6 +116,54 @@ pnpm verify:push # typecheck + test + build (ejecutar antes de push)
|
|
|
116
116
|
|
|
117
117
|
La cobertura se centra en las rutas sensibles a la seguridad — validación de sandbox, resolución de rutas locales del repositorio, la auto-exclusión de `.bridge/`, los almacenes de sesiones/checkpoints, permisos y conteo de contexto.
|
|
118
118
|
|
|
119
|
+
## Soporte de Google Flow
|
|
120
|
+
|
|
121
|
+
El bridge también puede controlar **[Google Labs Flow](https://labs.google/fx/tools/flow)** — el estudio de vídeo con IA de Google impulsado por Veo — con el mismo patrón Playwright/CDP. Flow es distinto en esencia a los proveedores de chat: es una superficie de **generación**, así que una «respuesta» es un **clip** renderizado y los adjuntos son **ingredientes** (imágenes de referencia).
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
bridge chrome start --provider flow # inicia sesión en Google; la cuenta necesita acceso a Flow (AI Pro/Ultra)
|
|
125
|
+
bridge ask --provider flow "a cat surfing a neon wave, cinematic, 8s"
|
|
126
|
+
bridge ask --provider flow "same scene, dawn light" --attach ref1.png ref2.png # hasta 3 ingredientes
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Más allá de generar, el bridge controla el **ciclo de vida de recursos** completo de Flow mediante los subcomandos `bridge flow` (cada uno se conecta a la pestaña de tu proyecto de Flow actual; añade `--json` para una salida legible por máquina):
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
bridge flow clips # lista los clips del proyecto actual (id + URL descargable)
|
|
133
|
+
bridge flow download # descarga el mp4 de cada clip en ./downloads/flow (o --id <clipId...>)
|
|
134
|
+
bridge flow reuse --id <clipId> # vuelve a añadir un clip al prompt como entrada ("Add to prompt")
|
|
135
|
+
bridge flow extend --id <clipId> # añade un clip a una escena ("Add to scene" de Flow)
|
|
136
|
+
bridge flow rename --id <clipId> --name "hero shot"
|
|
137
|
+
bridge flow delete --id <clipId> --yes # mueve un clip a la Papelera de Flow (recuperable)
|
|
138
|
+
bridge flow ingredients # lista las imágenes de referencia adjuntas al prompt
|
|
139
|
+
bridge flow ingredient-remove --id <mediaId> # desvincula un ingrediente
|
|
140
|
+
bridge flow ingredient-clear # desvincula todos los ingredientes
|
|
141
|
+
bridge flow projects # lista los proyectos
|
|
142
|
+
bridge flow project-rename --name "Launch teaser"
|
|
143
|
+
bridge flow project-delete --yes # elimina permanentemente el proyecto actual
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Los verbos destructivos (`delete`, `project-delete`) requieren `--yes`; borrar un clip lo mueve a la Papelera recuperable de Flow.
|
|
147
|
+
|
|
148
|
+
Los agentes sin acceso a shell obtienen el mismo ciclo de vida como **herramientas MCP `flow_*`** vía `bridge serve` — `flow_list_clips`, `flow_download_clips`, `flow_reuse_clip`, `flow_extend_clip`, `flow_rename_clip`, `flow_delete_clip`, `flow_list_ingredients`, `flow_remove_ingredient`, `flow_clear_ingredients`, `flow_list_projects`, `flow_rename_project`, `flow_delete_project`. Las herramientas destructivas (`flow_delete_clip`, `flow_delete_project`) requieren `confirm: true`.
|
|
149
|
+
|
|
150
|
+
**Qué funciona en Flow**
|
|
151
|
+
|
|
152
|
+
- Prompts de tomas desde la terminal que disparan la generación de Veo
|
|
153
|
+
- **Ingredientes** — adjunta hasta tres imágenes de referencia a un prompt, y lista / quita / limpia las que ya están adjuntas
|
|
154
|
+
- Una **referencia de clip** capturada (el `src` del vídeo / el href de descarga) devuelta como respuesta, de modo que un agente obtiene un puntero al resultado
|
|
155
|
+
- **CRUD de recursos** — lista / descarga / renombra / elimina clips, extiende o reutiliza un clip, gestiona los ingredientes del prompt, y lista / renombra / elimina proyectos — como comandos CLI `bridge flow …` **y** herramientas MCP `flow_*` vía `bridge serve`
|
|
156
|
+
- Reutiliza el mismo modelo de perfil compartido del bridge / puerto de depuración que todos los proveedores
|
|
157
|
+
|
|
158
|
+
**Qué no funciona en Flow (hoy)**
|
|
159
|
+
|
|
160
|
+
- **Conector MCP**, **`/task`**, **`/connector`**, **`/mcp`** — Flow no tiene interfaz de conector, así que el servidor MCP y el túnel de Cloudflare se omiten (igual que Gemini).
|
|
161
|
+
- **Controles de parada / a mitad de render** — cancelar un render de Veo en curso todavía no está implementado.
|
|
162
|
+
|
|
163
|
+
Flow requiere un plan **Google AI Pro/Ultra**. Como los renders de Veo tardan minutos, `--provider flow` espera una respuesta mucho más tiempo que los proveedores de chat.
|
|
164
|
+
|
|
165
|
+
**Mantenimiento de selectores:** los selectores de Flow fueron **verificados en vivo (LIVE-VERIFIED)** contra un editor de proyecto con sesión iniciada. Si Google cambia la UI, vuelve a capturarlos con `node src/scripts/maintain/captureProviderSelectors.mjs`, luego actualiza [`src/config/index.ts`](src/config/index.ts); la generación vive en [`src/features/providers/flow/flowPage.ts`](src/features/providers/flow/flowPage.ts) y el CRUD de recursos en [`src/features/providers/flow/flowAssets.ts`](src/features/providers/flow/flowAssets.ts).
|
|
166
|
+
|
|
119
167
|
## Limitaciones
|
|
120
168
|
|
|
121
169
|
- **Solo macOS** por ahora (ruta de Chrome fija y ayudantes `pbcopy`/`lsof`).
|
package/README.he.md
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
|------|-----------|--------|
|
|
60
60
|
| **CLI** | Ink / React | ממשק טרמינל: חלונית הודעות, שורת סטטוס, אזכורי `@file`, פקודות `/`. |
|
|
61
61
|
| **דפדפן** | Playwright + Chrome DevTools Protocol | מפעיל את לשונית ה-ChatGPT האמיתית ולוכד תשובות. הסלקטורים מבודדים ב-`src/browser/chatgpt-page.ts` כך ששינויי UI קלים לתיקון. |
|
|
62
|
-
| **שרת MCP** | MCP SDK +
|
|
62
|
+
| **שרת MCP** | MCP SDK + Effect Schema | חושף את כלי הריפו המקומיים ל-ChatGPT כ-handlers מאומתי-סכמה ומוגני-sandbox. |
|
|
63
63
|
| **מנהרה** | Cloudflare Tunnel (`cloudflared`) | מעניק לשרת ה-MCP המקומי כתובת HTTPS ציבורית זמנית שה-connector של ChatGPT יכול להגיע אליה — ללא פריסה. |
|
|
64
64
|
|
|
65
65
|
**למה בכלל מנהרה?** ה-connector של ChatGPT קורא לכלים דרך HTTPS, אבל שרת הכלים רץ על המחשב שלכם. במקום לפרוס משהו, ה-bridge מקים מנהרת Cloudflare זמנית (`*.trycloudflare.com`) מול הפורט המקומי ומסנכרן את כתובת ה-`…/mcp` הזו אל אפליקציית ChatGPT בעת ההפעלה. (ngrok היה פותר את אותה בעיית נגישות; נבחר `cloudflared` של Cloudflare מכיוון שמנהרות ה-quick שלו אינן דורשות חשבון או טוקן.)
|
|
@@ -136,6 +136,62 @@ pnpm verify:push # typecheck + test + build (להריץ לפני push)
|
|
|
136
136
|
|
|
137
137
|
הכיסוי מתמקד בנתיבים רגישי-בטיחות — אימות sandbox, רזולוציית נתיבים מקומיים לריפו, מנגנון ההתעלמות העצמית של `.bridge/`, מאגרי הסשנים/checkpoints, הרשאות וספירת הקשר.
|
|
138
138
|
|
|
139
|
+
## תמיכה ב-Google Flow
|
|
140
|
+
|
|
141
|
+
ה-bridge יכול להפעיל גם את **[Google Labs Flow](https://labs.google/fx/tools/flow)** — סטודיו הווידאו מבוסס-Veo של Google — עם אותה תבנית Playwright/CDP. Flow שונה במהותו מספקי הצ'אט: זהו משטח **יצירה (generation)**, כך ש"תשובה" היא **קליפ** מרונדר וקבצים מצורפים הם **מרכיבים (ingredients)** (תמונות ייחוס).
|
|
142
|
+
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
bridge chrome start --provider flow # התחברו ל-Google; החשבון צריך גישה ל-Flow (AI Pro/Ultra)
|
|
147
|
+
bridge ask --provider flow "a cat surfing a neon wave, cinematic, 8s"
|
|
148
|
+
bridge ask --provider flow "same scene, dawn light" --attach ref1.png ref2.png # עד 3 מרכיבים
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
<div dir="rtl">
|
|
152
|
+
|
|
153
|
+
מעבר ליצירה, ה-bridge מפעיל את **מחזור החיים המלא של הנכסים (assets)** ב-Flow דרך תת-פקודות `bridge flow` (כל אחת מתחברת ללשונית פרויקט ה-Flow הנוכחית שלכם; הוסיפו `--json` לפלט קריא למכונה):
|
|
154
|
+
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
bridge flow clips # הצגת הקליפים בפרויקט הנוכחי (id + כתובת ניתנת-להורדה)
|
|
159
|
+
bridge flow download # הורדת ה-mp4 של כל קליפ אל ./downloads/flow (או --id <clipId...>)
|
|
160
|
+
bridge flow reuse --id <clipId> # הוספת קליפ בחזרה לפרומפט כקלט ("Add to prompt")
|
|
161
|
+
bridge flow extend --id <clipId> # הוספת קליפ לסצנה ("Add to scene" של Flow)
|
|
162
|
+
bridge flow rename --id <clipId> --name "hero shot"
|
|
163
|
+
bridge flow delete --id <clipId> --yes # העברת קליפ לאשפת Flow (ניתן לשחזור)
|
|
164
|
+
bridge flow ingredients # הצגת תמונות הייחוס המצורפות לפרומפט
|
|
165
|
+
bridge flow ingredient-remove --id <mediaId> # ניתוק מרכיב יחיד
|
|
166
|
+
bridge flow ingredient-clear # ניתוק כל המרכיבים
|
|
167
|
+
bridge flow projects # הצגת הפרויקטים
|
|
168
|
+
bridge flow project-rename --name "Launch teaser"
|
|
169
|
+
bridge flow project-delete --yes # מחיקה לצמיתות של הפרויקט הנוכחי
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
<div dir="rtl">
|
|
173
|
+
|
|
174
|
+
פעלים הרסניים (`delete`, `project-delete`) דורשים `--yes`; מחיקת קליפ מעבירה אותו לאשפה הניתנת-לשחזור של Flow.
|
|
175
|
+
|
|
176
|
+
סוכנים ללא גישת shell מקבלים את אותו מחזור חיים בתור **כלי MCP מסוג `flow_*`** דרך `bridge serve` — `flow_list_clips`, `flow_download_clips`, `flow_reuse_clip`, `flow_extend_clip`, `flow_rename_clip`, `flow_delete_clip`, `flow_list_ingredients`, `flow_remove_ingredient`, `flow_clear_ingredients`, `flow_list_projects`, `flow_rename_project`, `flow_delete_project`. כלים הרסניים (`flow_delete_clip`, `flow_delete_project`) דורשים `confirm: true`.
|
|
177
|
+
|
|
178
|
+
**מה עובד ב-Flow**
|
|
179
|
+
|
|
180
|
+
- פרומפטים לצילומי שוט מהטרמינל שמפעילים יצירת Veo
|
|
181
|
+
- **מרכיבים (ingredients)** — צירוף של עד שלוש תמונות ייחוס לפרומפט, והצגה / הסרה / ניקוי של אלה שכבר מצורפות
|
|
182
|
+
- **הפניה לקליפ** שנלכדה (ה-`src` של הווידאו / קישור ההורדה) מוחזרת כתשובה, כך שהסוכן מקבל מצביע לתוצאה
|
|
183
|
+
- **CRUD של נכסים** — הצגה / הורדה / שינוי שם / מחיקה של קליפים, הרחבה או שימוש חוזר בקליפ, ניהול מרכיבי הפרומפט, והצגה / שינוי שם / מחיקה של פרויקטים — כפקודות CLI מסוג `bridge flow …` **וגם** ככלי MCP מסוג `flow_*` דרך `bridge serve`
|
|
184
|
+
- משתמש שוב באותו מודל של פרופיל bridge משותף / פורט דיבוג כמו כל ספק
|
|
185
|
+
|
|
186
|
+
**מה לא עובד ב-Flow (כרגע)**
|
|
187
|
+
|
|
188
|
+
- **connector של MCP**, **`/task`**, **`/connector`**, **`/mcp`** — ל-Flow אין ממשק connector, ולכן שרת ה-MCP ומנהרת ה-Cloudflare מדולגים (בדיוק כמו ב-Gemini).
|
|
189
|
+
- **בקרות עצירה / באמצע-רינדור** — ביטול רינדור של Veo תוך כדי ריצה עדיין לא מחובר.
|
|
190
|
+
|
|
191
|
+
Flow דורש תוכנית **Google AI Pro/Ultra**. מכיוון שרינדור ב-Veo אורך דקות, `--provider flow` ממתין לתשובה הרבה יותר זמן מספקי הצ'אט.
|
|
192
|
+
|
|
193
|
+
**תחזוקת סלקטורים:** הסלקטורים של Flow **אומתו בזמן אמת (LIVE-VERIFIED)** מול עורך פרויקט מחובר. אם Google משנה את ה-UI, בצעו לכידה מחדש עם `node src/scripts/maintain/captureProviderSelectors.mjs`, ואז עדכנו את [`src/config/index.ts`](src/config/index.ts); היצירה נמצאת ב-[`src/features/providers/flow/flowPage.ts`](src/features/providers/flow/flowPage.ts) וה-CRUD של הנכסים ב-[`src/features/providers/flow/flowAssets.ts`](src/features/providers/flow/flowAssets.ts).
|
|
194
|
+
|
|
139
195
|
## מגבלות
|
|
140
196
|
|
|
141
197
|
- **macOS בלבד** כיום (נתיב Chrome קשיח ועוזרי `pbcopy`/`lsof`).
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="assets/hero.png" alt="ai-browser-bridge — drive ChatGPT
|
|
2
|
+
<img src="assets/hero.png" alt="ai-browser-bridge — drive ChatGPT, Gemini, Claude, DeepSeek, Grok, Perplexity, and Flow from your terminal through Chrome" width="640" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# ai-browser-bridge
|
|
@@ -25,11 +25,11 @@ ChatGPT is at its best in the browser — real account state, the model picker,
|
|
|
25
25
|
## Features
|
|
26
26
|
|
|
27
27
|
- **Terminal-driven ChatGPT** — send prompts and stream replies without leaving the shell; the real browser conversation stays the source of truth.
|
|
28
|
-
- **
|
|
28
|
+
- **Nine providers, one command** — `chatgpt`, `gemini`, `claude`, `deepseek`, `grok`, `perplexity`, `duck` ([Duck.ai](https://duck.ai/chat)), `arena` ([Arena](https://arena.ai/code/direct) — Direct/Battle/Agent/Side-by-Side + model picker), plus `flow` (Google's Veo video studio — a generation surface, not a chat). Pick one with `--provider`, or **fan out** across several (`--provider claude,deepseek,duck`) and get every reply keyed by provider in one call.
|
|
29
29
|
- **Built for agents** — a stable non-interactive `bridge ask … --json` contract (never hangs in a pipe) plus an outbound MCP `ask` tool, so any agent can drive a web chat.
|
|
30
30
|
- **Sandboxed local tools over MCP** — every file operation is validated against the selected repo root; no arbitrary shell, allowlisted test commands only.
|
|
31
31
|
- **Browser actions as commands** — `/resume`, `/new`, `/model`, `/rewind`, `/stop`, `/context`, `/diff`, `/compact`, and more.
|
|
32
|
-
- **Repo-local sessions & transcripts** —
|
|
32
|
+
- **Repo-local sessions & transcripts when needed** — TUI and tool-enabled runs persist under `<repo>/.bridge/`; plain `bridge ask` stays stateless and only reuses the shared Chrome profile.
|
|
33
33
|
- **Safety controls** — permission modes (`read-only` / `ask` / `auto`) and automatic file checkpoints around every patch.
|
|
34
34
|
- **Project conventions** — custom commands plus `AGENTS.md` / `CLAUDE.md` are fed to ChatGPT for `/task` runs.
|
|
35
35
|
- **A real composer** — prompt history, reverse search, queued prompts, and `@file` mention autocomplete.
|
|
@@ -56,20 +56,20 @@ Four layers, each with one job:
|
|
|
56
56
|
| Layer | Tech | Responsibility |
|
|
57
57
|
|-------|------|----------------|
|
|
58
58
|
| **CLI** | Ink / React | Terminal UI: message pane, status line, `@file` mentions, `/commands`. |
|
|
59
|
-
| **Browser** | Playwright + Chrome DevTools Protocol |
|
|
60
|
-
| **MCP server** | MCP SDK +
|
|
61
|
-
| **Tunnel** | Cloudflare Tunnel (`cloudflared`) | Gives the local MCP server a temporary public HTTPS URL that
|
|
59
|
+
| **Browser** | Playwright + Chrome DevTools Protocol | Attaches to Chrome on the debug port and reuses one shared bridge Chrome profile. Lifecycle/status/cache code lives in `src/features/browser/`; provider selectors live under `src/features/providers/<name>/`. |
|
|
60
|
+
| **MCP server** | MCP SDK + Effect Schema | Exposes the local repo tools to ChatGPT, Claude, and Grok as schema-validated, sandboxed handlers. |
|
|
61
|
+
| **Tunnel** | Cloudflare Tunnel (`cloudflared`) | Gives the local MCP server a temporary public HTTPS URL that provider connectors can reach — no deployment required. |
|
|
62
62
|
|
|
63
|
-
**Why a tunnel at all?**
|
|
63
|
+
**Why a tunnel at all?** Provider MCP connectors call tools over HTTPS, but the tool server runs on your machine. Rather than deploy anything, the bridge spins up an ephemeral Cloudflare Tunnel (`*.trycloudflare.com`) in front of the local port and syncs that Streamable HTTP `…/mcp` URL into the provider app on startup. (ngrok would solve the same reachability problem; Cloudflare's `cloudflared` is used because its quick tunnels need no account or auth token. Grok's UI may show an `/sse` example — the bridge registers `/mcp` because cloudflared quick tunnels do not support SSE.)
|
|
64
64
|
|
|
65
65
|
## Quick start
|
|
66
66
|
|
|
67
67
|
**Prerequisites**
|
|
68
68
|
|
|
69
|
-
- **macOS** — Chrome is launched
|
|
69
|
+
- **macOS** — Chrome is launched with the macOS `open` command, and clipboard/process helpers use `pbcopy`/`lsof`.
|
|
70
70
|
- **Node.js ≥ 20** and **pnpm** (the repo pins `pnpm@10.14.0`).
|
|
71
|
-
- **Google Chrome** — the bridge drives
|
|
72
|
-
- **`cloudflared`** *(optional
|
|
71
|
+
- **Google Chrome or Chrome for Testing** — the bridge drives one shared bridge profile through a debug port. Sign in once in that bridge-launched window; every repo reuses it.
|
|
72
|
+
- **`cloudflared`** *(optional; ChatGPT, Claude, Grok)* — only needed for those providers to call local MCP tools. Without it the TUI still runs. Install with `brew install cloudflared`.
|
|
73
73
|
|
|
74
74
|
**Install & build**
|
|
75
75
|
|
|
@@ -80,21 +80,39 @@ pnpm install
|
|
|
80
80
|
pnpm build
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
**
|
|
83
|
+
**Start Chrome, then run (ChatGPT — default)**
|
|
84
84
|
|
|
85
85
|
```bash
|
|
86
|
-
node dist/bridge.js
|
|
86
|
+
node dist/bridge.js chrome start
|
|
87
87
|
node dist/bridge.js --repo /path/to/your/project
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
**
|
|
90
|
+
**Start Chrome, then run (Gemini web)**
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
|
-
node dist/bridge.js
|
|
93
|
+
node dist/bridge.js chrome start --provider gemini
|
|
94
94
|
node dist/bridge.js --provider gemini --repo /path/to/your/project
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
Prefer a global `bridge` command? Run `pnpm link --global` after building, then use `bridge`, `bridge
|
|
97
|
+
Prefer a global `bridge` command? Run `pnpm link --global` after building, then use `bridge`, `bridge chrome start`, `bridge ask "…"`, etc.
|
|
98
|
+
|
|
99
|
+
### Browser profile policy
|
|
100
|
+
|
|
101
|
+
Chrome 136+ no longer accepts remote debugging switches against the real default Chrome data directory. `ai-browser-bridge` therefore does **not** drive `~/Library/Application Support/Google/Chrome`. It always launches the browser on the debug port with one global bridge profile:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
~/.ai-browser-bridge/chrome-profile
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
That profile is the browser-login SSOT for the bridge. Sign in once in the bridge-launched Chrome window, then `bridge chrome start`, `bridge ask`, and the TUI reuse that login from any repo or shell root.
|
|
108
|
+
|
|
109
|
+
For release and automation work, Chrome's team recommends [Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing). Install it separately, then point the bridge at that app while keeping the same shared profile:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
AI_BROWSER_BRIDGE_CHROME_APP="Google Chrome for Testing" bridge chrome start
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The app override changes only which Chrome build is launched. The profile remains `~/.ai-browser-bridge/chrome-profile`; do not add per-repo Chrome profiles. See Chrome's [remote-debugging profile change](https://developer.chrome.com/blog/remote-debugging-port) for the upstream reason.
|
|
98
116
|
|
|
99
117
|
**One-shot, non-interactive**
|
|
100
118
|
|
|
@@ -114,7 +132,8 @@ node dist/bridge.js ask "hello" --provider gemini --repo /path/to/project
|
|
|
114
132
|
/stop stop the active response /restore <id> restore files from a checkpoint
|
|
115
133
|
/context model-aware context est. /status repo/model/context/session status
|
|
116
134
|
/diff ask ChatGPT to read diff /mcp connector + exposed tools
|
|
117
|
-
/task <request> project-agent task (MCP) /connector (re)run
|
|
135
|
+
/task <request> project-agent task (MCP) /connector (re)run MCP connector setup
|
|
136
|
+
/conversations list/search/open browser conversations
|
|
118
137
|
```
|
|
119
138
|
|
|
120
139
|
**File mentions** — reference repo files inline; they are resolved inside the repo and expanded before ChatGPT sees them:
|
|
@@ -126,6 +145,8 @@ compare @src/features/store/fileResolver.ts with @src/features/store/fileResolve
|
|
|
126
145
|
|
|
127
146
|
Paths that escape the repo root are skipped; files over 100 KB are summarized rather than inlined.
|
|
128
147
|
|
|
148
|
+
**Conversation search** — `bridge chat search "query" --json` searches ChatGPT history through the shared conversation catalog. Add `--open` to navigate the browser to the best match.
|
|
149
|
+
|
|
129
150
|
## Agents & fan-out
|
|
130
151
|
|
|
131
152
|
`bridge ask` is a stable, non-interactive surface for scripts and agents — it prints to stdout, never prompts in a pipe, and `--json` emits a machine-readable payload.
|
|
@@ -141,9 +162,9 @@ bridge ask --provider claude,deepseek,grok --json "same question, three models"
|
|
|
141
162
|
# "grok": { "ok": false, "error": "…", "elapsedMs": 300000 } }
|
|
142
163
|
```
|
|
143
164
|
|
|
144
|
-
Fan-out is **partial-failure tolerant**: the run exits non-zero only when *every* provider fails, or — with `--strict` — when *any* fails.
|
|
165
|
+
Fan-out is **partial-failure tolerant**: the run exits non-zero only when *every* provider fails, or — with `--strict` — when *any* fails. Run `bridge chrome start --provider <name>` and sign in if needed; the bridge reuses the shared bridge Chrome profile across repos.
|
|
145
166
|
|
|
146
|
-
The same fan-out core is exposed
|
|
167
|
+
The same fan-out core is exposed through outbound MCP tools — launch a stdio MCP server with `bridge serve` and any MCP-capable agent can call `ask({ prompt, providers })` or `search_conversations({ query, providers, limit })` as native tools instead of shelling out. Register it with Claude Code:
|
|
147
168
|
|
|
148
169
|
```bash
|
|
149
170
|
claude mcp add ai-browser-bridge -- bridge serve
|
|
@@ -159,20 +180,18 @@ claude mcp add ai-browser-bridge -- bridge serve
|
|
|
159
180
|
}
|
|
160
181
|
```
|
|
161
182
|
|
|
162
|
-
The `ask` tool takes `{ prompt, providers?, timeoutSeconds? }` and returns each provider's reply keyed by id (the same partial-failure-tolerant fan-out as `bridge ask`). Run `bridge
|
|
183
|
+
The `ask` tool takes `{ prompt, providers?, timeoutSeconds? }` and returns each provider's reply keyed by id (the same partial-failure-tolerant fan-out as `bridge ask`). The `search_conversations` tool takes `{ query, providers?, limit? }` and returns matching conversation URLs keyed by provider. Run `bridge chrome start --provider <name>` first, so the gateway has a signed-in Chrome session to drive. This is the opposite direction to the inbound MCP server, which exposes your repo tools *to* the web model.
|
|
163
184
|
|
|
164
185
|
> Provider adapters other than ChatGPT/Gemini ship with best-effort selectors marked `LIVE-VERIFY` — confirm them against the live signed-in site before relying on them in production.
|
|
165
186
|
|
|
166
187
|
## Where state lives
|
|
167
188
|
|
|
168
|
-
|
|
189
|
+
Persistent bridge state for a project is written **inside that project**, under `<repo>/.bridge/`:
|
|
169
190
|
|
|
170
191
|
```text
|
|
171
192
|
<repo>/.bridge/
|
|
172
193
|
├── .gitignore # a single "*", written automatically — see below
|
|
173
194
|
├── config.json # per-repo settings (includes `provider`: chatgpt | gemini)
|
|
174
|
-
├── chrome-profile/ # signed-in ChatGPT session for this repo
|
|
175
|
-
├── chrome-profile-gemini/ # signed-in Gemini session for this repo
|
|
176
195
|
├── sessions/<id>/ # metadata.json + append-only events.jsonl transcript
|
|
177
196
|
├── logs/<date>.jsonl # prompts, replies, and MCP tool-call summaries
|
|
178
197
|
├── checkpoints/ # before/after snapshots around each apply_patch
|
|
@@ -181,13 +200,15 @@ All bridge state for a project is written **inside that project**, under `<repo>
|
|
|
181
200
|
└── screenshots/ # /screenshot and /ui-qa captures
|
|
182
201
|
```
|
|
183
202
|
|
|
184
|
-
|
|
203
|
+
Plain `bridge ask` and `bridge chrome start` do not create repo-local state; they only reuse the shared Chrome profile. The bridge creates `<repo>/.bridge/` for persistent TUI sessions, tool-enabled asks (`bridge ask --tools`), checkpoints, exports, screenshots, or default attachment downloads.
|
|
204
|
+
|
|
205
|
+
When repo-local state is needed, the bridge writes `.bridge/.gitignore` containing a single `*`. That makes git ignore **everything** in the directory — session transcripts, logs, downloads, screenshots, and checkpoints — so none of it can be committed, even though it lives inside the repo. Chrome cookies for bridge-driven sessions stay in the shared bridge profile under `~/.ai-browser-bridge/chrome-profile`, not under `.bridge/`. `git add -A` and `git add .bridge/` both skip bridge state; only an explicit `git add -f` could override. The file is re-asserted on persistent runs, so deleting or tampering with it heals automatically.
|
|
185
206
|
|
|
186
207
|
> User-authored config meant to apply across **all** repos lives in your home directory: custom commands in `~/.ai-browser-bridge/commands/*.md` and user-level hooks in `~/.ai-browser-bridge/hooks.json`.
|
|
187
208
|
|
|
188
209
|
### Migrating from `chatgpt-local-bridge`
|
|
189
210
|
|
|
190
|
-
The package was renamed to **`ai-browser-bridge`**. Global user config moved from `~/.chatgpt-local-bridge/` to `~/.ai-browser-bridge/` — copy your `commands/` folder and `hooks.json` if you had them.
|
|
211
|
+
The package was renamed to **`ai-browser-bridge`**. Global user config moved from `~/.chatgpt-local-bridge/` to `~/.ai-browser-bridge/` — copy your `commands/` folder and `hooks.json` if you had them. Persistent repo-local state stays at `<repo>/.bridge/` (unchanged). Re-run `/connector` or `bridge ask --tools` once so ChatGPT picks up the renamed MCP connector app.
|
|
191
212
|
|
|
192
213
|
## Permissions & checkpoints
|
|
193
214
|
|
|
@@ -214,7 +235,7 @@ Coverage focuses on the safety-sensitive paths — sandbox validation, repo-loca
|
|
|
214
235
|
The bridge can drive **gemini.google.com** from the terminal with the same Playwright/CDP pattern as ChatGPT:
|
|
215
236
|
|
|
216
237
|
```bash
|
|
217
|
-
bridge
|
|
238
|
+
bridge chrome start --provider gemini
|
|
218
239
|
bridge --provider gemini --repo /path/to/project
|
|
219
240
|
bridge ask "explain this repo" --provider gemini --repo /path/to/project
|
|
220
241
|
```
|
|
@@ -224,21 +245,90 @@ bridge ask "explain this repo" --provider gemini --repo /path/to/project
|
|
|
224
245
|
- Terminal-driven prompts and captured replies
|
|
225
246
|
- `@file` mention expansion (read-only repo context inlined into prompts)
|
|
226
247
|
- Model detection/switching when the Gemini UI exposes a picker
|
|
227
|
-
-
|
|
248
|
+
- Reuses the same shared bridge profile/debug port model as every provider
|
|
228
249
|
|
|
229
250
|
**What does not work on Gemini web (today)**
|
|
230
251
|
|
|
231
|
-
- **MCP connector** — gemini.google.com has no custom connector UI like ChatGPT
|
|
232
|
-
- **`/task`, `/connector`, `/mcp`** — these require live MCP tools; use ChatGPT for those workflows.
|
|
252
|
+
- **MCP connector** — gemini.google.com has no custom connector UI like ChatGPT, Claude, or Grok. The bridge skips the MCP server and Cloudflare tunnel when `--provider gemini`.
|
|
253
|
+
- **`/task`, `/connector`, `/mcp`** — these require live MCP tools; use ChatGPT, Claude, or Grok for those workflows.
|
|
233
254
|
- **Attachment download** — `bridge download` is ChatGPT-only for now.
|
|
234
255
|
|
|
235
256
|
For full MCP on Gemini, use the official [Gemini API Remote MCP](https://ai.google.dev/gemini-api/docs/function-calling) or [Gemini CLI](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md) instead of the browser UI.
|
|
236
257
|
|
|
237
|
-
**Selector maintenance:** when Google changes the Gemini web UI, fix selectors only in [`src/
|
|
258
|
+
**Selector maintenance:** when Google changes the Gemini web UI, fix selectors only in [`src/features/providers/gemini/geminiPage.ts`](src/features/providers/gemini/geminiPage.ts).
|
|
259
|
+
|
|
260
|
+
## Arena.ai support
|
|
261
|
+
|
|
262
|
+
The bridge drives **[Arena](https://arena.ai/code/direct)** (LMSYS) with a dedicated adapter for the mode menu and model picker:
|
|
263
|
+
|
|
264
|
+
| Mode | `--model` token | URL |
|
|
265
|
+
|------|-----------------|-----|
|
|
266
|
+
| **Direct** (default) | `direct` | `/code/direct` — one model |
|
|
267
|
+
| **Battle Mode** | `battle` | `/code` — Option A/B (dual reply when both finish) |
|
|
268
|
+
| **Agent Mode** | `agent` | `/agent` — agent shell (best-effort) |
|
|
269
|
+
| **Side by Side** | `side` / `sbs` | `/text/side-by-side` — pick two models |
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
bridge chrome start --provider arena
|
|
273
|
+
bridge ask --provider arena "build a todo app" # Direct + Max
|
|
274
|
+
bridge ask --provider arena --model glm-5.1 "reply with pong" # pick a model
|
|
275
|
+
bridge ask --provider arena --model battle "compare two approaches" # dual Option A/B
|
|
276
|
+
bridge ask --provider arena --model direct/gemini-3-flash "hello" # mode + model
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Model search matches the in-UI picker (Search models + Text/Code/Image/Search tabs). Battle turns on Code Arena can take minutes (full site builds) — raise `--timeout` if needed. No MCP connector on Arena.
|
|
280
|
+
|
|
281
|
+
## Google Flow support
|
|
282
|
+
|
|
283
|
+
The bridge can also drive **[Google Labs Flow](https://labs.google/fx/tools/flow)** — Google's Veo-powered AI video studio — with the same Playwright/CDP pattern. Flow is different in kind from the chat providers: it is a **generation** surface, so a "reply" is a rendered **clip** and attachments are **ingredients** (reference images).
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
bridge chrome start --provider flow # sign in to Google; account needs Flow access (AI Pro/Ultra)
|
|
287
|
+
bridge ask --provider flow "a cat surfing a neon wave, cinematic, 8s"
|
|
288
|
+
bridge ask --provider flow "same scene, dawn light" --attach ref1.png ref2.png # up to 3 ingredients
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Beyond generating, the bridge drives Flow's full **asset lifecycle** through `bridge flow` subcommands (each attaches to your current Flow project tab; add `--json` for machine-readable output):
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
bridge flow clips # list clips in the current project (id + fetchable URL)
|
|
295
|
+
bridge flow download # download every clip's mp4 to ./downloads/flow (or --id <clipId...>)
|
|
296
|
+
bridge flow reuse --id <clipId> # add a clip back to the prompt as input ("Add to prompt")
|
|
297
|
+
bridge flow extend --id <clipId> # add a clip to a scene (Flow's "Add to scene")
|
|
298
|
+
bridge flow rename --id <clipId> --name "hero shot"
|
|
299
|
+
bridge flow delete --id <clipId> --yes # move a clip to Flow Trash (recoverable)
|
|
300
|
+
bridge flow ingredients # list reference images attached to the prompt
|
|
301
|
+
bridge flow ingredient-remove --id <mediaId> # detach one ingredient
|
|
302
|
+
bridge flow ingredient-clear # detach every ingredient
|
|
303
|
+
bridge flow projects # list projects
|
|
304
|
+
bridge flow project-rename --name "Launch teaser"
|
|
305
|
+
bridge flow project-delete --yes # permanently delete the current project
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Destructive verbs (`delete`, `project-delete`) require `--yes`; clip delete moves to Flow's recoverable Trash.
|
|
309
|
+
|
|
310
|
+
Agents without shell access get the same lifecycle as **`flow_*` MCP tools** over `bridge serve` — `flow_list_clips`, `flow_download_clips`, `flow_reuse_clip`, `flow_extend_clip`, `flow_rename_clip`, `flow_delete_clip`, `flow_list_ingredients`, `flow_remove_ingredient`, `flow_clear_ingredients`, `flow_list_projects`, `flow_rename_project`, `flow_delete_project`. Destructive tools (`flow_delete_clip`, `flow_delete_project`) require `confirm: true`.
|
|
311
|
+
|
|
312
|
+
**What works on Flow**
|
|
313
|
+
|
|
314
|
+
- Terminal-driven shot prompts that trigger Veo generation
|
|
315
|
+
- **Ingredients** — attach up to three reference images to a prompt, and list / remove / clear already-attached ones
|
|
316
|
+
- A captured **clip reference** (video `src` / download href) returned as the reply, so an agent gets a pointer to the result
|
|
317
|
+
- **Asset CRUD** — list / download / rename / delete clips, extend or reuse a clip, manage prompt ingredients, and list / rename / delete projects — as `bridge flow …` CLI commands **and** `flow_*` MCP tools over `bridge serve`
|
|
318
|
+
- Reuses the same shared bridge profile / debug-port model as every provider
|
|
319
|
+
|
|
320
|
+
**What does not work on Flow (today)**
|
|
321
|
+
|
|
322
|
+
- **MCP connector**, **`/task`**, **`/connector`**, **`/mcp`** — Flow has no connector UI, so the MCP server and Cloudflare tunnel are skipped (same as Gemini).
|
|
323
|
+
- **Stop / mid-render controls** — cancelling a Veo render in flight is not wired yet.
|
|
324
|
+
|
|
325
|
+
Flow requires a **Google AI Pro/Ultra** plan. Because Veo renders take minutes, `--provider flow` waits far longer for a response than the chat providers do.
|
|
326
|
+
|
|
327
|
+
**Selector maintenance:** Flow's selectors were **LIVE-VERIFIED** against a signed-in project editor. If Google changes the UI, recapture with `node src/scripts/maintain/captureProviderSelectors.mjs`, then update [`src/config/index.ts`](src/config/index.ts); generation lives in [`src/features/providers/flow/flowPage.ts`](src/features/providers/flow/flowPage.ts) and asset CRUD in [`src/features/providers/flow/flowAssets.ts`](src/features/providers/flow/flowAssets.ts).
|
|
238
328
|
|
|
239
329
|
## Limitations
|
|
240
330
|
|
|
241
|
-
- **macOS-only** today (
|
|
331
|
+
- **macOS-only** today (`open`, `pbcopy`, and `lsof` helpers).
|
|
242
332
|
- ChatGPT and Gemini browser selectors can break when the web UI changes; fixes are localized to the browser layer.
|
|
243
333
|
- Context usage is an **estimate** — the browser does not expose exact server-side token counts.
|
|
244
334
|
- The Cloudflare Tunnel requires `cloudflared` installed.
|
package/README.zh.md
CHANGED
|
@@ -55,7 +55,7 @@ ChatGPT 在浏览器中表现最佳——真实的账户状态、模型选择器
|
|
|
55
55
|
|----|------|------|
|
|
56
56
|
| **CLI** | Ink / React | 终端界面:消息面板、状态栏、`@file` 提及、`/` 命令。 |
|
|
57
57
|
| **浏览器** | Playwright + Chrome DevTools Protocol | 驱动真实的 ChatGPT 标签页并捕获响应。选择器隔离在 `src/browser/chatgpt-page.ts`,便于在 UI 变动时修复。 |
|
|
58
|
-
| **MCP 服务器** | MCP SDK +
|
|
58
|
+
| **MCP 服务器** | MCP SDK + Effect Schema | 将本地仓库工具以经过 schema 校验且沙箱化的处理器形式暴露给 ChatGPT。 |
|
|
59
59
|
| **隧道** | Cloudflare Tunnel (`cloudflared`) | 为本地 MCP 服务器提供一个临时的公共 HTTPS 地址,供 ChatGPT 连接器访问——无需部署。 |
|
|
60
60
|
|
|
61
61
|
**为什么需要隧道?** ChatGPT 的 MCP 连接器通过 HTTPS 调用工具,但工具服务器运行在你的机器上。与其部署任何东西,bridge 在本地端口前面启动一个临时的 Cloudflare 隧道(`*.trycloudflare.com`),并在启动时把该 `…/mcp` 地址同步到 ChatGPT 应用中。(ngrok 也能解决同样的可达性问题;这里使用 Cloudflare 的 `cloudflared`,因为它的快速隧道无需账户或令牌。)
|
|
@@ -116,6 +116,54 @@ pnpm verify:push # typecheck + test + build(推送前运行)
|
|
|
116
116
|
|
|
117
117
|
覆盖率聚焦于安全敏感路径——沙箱校验、仓库本地路径解析、`.bridge/` 自忽略保护、会话/检查点存储、权限以及上下文计数。
|
|
118
118
|
|
|
119
|
+
## Google Flow 支持
|
|
120
|
+
|
|
121
|
+
bridge 也可以驱动 **[Google Labs Flow](https://labs.google/fx/tools/flow)**——Google 基于 Veo 的 AI 视频工作室——采用与聊天类提供商相同的 Playwright/CDP 模式。Flow 与聊天类提供商本质不同:它是一个**生成**界面,因此“回复”是一段渲染出的**片段(clip)**,而附件则是**素材(ingredients)**(参考图像)。
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
bridge chrome start --provider flow # 登录 Google;账户需要 Flow 访问权限(AI Pro/Ultra)
|
|
125
|
+
bridge ask --provider flow "a cat surfing a neon wave, cinematic, 8s"
|
|
126
|
+
bridge ask --provider flow "same scene, dawn light" --attach ref1.png ref2.png # 最多 3 个素材
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
除了生成之外,bridge 还通过 `bridge flow` 子命令驱动 Flow 完整的**素材生命周期**(每个子命令都会附着到你当前的 Flow 项目标签页;添加 `--json` 可获得机器可读的输出):
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
bridge flow clips # 列出当前项目中的片段(id + 可获取的 URL)
|
|
133
|
+
bridge flow download # 将每个片段的 mp4 下载到 ./downloads/flow(或 --id <clipId...>)
|
|
134
|
+
bridge flow reuse --id <clipId> # 将片段作为输入重新加入提示词("Add to prompt")
|
|
135
|
+
bridge flow extend --id <clipId> # 将片段加入场景(Flow 的 "Add to scene")
|
|
136
|
+
bridge flow rename --id <clipId> --name "hero shot"
|
|
137
|
+
bridge flow delete --id <clipId> --yes # 将片段移入 Flow 回收站(可恢复)
|
|
138
|
+
bridge flow ingredients # 列出附加到提示词的参考图像
|
|
139
|
+
bridge flow ingredient-remove --id <mediaId> # 移除单个素材
|
|
140
|
+
bridge flow ingredient-clear # 移除全部素材
|
|
141
|
+
bridge flow projects # 列出项目
|
|
142
|
+
bridge flow project-rename --name "Launch teaser"
|
|
143
|
+
bridge flow project-delete --yes # 永久删除当前项目
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
破坏性动词(`delete`、`project-delete`)需要 `--yes`;删除片段会将其移入 Flow 可恢复的回收站。
|
|
147
|
+
|
|
148
|
+
没有 shell 访问权限的智能体可以通过 `bridge serve` 以 **`flow_*` MCP 工具**的形式获得相同的生命周期——`flow_list_clips`、`flow_download_clips`、`flow_reuse_clip`、`flow_extend_clip`、`flow_rename_clip`、`flow_delete_clip`、`flow_list_ingredients`、`flow_remove_ingredient`、`flow_clear_ingredients`、`flow_list_projects`、`flow_rename_project`、`flow_delete_project`。破坏性工具(`flow_delete_clip`、`flow_delete_project`)需要 `confirm: true`。
|
|
149
|
+
|
|
150
|
+
**Flow 上可用的功能**
|
|
151
|
+
|
|
152
|
+
- 从终端驱动、触发 Veo 生成的镜头提示词
|
|
153
|
+
- **素材(ingredients)** — 为提示词附加最多三张参考图像,并列出 / 移除 / 清空已附加的素材
|
|
154
|
+
- 捕获到的**片段引用**(视频的 `src` / 下载 href)作为回复返回,因此智能体能获得指向结果的指针
|
|
155
|
+
- **素材 CRUD** — 列出 / 下载 / 重命名 / 删除片段,扩展或复用片段,管理提示词素材,以及列出 / 重命名 / 删除项目 — 既可作为 `bridge flow …` CLI 命令,**也可**作为通过 `bridge serve` 提供的 `flow_*` MCP 工具
|
|
156
|
+
- 复用与所有提供商相同的共享 bridge 配置文件 / 调试端口模型
|
|
157
|
+
|
|
158
|
+
**Flow 上尚不可用的功能(当前)**
|
|
159
|
+
|
|
160
|
+
- **MCP 连接器**、**`/task`**、**`/connector`**、**`/mcp`** — Flow 没有连接器界面,因此会跳过 MCP 服务器和 Cloudflare 隧道(与 Gemini 相同)。
|
|
161
|
+
- **停止 / 渲染中途控制** — 尚未接入对进行中的 Veo 渲染的取消功能。
|
|
162
|
+
|
|
163
|
+
Flow 需要 **Google AI Pro/Ultra** 套餐。由于 Veo 渲染需要数分钟,`--provider flow` 等待响应的时间远比聊天类提供商更长。
|
|
164
|
+
|
|
165
|
+
**选择器维护:** Flow 的选择器已针对已登录的项目编辑器**实时验证(LIVE-VERIFIED)**。如果 Google 更改了 UI,请使用 `node src/scripts/maintain/captureProviderSelectors.mjs` 重新捕获,然后更新 [`src/config/index.ts`](src/config/index.ts);生成逻辑位于 [`src/features/providers/flow/flowPage.ts`](src/features/providers/flow/flowPage.ts),素材 CRUD 位于 [`src/features/providers/flow/flowAssets.ts`](src/features/providers/flow/flowAssets.ts)。
|
|
166
|
+
|
|
119
167
|
## 限制
|
|
120
168
|
|
|
121
169
|
- 目前**仅支持 macOS**(硬编码的 Chrome 路径以及 `pbcopy`/`lsof` 辅助)。
|