@plumpslabs/fennec-cli 1.14.2 → 1.14.4
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 +122 -69
- package/dist/index.js +1600 -436
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -57,6 +57,7 @@ pnpm build
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
Browser engines (optional for source install):
|
|
60
|
+
|
|
60
61
|
```bash
|
|
61
62
|
pnpm add playwright
|
|
62
63
|
npx playwright install chromium
|
|
@@ -126,7 +127,7 @@ Connect remote MCP clients with `{ "type": "remote", "url": "http://127.0.0.1:33
|
|
|
126
127
|
|
|
127
128
|
### 4. Ask your AI to diagnose issues
|
|
128
129
|
|
|
129
|
-
>
|
|
130
|
+
> _"Why is my app broken?"_ — AI uses Fennec to check browser console, network, and server logs simultaneously.
|
|
130
131
|
|
|
131
132
|
## CLI Commands
|
|
132
133
|
|
|
@@ -134,35 +135,38 @@ Fennec is both an MCP server **and** a CLI you can use directly in your terminal
|
|
|
134
135
|
|
|
135
136
|
### Server
|
|
136
137
|
|
|
137
|
-
| Command
|
|
138
|
-
|
|
139
|
-
| `fennec start`
|
|
140
|
-
| `fennec start --sse`
|
|
141
|
-
| `fennec start --transport sse` | Alias of `--sse`.
|
|
138
|
+
| Command | Description |
|
|
139
|
+
| ------------------------------ | ----------------------------------------------------------------------------- |
|
|
140
|
+
| `fennec start` | Start the MCP server (stdio transport). Default when no app command is given. |
|
|
141
|
+
| `fennec start --sse` | Start the MCP server over HTTP+SSE (experimental). |
|
|
142
|
+
| `fennec start --transport sse` | Alias of `--sse`. |
|
|
142
143
|
|
|
143
144
|
### Apps & Processes
|
|
144
145
|
|
|
145
|
-
| Command
|
|
146
|
-
|
|
147
|
-
| `fennec start <command> --name <name> [options]`
|
|
148
|
-
| `fennec ps [options]`
|
|
149
|
-
| `fennec status [name]`
|
|
150
|
-
| `fennec log <name\|pid> [options]`
|
|
151
|
-
| `fennec spawn [name] [--all]`
|
|
152
|
-
| `fennec stop <name\|--all
|
|
153
|
-
| `fennec restart <name\|pid
|
|
154
|
-
| `fennec kill <pid\|name\|all
|
|
155
|
-
| `fennec
|
|
156
|
-
| `fennec
|
|
157
|
-
| `fennec
|
|
158
|
-
| `fennec
|
|
159
|
-
| `fennec
|
|
160
|
-
| `fennec
|
|
161
|
-
| `fennec
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
146
|
+
| Command | Description |
|
|
147
|
+
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
148
|
+
| `fennec start <command> --name <name> [options]` | Launch an app as a supervised background daemon. Alias: `run`. |
|
|
149
|
+
| `fennec ps [options]` | List Fennec-tracked apps with live status. |
|
|
150
|
+
| `fennec status [name]` | System overview + top processes (tracked and system). |
|
|
151
|
+
| `fennec log <name\|pid> [options]` | Show (and follow) logs for a tracked app. |
|
|
152
|
+
| `fennec spawn [name] [name...] [--all]` | Re-spawn a stopped tracked app from its saved config. Accepts MULTIPLE names at once. |
|
|
153
|
+
| `fennec stop <name\|--all> [name...]` | Stop (pause) a tracked app but keep it in the registry. Accepts MULTIPLE names. Add `-y/--yes` to skip the confirmation prompt. |
|
|
154
|
+
| `fennec restart <name\|pid> [name...]` | Stop and re-spawn a tracked app from its saved config. Accepts MULTIPLE names at once. |
|
|
155
|
+
| `fennec kill <pid\|name\|all> [name...]` | Kill a process and remove it from the registry. Accepts MULTIPLE names at once. Add `-y/--yes` to skip the confirmation prompt. |
|
|
156
|
+
| `fennec group [name] [group]` | Assign a logical group to tracked apps (or list them). Bulk: `fennec group <group> <name...>`. `--unset` to clear. Group is preserved across `spawn`/`restart`. |
|
|
157
|
+
| `fennec adopt <pid> [--name <name>] [--port <port>]` | Adopt an externally-started process into Fennec tracking. |
|
|
158
|
+
| `fennec supervisor <start\|stop\|restart\|status>` | Manage the background supervisor that keeps `--restart` apps alive. |
|
|
159
|
+
| `fennec persist <enable\|disable\|status>` | Survive reboots — auto-start tracked apps after login (systemd/launchd/Windows). |
|
|
160
|
+
| `fennec dev <up\|down\|status\|restart <app>>` | Orchestrate a whole dev stack from `fennec.config.yaml`. |
|
|
161
|
+
| `fennec inspect <name\|pid>` | Compact, AI-safe snapshot (status + recent logs + error scan). |
|
|
162
|
+
| `fennec info <name>` | Detailed info for a tracked app. |
|
|
163
|
+
| `fennec rename <old> <new>` | Rename a tracked app. |
|
|
164
|
+
|
|
165
|
+
**`start` / `run` options:** `--name <name>` (recommended), `--port <port>` (Fennec waits until it accepts connections), `--cwd <dir>`, `--restart` (auto-restart on crash / port-down, survives terminal close), `--group <group>` (tag for scoped bulk ops), `--jsonl` (structured JSON-lines logs).
|
|
166
|
+
|
|
167
|
+
**`ps` options:** `-w/--watch` (live refresh), `--system/-a/--all` (include non-Fennec system processes), `--json`, `--name <filter>`, `--group <g>` (show only apps in group `<g>`), `--sort <cpu|mem|pid|name>`. The `MEM` column shows each running app's resident memory (RSS) cross-platform, so you can spot leaks from long-lived apps.
|
|
168
|
+
|
|
169
|
+
**Logical groups + bulk (multiple names):** tag apps with `fennec start <cmd> --name <n> --group <g>`, or retroactively with `fennec group <name> <g>` (existing entries too — `fennec group <name> --unset` clears). You can ALSO assign a group to MANY apps at once (bulk): `fennec group <group> <name1> <name2> ...` — e.g. `fennec group crm be-crm fe-crm` tags all three as `crm` in one shot (alternatively `fennec group --group crm be-crm fe-crm`). Then scope bulk ops to just that group: `fennec kill --group <g>`, `fennec stop --group <g>`, `fennec spawn --group <g>`, `fennec restart --group <g>`, `fennec ps --group <g>`. A bare group name as the positional (e.g. `fennec kill <g>`) is also accepted as shorthand. You can ALSO pass MULTIPLE names at once for one-shot bulk ops: `fennec stop be-crm fe-crm`, `fennec kill be-crm fe-crm -y`, `fennec restart be-crm fe-crm -y`, `fennec spawn be-crm fe-crm`. The group is PRESERVED across `spawn`/`restart` (stop→resume keeps the tag). Already-running entries in scope are reported as "already running" (never double-spawned); `--all` still targets **every** tracked app across all groups.
|
|
166
170
|
|
|
167
171
|
**`log` options:** `-f/--follow`, `--lines N`, `--since 10m|1h|2d`, `--level error|warn|info|debug`, `--json` (bounded, redacted, machine-readable for AI), `--no-redact`, `--clear`.
|
|
168
172
|
|
|
@@ -170,32 +174,47 @@ Fennec is both an MCP server **and** a CLI you can use directly in your terminal
|
|
|
170
174
|
|
|
171
175
|
### Observation
|
|
172
176
|
|
|
173
|
-
| Command
|
|
174
|
-
|
|
175
|
-
| `fennec attach <port>`
|
|
176
|
-
| `fennec attach-pid <pid>`
|
|
177
|
-
| `fennec attach-port <port>`
|
|
178
|
-
| `fennec pipe --name <name>`
|
|
179
|
-
| `fennec watch --file <path>` | Watch an existing log file.
|
|
177
|
+
| Command | Description |
|
|
178
|
+
| ---------------------------- | ---------------------------------------------------- |
|
|
179
|
+
| `fennec attach <port>` | Observe a running process by the port it listens on. |
|
|
180
|
+
| `fennec attach-pid <pid>` | Attach to and observe a process by its PID. |
|
|
181
|
+
| `fennec attach-port <port>` | Attach to and observe a process by its port. |
|
|
182
|
+
| `fennec pipe --name <name>` | Pipe stdin into a Fennec log watcher. |
|
|
183
|
+
| `fennec watch --file <path>` | Watch an existing log file. |
|
|
180
184
|
|
|
181
185
|
### Data
|
|
182
186
|
|
|
183
|
-
| Command
|
|
184
|
-
|
|
185
|
-
| `fennec export --file <path>` | Export tracked apps to a file.
|
|
186
|
-
| `fennec import <file>`
|
|
187
|
-
| `fennec cleanup`
|
|
187
|
+
| Command | Description |
|
|
188
|
+
| ----------------------------- | ---------------------------------------------------- |
|
|
189
|
+
| `fennec export --file <path>` | Export tracked apps to a file. |
|
|
190
|
+
| `fennec import <file>` | Import tracked apps from a file. |
|
|
191
|
+
| `fennec cleanup` | Remove dead/stale entries from the tracked registry. |
|
|
192
|
+
|
|
193
|
+
### Store & Doctor
|
|
194
|
+
|
|
195
|
+
Fennec persists everything — auth sessions, tracked processes, exports, plugin/workflow state — under **one global store**, by default `~/.fennec` (honors `FENNEC_HOME` / `FENNEC_DATA_DIR`), manageable from **any directory**. `--local` targets the per-project `.fennec` instead.
|
|
196
|
+
|
|
197
|
+
| Command | Description |
|
|
198
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
199
|
+
| `fennec store` | Overview of everything in the global store (counts, size, age). |
|
|
200
|
+
| `fennec store --local` | Same, for the project `.fennec`. |
|
|
201
|
+
| `fennec store session` | List saved auth sessions. |
|
|
202
|
+
| `fennec store session info <name>` | Show a session — cookie/localStorage **values are masked**; add `--show-secrets` to reveal. |
|
|
203
|
+
| `fennec store session rm <name>` | Delete a session (confirm prompt). |
|
|
204
|
+
| `fennec doctor` | Health + secret-surface checks: store permissions, synced-home leakage, embedded secrets in launch commands. |
|
|
188
205
|
|
|
189
206
|
### Configuration & Misc
|
|
190
207
|
|
|
191
|
-
| Command
|
|
192
|
-
|
|
193
|
-
| `fennec init`
|
|
194
|
-
| `fennec setup`
|
|
195
|
-
| `fennec install-browsers` | Install Playwright browser engines.
|
|
196
|
-
| `fennec sessions`
|
|
197
|
-
| `fennec
|
|
198
|
-
| `fennec
|
|
208
|
+
| Command | Description |
|
|
209
|
+
| ------------------------- | -------------------------------------------------------------------------- |
|
|
210
|
+
| `fennec init` | Generate a `fennec.config.yaml` in the current directory. |
|
|
211
|
+
| `fennec setup` | Interactively configure your MCP client for Fennec. |
|
|
212
|
+
| `fennec install-browsers` | Install Playwright browser engines. |
|
|
213
|
+
| `fennec sessions` | List saved browser auth sessions (alias of `fennec store session`). |
|
|
214
|
+
| `fennec store` | Unified view of everything Fennec persists (sessions, processes, exports). |
|
|
215
|
+
| `fennec doctor` | Health + secret-surface checks for the store. |
|
|
216
|
+
| `fennec health` | Health check of the Fennec environment. |
|
|
217
|
+
| `fennec help [command]` | Show help, or detailed help for a command. |
|
|
199
218
|
|
|
200
219
|
## Usage Examples
|
|
201
220
|
|
|
@@ -217,7 +236,7 @@ fennec log web -f
|
|
|
217
236
|
|
|
218
237
|
`fennec dev up` reads `fennec.config.yaml` and brings the whole stack up. It is
|
|
219
238
|
**idempotent**: already-running apps with unchanged config are skipped, apps whose
|
|
220
|
-
config changed are restarted, and an app whose port is already taken by
|
|
239
|
+
config changed are restarted, and an app whose port is already taken by _another_
|
|
221
240
|
process is **adopted** instead of spawning a conflicting duplicate.
|
|
222
241
|
|
|
223
242
|
```bash
|
|
@@ -227,6 +246,28 @@ fennec dev restart web # restart just one app
|
|
|
227
246
|
fennec dev down # stop everything (keeps it in the registry)
|
|
228
247
|
```
|
|
229
248
|
|
|
249
|
+
### Bulk operations & groups
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Tag apps into groups when starting (or retroactively with `fennec group`)
|
|
253
|
+
fennec start "npm run dev-be" --name be-crm --group crm
|
|
254
|
+
fennec start "npm run dev-fe" --name fe-crm --group crm
|
|
255
|
+
|
|
256
|
+
# One-shot bulk: pass MULTIPLE names at once
|
|
257
|
+
fennec stop be-crm fe-crm # pause both, keep them in the registry
|
|
258
|
+
fennec spawn be-crm fe-crm # re-spawn both paused apps
|
|
259
|
+
fennec kill be-crm fe-crm -y # kill + forget both
|
|
260
|
+
fennec restart be-crm fe-crm -y # restart both from saved config
|
|
261
|
+
|
|
262
|
+
# Group-scoped bulk: only that group is touched (other groups safe)
|
|
263
|
+
fennec kill --group crm -y
|
|
264
|
+
fennec stop --group crm
|
|
265
|
+
fennec ps --group crm # MEM column shows each app's live RSS
|
|
266
|
+
|
|
267
|
+
# Global: --all still hits EVERY tracked app across all groups
|
|
268
|
+
fennec stop --all
|
|
269
|
+
```
|
|
270
|
+
|
|
230
271
|
### Adopt a process an AI agent started via raw bash
|
|
231
272
|
|
|
232
273
|
An AI agent (or you) sometimes launches a server with plain bash. Fennec can take
|
|
@@ -272,8 +313,8 @@ Key configuration options (see [full reference](../../docs/configuration.md)):
|
|
|
272
313
|
|
|
273
314
|
```yaml
|
|
274
315
|
browser:
|
|
275
|
-
adapter: auto
|
|
276
|
-
type: chromium
|
|
316
|
+
adapter: auto # auto, cdp, or playwright
|
|
317
|
+
type: chromium # chromium, firefox, or webkit
|
|
277
318
|
headless: true
|
|
278
319
|
viewport:
|
|
279
320
|
width: 1280
|
|
@@ -281,7 +322,7 @@ browser:
|
|
|
281
322
|
|
|
282
323
|
process:
|
|
283
324
|
maxProcesses: 10
|
|
284
|
-
spawnAllowlist:
|
|
325
|
+
spawnAllowlist: # only these commands may be spawned
|
|
285
326
|
- npm
|
|
286
327
|
- node
|
|
287
328
|
- pnpm
|
|
@@ -293,13 +334,13 @@ process:
|
|
|
293
334
|
security:
|
|
294
335
|
sandbox: true
|
|
295
336
|
allowProcessSpawn: true
|
|
296
|
-
allowProcessKill: false
|
|
337
|
+
allowProcessKill: false # off by default — opt in explicitly
|
|
297
338
|
allowJSEvaluation: true
|
|
298
339
|
|
|
299
340
|
lazyContext:
|
|
300
|
-
level1: true
|
|
301
|
-
level2: false
|
|
302
|
-
level3: false
|
|
341
|
+
level1: true # Auto-attach summary on errors
|
|
342
|
+
level2: false # Attach detail on expand
|
|
343
|
+
level3: false # Attach raw data on request
|
|
303
344
|
|
|
304
345
|
correlation:
|
|
305
346
|
windowMs: 500
|
|
@@ -312,20 +353,20 @@ correlation:
|
|
|
312
353
|
Fennec ships with **sandbox mode enabled by default** and conservative process
|
|
313
354
|
permissions. Environment variables override the config file:
|
|
314
355
|
|
|
315
|
-
| Variable
|
|
316
|
-
|
|
317
|
-
| `FENNEC_DATA_DIR`
|
|
318
|
-
| `FENNEC_SANDBOX`
|
|
319
|
-
| `FENNEC_SECURITY_ALLOW_PROCESS_SPAWN`
|
|
320
|
-
| `FENNEC_SECURITY_ALLOW_PROCESS_KILL`
|
|
321
|
-
| `FENNEC_SECURITY_ALLOW_JS_EVALUATION`
|
|
322
|
-
| `FENNEC_TRANSPORT_TYPE`
|
|
323
|
-
| `FENNEC_PORT`
|
|
324
|
-
| `FENNEC_BROWSER_TYPE`
|
|
325
|
-
| `FENNEC_HEADLESS`
|
|
326
|
-
| `FENNEC_DEFAULT_TIMEOUT`
|
|
327
|
-
| `FENNEC_VIEWPORT_WIDTH` / `FENNEC_VIEWPORT_HEIGHT` | Viewport size.
|
|
328
|
-
| `FENNEC_LOG_LEVEL`
|
|
356
|
+
| Variable | Effect |
|
|
357
|
+
| -------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
358
|
+
| `FENNEC_DATA_DIR` | Override where Fennec stores tracked state & logs (default `~/.fennec`). |
|
|
359
|
+
| `FENNEC_SANDBOX` | `false` disables the sandbox (permits more operations). |
|
|
360
|
+
| `FENNEC_SECURITY_ALLOW_PROCESS_SPAWN` | `true` allows the AI to spawn new processes. |
|
|
361
|
+
| `FENNEC_SECURITY_ALLOW_PROCESS_KILL` | `true` allows the AI to kill processes. |
|
|
362
|
+
| `FENNEC_SECURITY_ALLOW_JS_EVALUATION` | `true` allows in-page JS evaluation. |
|
|
363
|
+
| `FENNEC_TRANSPORT_TYPE` | `stdio` (default) or `sse`. |
|
|
364
|
+
| `FENNEC_PORT` | Port for SSE transport (default `3333`). |
|
|
365
|
+
| `FENNEC_BROWSER_TYPE` | `chromium` \| `firefox` \| `webkit`. |
|
|
366
|
+
| `FENNEC_HEADLESS` | `false` to run headed. |
|
|
367
|
+
| `FENNEC_DEFAULT_TIMEOUT` | Browser default timeout (ms). |
|
|
368
|
+
| `FENNEC_VIEWPORT_WIDTH` / `FENNEC_VIEWPORT_HEIGHT` | Viewport size. |
|
|
369
|
+
| `FENNEC_LOG_LEVEL` | `debug` \| `info` \| `warn` \| `error`. |
|
|
329
370
|
|
|
330
371
|
Security features:
|
|
331
372
|
|
|
@@ -364,6 +405,18 @@ FENNEC_BROWSER_TYPE=webkit fennec start
|
|
|
364
405
|
- [Security Model](https://github.com/plumpslabs/fennec/blob/main/docs/security-model.md)
|
|
365
406
|
- [GitHub Repository](https://github.com/plumpslabs/fennec)
|
|
366
407
|
|
|
408
|
+
## Memory & Garbage Safety
|
|
409
|
+
|
|
410
|
+
Fennec is built to **not** leak memory or orphan processes on your machine:
|
|
411
|
+
|
|
412
|
+
- 🌳 **Process-tree kills** — `stop`/`kill`/`spawn`/`restart` tear down the _entire_ process tree (npm → vite → esbuild on POSIX; `taskkill /T /F` on Windows), so no orphaned children are left "nyampah".
|
|
413
|
+
- 🧹 **Browser contexts are fully torn down** on session destroy (page **and** its `BrowserContext` — cookies, cache, service workers), not just the page.
|
|
414
|
+
- ⏳ **Idle-session GC** runs on a timer (not only when the session cap is hit): idle sessions and over-TTL sessions are destroyed automatically.
|
|
415
|
+
- 📑 **Tab caps** — opening many tabs (`tab_new` / `context_new`) auto-closes the oldest non-active page so contexts can't accumulate.
|
|
416
|
+
- ♻️ **Context rotation** — long-lived contexts are periodically recycled (`config.session.rotationIntervalSecs`, default 0 = off). The old `BrowserContext` is closed and a fresh one built with your cookies/localStorage preserved (via storageState) and the current URL reloaded, so a session that's open for hours can't grow unbounded in DOM/listeners/workers. Trigger on demand with the `context_rotate` tool too.
|
|
417
|
+
- 🪵 **Bounded logs** — app logs are rotated (10 MB × 3 files) so disk never fills.
|
|
418
|
+
- 🔌 **Graceful shutdown** — `SIGTERM`/`SIGINT` closes the browser and all tracked daemons; `ps` even shows a live **MEM** (RSS) column so you can spot leaks.
|
|
419
|
+
|
|
367
420
|
## License
|
|
368
421
|
|
|
369
422
|
MIT — see [LICENSE](https://github.com/plumpslabs/fennec/blob/main/LICENSE) for details.
|