ghostrun-cli 1.0.0 → 1.0.2

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,10 +1,62 @@
1
1
  # GhostRun
2
2
 
3
- Record once. Replay as a ghost.
3
+ [![npm version](https://badge.fury.io/js/ghostrun-cli.svg)](https://www.npmjs.com/package/ghostrun-cli)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
6
+ [![Downloads](https://img.shields.io/npm/dm/ghostrun-cli)](https://www.npmjs.com/package/ghostrun-cli)
4
7
 
5
- Memory-driven browser automation and API testing CLI — record real browser flows, replay them headlessly, test REST APIs with assertions and variable extraction, run load tests, detect failures with AI analysis, and chat with your test suite. Entirely local.
8
+ **Record once. Replay as a ghost.**
6
9
 
7
- ![GhostRun Demo](demo/out/ghostrun-demo.gif)
10
+ GhostRun is a local-first CLI for browser automation, API testing, and load testing — all in one tool. Record a real browser flow, replay it headlessly, test REST APIs with assertions, and run VU-based load tests. No cloud. No account. Runs entirely on your machine.
11
+
12
+ ---
13
+
14
+ ## Table of Contents
15
+
16
+ - [What is GhostRun?](#what-is-ghostrun)
17
+ - [Install](#install)
18
+ - [Quick Start](#quick-start)
19
+ - [The Three Modes](#the-three-modes)
20
+ - [Browser Automation](#1-browser-automation)
21
+ - [API Testing](#2-api-testing)
22
+ - [Load Testing](#3-load-testing)
23
+ - [Commands](#commands)
24
+ - [Setup](#setup)
25
+ - [Recording](#recording)
26
+ - [Running Flows](#running-flows)
27
+ - [Flow Management](#flow-management)
28
+ - [Environments](#environments)
29
+ - [Run History](#run-history)
30
+ - [Scheduling](#scheduling)
31
+ - [Test Suites](#test-suites)
32
+ - [Web Dashboard](#web-dashboard)
33
+ - [Chat Assistant](#chat-assistant)
34
+ - [MCP Server](#mcp-server)
35
+ - [Reports](#reports)
36
+ - [Selector Repair](#selector-repair)
37
+ - [Screenshot Diff](#screenshot-diff)
38
+ - [CI/CD Integration](#cicd-integration)
39
+ - [AI Setup](#ai-setup)
40
+ - [Data & Privacy](#data--privacy)
41
+ - [Contributing](#contributing)
42
+ - [Trust & Transparency](#trust--transparency)
43
+ - [License](#license)
44
+
45
+ ---
46
+
47
+ ## What is GhostRun?
48
+
49
+ Most testing tools make you choose — browser OR API OR load testing. GhostRun does all three from a single CLI, using the same flow format.
50
+
51
+ | What you want to do | How GhostRun helps |
52
+ |---------------------|-------------------|
53
+ | Test a web UI regression | Record a browser flow once, replay headlessly on every deploy |
54
+ | Test a REST API | Write or import flows with HTTP requests, assertions, and variable extraction |
55
+ | Stress-test an endpoint | Run any API flow as a load test with configurable VUs and duration |
56
+ | Monitor a live site | Schedule flows to run on a cron and alert on failure |
57
+ | Give AI agents your test suite | MCP server exposes all flows as tools for Claude, Cursor, etc. |
58
+
59
+ Everything is stored locally in SQLite (`~/.ghostrun/`). No accounts, no telemetry, no cloud.
8
60
 
9
61
  ---
10
62
 
@@ -12,105 +64,116 @@ Memory-driven browser automation and API testing CLI — record real browser flo
12
64
 
13
65
  ```bash
14
66
  npm install -g ghostrun-cli
67
+ ghostrun init # guided setup: installs Chromium, configures AI (optional)
15
68
  ```
16
69
 
17
70
  Or run from source:
18
71
 
19
72
  ```bash
20
- git clone https://github.com/your-org/ghostrun
21
- cd ghostrun
22
- npm install
23
- npm run build
24
- node ghostrun.js init # guided setup
73
+ git clone https://github.com/TechBuiltBySharan/ghostrun
74
+ cd ghostrun && npm install && npm run build
75
+ node ghostrun.js init
25
76
  ```
26
77
 
78
+ **Requirements:** Node 18+, macOS/Linux/Windows
79
+
27
80
  ---
28
81
 
29
82
  ## Quick Start
30
83
 
84
+ **Record a browser flow:**
85
+
31
86
  ```bash
32
- ghostrun init # setup wizard: installs Chromium, configures AI
33
- ghostrun learn https://yourapp.com # record a browser flow
34
- ghostrun api:learn # import a .flow.json with API actions
35
- ghostrun run <flow-id> # replay headlessly (browser or API)
36
- ghostrun perf:run <flow-id> # load test an API flow (VU-based)
37
- ghostrun chat # AI chat: ask questions, run flows by name
38
- ghostrun serve --ui # web dashboard at http://localhost:3000
87
+ ghostrun learn https://yourapp.com # real browser opens, you interact, GhostRun records
88
+ ghostrun run "My Flow" # replay headlessly
89
+ ```
90
+
91
+ **Test an API:**
92
+
93
+ ```bash
94
+ ghostrun flow:from-curl "curl -X POST https://api.example.com/login \
95
+ -H 'Content-Type: application/json' \
96
+ -d '{\"email\":\"user@example.com\",\"password\":\"secret\"}'"
97
+ ghostrun run "POST /login"
98
+ ```
99
+
100
+ **Run a load test:**
101
+
102
+ ```bash
103
+ ghostrun perf:run "POST /login" --vus 20 --duration 30
39
104
  ```
40
105
 
41
106
  ---
42
107
 
43
- ## What Needs AI vs What Doesn't
44
-
45
- Every core feature works with zero AI. AI is an optional enhancement.
46
-
47
- | Feature | AI Required? | Notes |
48
- |---------|:------------:|-------|
49
- | Browser recording | No | Real click/input capture via Playwright |
50
- | Flow execution | No | Headless Playwright replay |
51
- | Screenshot capture | No | PNG per step, pass and fail |
52
- | Failure detection | No | Stops on error, shows what failed |
53
- | Selector repair (`flow:fix`) | No | Interactive browser-based fix |
54
- | Screenshot diff (`run:diff`) | No | Pixel comparison, no AI needed |
55
- | Flow scheduling | No | Cron-based, runs offline |
56
- | Monitor & diff extracted data | No | `ghostrun monitor <flow>` |
57
- | PII sanitization | No | Regex-based, local only |
58
- | Web dashboard | No | `ghostrun serve --ui` |
59
- | **API testing** | No | HTTP requests, assertions, variable extraction |
60
- | **Environment profiles** | No | Named env sets, injected at runtime |
61
- | **Load testing** | No | VU-based perf runs, p50/p95/p99 stats |
62
- | **k6 export** | No | `perf:export` generates a k6 script |
63
- | **Failure analysis** | Optional ✨ | Plain-English explanation of why it failed |
64
- | **Auto run summary** | Optional ✨ | Attached to every failed run automatically |
65
- | **Chat assistant** | Optional ✨ | Q&A + run flows by name via `ghostrun chat` |
66
-
67
- **Bottom line:** Record, replay, schedule, diff, and fix flows entirely offline. AI adds explanations and a conversational interface.
108
+ ## The Three Modes
109
+
110
+ ### 1. Browser Automation
111
+
112
+ GhostRun opens a real browser (Playwright/Chromium), watches your interactions, and saves them as a flow. Replay runs headlessly.
113
+
114
+ ```bash
115
+ ghostrun learn https://yourapp.com # record
116
+ ghostrun run <id|name> # replay headlessly
117
+ ghostrun run <id|name> --visible # replay with browser window visible
118
+ ```
119
+
120
+ **What gets recorded:** clicks, form fills, navigation, waits, checkboxes, dropdowns, keyboard input, file uploads, scroll, drag and drop.
121
+
122
+ **Selector repair:** If a flow breaks after a UI update, `ghostrun flow:fix <id>` opens the browser, replays up to the broken step, and lets you click the correct element. Selector is updated automatically — no manual JSON editing.
68
123
 
69
124
  ---
70
125
 
71
- ## AI Setup
126
+ ### 2. API Testing
72
127
 
73
- ### Option 1 Local (Default, Recommended)
128
+ When all steps in a flow are API actions (no `click`, `fill`, etc.), GhostRun skips Playwright entirely. Execution is ~30ms per run.
74
129
 
75
- GhostRun uses **Ollama** by default. No API key, no internet, runs on your machine.
130
+ **Three ways to create an API flow:**
76
131
 
77
132
  ```bash
78
- brew install ollama
79
- ollama serve &
80
- ollama pull gemma3:4b # 2.6 GB, fast on Apple Silicon
81
- node ghostrun.js status # → AI Provider: Ollama (gemma3:4b)
133
+ # From a curl command
134
+ ghostrun flow:from-curl "curl -X GET https://api.example.com/users \
135
+ -H 'Authorization: Bearer {{token}}'"
136
+
137
+ # From an OpenAPI/Swagger spec
138
+ ghostrun flow:from-spec openapi.json # JSON or YAML
139
+ ghostrun flow:from-spec swagger.yaml
140
+
141
+ # Import a hand-crafted .flow.json
142
+ ghostrun flow:import my-api-tests.flow.json
82
143
  ```
83
144
 
84
- **Model options by hardware:**
145
+ **API flow features:**
146
+ - HTTP requests with custom headers, JSON body, bearer auth
147
+ - Response assertions (status code, JSON path, headers, response time)
148
+ - Variable extraction from responses — use in subsequent steps
149
+ - Named environment profiles (dev / staging / prod)
85
150
 
86
- | Model | Size | Best for |
87
- |-------|------|---------|
88
- | `gemma3:4b` | 2.6 GB | Apple Silicon M1/M2/M3, fast |
89
- | `gemma2:9b` | 5.4 GB | Better quality, more RAM needed |
90
- | `llama3.2:3b` | 2.0 GB | Fastest, lighter quality |
151
+ ---
91
152
 
92
- Override model: `export GHOSTRUN_OLLAMA_MODEL=llama3.2:3b`
153
+ ### 3. Load Testing
93
154
 
94
- ### Option 2 Anthropic Cloud (Fallback)
155
+ Run any API flow as a load test. GhostRun sends parallel VU requests, collects timing, and prints a latency breakdown.
95
156
 
96
157
  ```bash
97
- export ANTHROPIC_API_KEY=sk-ant-...
158
+ ghostrun perf:run <id|name> # defaults: 10 VUs, 30s
159
+ ghostrun perf:run <id|name> --vus 50 --duration 60 --ramp-up 10
160
+ ghostrun perf:compare <run-A-id> <run-B-id> # diff two runs
161
+ ghostrun perf:export <id|name> # generate a k6 script
98
162
  ```
99
163
 
100
- ### Fallback chain
164
+ **Output includes:** HTTP requests, success rate, avg RPS, p50 / p95 / p99 latency, min/max, per-step breakdown, checks passed/failed.
165
+
166
+ **perf:compare** shows side-by-side deltas with color-coded improvement/regression:
101
167
 
102
168
  ```
103
- run → try Ollama → if down → try Anthropic → if no key → skip AI silently
169
+ Before After Delta
170
+ p50 latency 142ms 98ms ↓ 44ms ✓
171
+ p95 latency 310ms 201ms ↓ 109ms ✓
172
+ p99 latency 580ms 390ms ↓ 190ms ✓
173
+ avg RPS 47.2 68.1 ↑ 20.9 ✓
104
174
  ```
105
175
 
106
- ### Environment Variables
107
-
108
- | Variable | Default | Description |
109
- |----------|---------|-------------|
110
- | `GHOSTRUN_AI_PROVIDER` | auto | `ollama`, `anthropic`, or auto |
111
- | `GHOSTRUN_OLLAMA_URL` | `http://localhost:11434` | Ollama server URL |
112
- | `GHOSTRUN_OLLAMA_MODEL` | auto-detected | Model to use |
113
- | `ANTHROPIC_API_KEY` | — | Anthropic API key (cloud fallback) |
176
+ **perf:export** generates a valid k6 script with VU stages, `http.get`/`http.post` calls, `check()` assertions, and `Trend` metrics per step.
114
177
 
115
178
  ---
116
179
 
@@ -120,65 +183,89 @@ run → try Ollama → if down → try Anthropic → if no key → skip AI silen
120
183
 
121
184
  ```bash
122
185
  ghostrun init # guided setup wizard
123
- ghostrun status # stats + AI provider info
186
+ ghostrun status # stats, AI provider, data path
124
187
  ```
125
188
 
126
189
  ### Recording
127
190
 
128
191
  ```bash
129
- ghostrun learn <url> [name] # record a flow (real browser opens)
130
- ghostrun learn <url> --name "Login" # with explicit name
192
+ ghostrun learn <url> # open browser and record a flow
193
+ ghostrun learn <url> --name "Login" # with an explicit name
131
194
  ```
132
195
 
133
- ### Running
196
+ ### Running Flows
134
197
 
135
198
  ```bash
136
- ghostrun run <id|name> # headless execution
137
- ghostrun run <id|name> --visible # show the browser window
138
- ghostrun run <id|name> --output json # structured JSON output with extracted data
139
- ghostrun run <id|name> --var key=val # inject variables
140
- ghostrun run <id|name> --session-save mysession # save cookies/storage
141
- ghostrun run <id|name> --session-load mysession # restore cookies/storage
199
+ ghostrun run <id|name> # headless execution
200
+ ghostrun run <id|name> --visible # show the browser window
201
+ ghostrun run <id|name> --var key=val # inject a variable
202
+ ghostrun run <id|name> --output json # JSON output (for scripting/CI)
203
+ ghostrun run <id|name> --report html # save an HTML run report
204
+ ghostrun run <id|name> --session-save <name> # save browser cookies/storage
205
+ ghostrun run <id|name> --session-load <name> # restore browser cookies/storage
142
206
  ```
143
207
 
144
208
  ### Flow Management
145
209
 
146
210
  ```bash
147
- ghostrun flow:list # list all flows
148
- ghostrun flow:show <id|name> # show steps
149
- ghostrun flow:fix <id|name> # fix broken selectors interactively
150
- ghostrun flow:delete <id|name> # delete a flow
151
- ghostrun flow:export <id|name> # export to .flow.json
152
- ghostrun flow:import <file> # import from .flow.json
153
- ghostrun flow:clone <id|name> # duplicate a flow
154
- ghostrun flow:rename <id|name> <new> # rename a flow
211
+ ghostrun flow:list # list all flows
212
+ ghostrun flow:show <id|name> # show steps for a flow
213
+ ghostrun flow:rename <id|name> <new-name> # rename a flow
214
+ ghostrun flow:clone <id|name> # duplicate a flow
215
+ ghostrun flow:delete <id|name> # delete a flow
216
+ ghostrun flow:export <id|name> # export to .flow.json
217
+ ghostrun flow:import <file> # import from .flow.json
218
+ ghostrun flow:fix <id|name> # fix broken selectors interactively
219
+ ghostrun flow:from-curl "<curl>" # create a flow from a curl command
220
+ ghostrun flow:from-spec <file> # create flows from an OpenAPI spec
155
221
  ```
156
222
 
157
- ### Data Extraction & Monitoring
223
+ ### Environments
224
+
225
+ Named variable sets injected at run time. Perfect for dev / staging / prod.
158
226
 
159
227
  ```bash
160
- ghostrun monitor <id|name> # run + show extracted data, diff vs previous
161
- ghostrun run:show <id> # step details + screenshots + extracted data
228
+ ghostrun env:create <name> [base-url] # create an environment
229
+ ghostrun env:set <name> <key=value> # add or update a variable
230
+ ghostrun env:list # list all environments
231
+ ghostrun env:show <name> # show variables in an environment
232
+ ghostrun env:use <name> # set as the active environment
233
+ ghostrun env:delete <name> # delete an environment
162
234
  ```
163
235
 
236
+ Reference variables in any URL, header, or body field with `{{variableName}}`. The active environment's variables are injected automatically before each run.
237
+
164
238
  ### Run History
165
239
 
166
240
  ```bash
167
241
  ghostrun run:list # list recent runs
168
- ghostrun run:show <id> # step details + screenshots
169
- ghostrun run:diff <id1> <id2> # visual screenshot diff (no AI needed)
170
- ghostrun run:analyze <id> # AI failure analysis (optional)
242
+ ghostrun run:show <id> # step-by-step detail, screenshots, extracted data
243
+ ghostrun run:diff <id1> <id2> # pixel-level screenshot comparison
244
+ ghostrun run:analyze <id> # AI failure analysis (requires AI setup)
245
+ ghostrun var:dump <run-id> # show all variables extracted during a run
171
246
  ```
172
247
 
173
248
  ### Scheduling
174
249
 
175
250
  ```bash
176
- ghostrun flow:schedule <id> "<cron>" # e.g. "0 9 * * *" = daily 9am
251
+ ghostrun flow:schedule <id> "<cron>" # e.g. "0 9 * * *" = daily at 9am
177
252
  ghostrun schedule:list # list all schedules
178
253
  ghostrun schedule:remove <id> # remove a schedule
179
254
  ghostrun serve # start the scheduler daemon
180
255
  ```
181
256
 
257
+ ### Test Suites
258
+
259
+ Group flows and run them together:
260
+
261
+ ```bash
262
+ ghostrun suite:create <name> # create a suite
263
+ ghostrun suite:add <suite> <flow> # add a flow to the suite
264
+ ghostrun suite:run <suite> # run all flows in the suite
265
+ ghostrun suite:list # list suites
266
+ ghostrun suite:show <suite> # show flows in a suite
267
+ ```
268
+
182
269
  ### Web Dashboard
183
270
 
184
271
  ```bash
@@ -186,152 +273,91 @@ ghostrun serve --ui # launch dashboard at http://localhost:30
186
273
  ghostrun serve --ui --port 8080 # custom port
187
274
  ```
188
275
 
189
- The dashboard shows:
190
- - All flows with one-click run buttons
191
- - Live run log with SSE streaming
192
- - Run history with status and duration
193
- - Chat tab for natural-language interaction
276
+ The dashboard shows all flows with one-click run, a live log stream, run history, and a chat tab.
194
277
 
195
278
  ### Chat Assistant
196
279
 
280
+ Ask questions about your flows in plain English:
281
+
197
282
  ```bash
198
- ghostrun chat # interactive AI chat (requires Ollama or ANTHROPIC_API_KEY)
283
+ ghostrun chat
199
284
  ```
200
285
 
201
- Ask questions in plain English:
286
+ Examples:
202
287
  - `did my login flow pass recently?`
203
288
  - `what flows do I have?`
204
- - `run the login flow` ← executes the flow with confirmation
289
+ - `run the login flow` ← executes with confirmation
205
290
 
206
- ### Test Suites
291
+ Requires Ollama (local, free) or an Anthropic API key. See [AI Setup](#ai-setup).
207
292
 
208
- ```bash
209
- ghostrun suite:create <name> # create a suite
210
- ghostrun suite:add <suite> <flow> # add a flow to a suite
211
- ghostrun suite:list # list suites
212
- ghostrun suite:show <suite> # show flows in suite
213
- ghostrun suite:run <suite> # run all flows in suite
214
- ```
293
+ ### MCP Server
215
294
 
216
- ### Visual Baselines
295
+ Expose GhostRun to AI agents (Claude Desktop, Cursor, etc.):
217
296
 
218
297
  ```bash
219
- ghostrun baseline:set <flow-id> # capture reference screenshots
220
- ghostrun baseline:clear <flow-id> # clear baselines
221
- ghostrun baseline:show <flow-id> # list baselines
298
+ node mcp-server.js
222
299
  ```
223
300
 
224
- ### Importing Flows
301
+ Tools exposed: `list_flows`, `get_flow`, `run_flow`, `get_run_result`, `list_runs`, `delete_flow`, `get_status`.
225
302
 
226
- ```bash
227
- ghostrun flow:from-curl # paste a curl command → instant flow
228
- ghostrun flow:from-curl "curl -X POST https://api.example.com/users -H 'Content-Type: application/json' -d '{\"name\":\"Alice\"}'"
229
- ghostrun flow:from-spec openapi.json # import all endpoints from an OpenAPI spec
230
- ghostrun flow:from-spec swagger.yaml # YAML supported too
231
- ghostrun flow:import <file> # import a .flow.json directly
232
- ```
303
+ See [MCP-SETUP.md](MCP-SETUP.md) for connection setup.
233
304
 
234
- `flow:from-curl` parses the curl command (method, headers, body, bearer auth) and creates a ready-to-run flow with a status assertion. `flow:from-spec` reads an OpenAPI/Swagger spec and lets you choose: one flow per tag group, one per endpoint, or one big flow.
305
+ ---
235
306
 
236
- ### Run Reports
307
+ ## Reports
237
308
 
238
309
  ```bash
239
- ghostrun run <id> --report html # run + save HTML report
240
- ghostrun perf:run <id> --report html # load test + save HTML report
310
+ ghostrun run <id> --report html # browser or API run report
311
+ ghostrun perf:run <id> --report html # load test report
241
312
  ```
242
313
 
243
- Reports are dark-themed HTML files saved to the current directory shareable, self-contained, screenshot-inclusive.
244
-
245
- ### API Testing
246
-
247
- Import an API flow from a `.flow.json` file (no browser needed):
248
-
249
- ```bash
250
- ghostrun api:learn # interactive: pick a .flow.json file to import
251
- ghostrun flow:import <file> # import directly by path
252
- ghostrun run <id|name> # runs pure API flows without launching a browser
253
- ```
314
+ Dark-themed, self-contained HTML files saved to the current directory. Include per-step timing, status, screenshots (for browser flows), and extracted data. Shareable without any external dependencies.
254
315
 
255
- When all steps in a flow are API actions (`http:request`, `assert:response`, `set:variable`, `extract:json`, `env:switch`), GhostRun skips Playwright entirely — execution is ~30ms.
316
+ ---
256
317
 
257
- ### Environments
318
+ ## Selector Repair
258
319
 
259
- Named variable sets injected at flow start. Great for dev / staging / prod:
320
+ When a UI update breaks a selector:
260
321
 
261
322
  ```bash
262
- ghostrun env:create <name> [base-url] # create an environment profile
263
- ghostrun env:list # list all environments
264
- ghostrun env:show <name> # show variables in an environment
265
- ghostrun env:set <name> <key=value> # add or update a variable
266
- ghostrun env:use <name> # set as active environment
267
- ghostrun env:delete <name> # delete an environment
323
+ ghostrun flow:fix <id|name>
268
324
  ```
269
325
 
270
- The active environment's variables are automatically injected before each flow run. Use `{{variableName}}` in any URL, header, or body field to reference them.
326
+ The browser opens, replays all passing steps automatically, then **pauses on the broken step** and asks you to click the correct element. The selector is updated and saved. No JSON editing needed.
271
327
 
272
- ### Variable Inspection
328
+ ---
273
329
 
274
- ```bash
275
- ghostrun var:dump <run-id> # show all variables extracted during a run
276
- ```
330
+ ## Screenshot Diff
277
331
 
278
- ### Load & Performance Testing
332
+ Compare any two runs pixel-by-pixel — no AI needed:
279
333
 
280
334
  ```bash
281
- ghostrun perf:run <id|name> # run a load test against an API flow
282
- ghostrun perf:run <id|name> --vus 20 --duration 30 --ramp-up 5
283
- ghostrun perf:export <id|name> # generate a k6 script from the flow
284
- ghostrun perf:export <id|name> --output mytest.js
285
- ghostrun perf:list # list past perf runs
286
- ghostrun perf:show <perf-run-id> # show stats for a specific perf run
335
+ ghostrun run:diff <run1-id> <run2-id>
287
336
  ```
288
337
 
289
- **perf:run options:**
290
-
291
- | Flag | Default | Description |
292
- |------|---------|-------------|
293
- | `--vus <n>` | 10 | Number of virtual users |
294
- | `--duration <s>` | 30 | Test duration in seconds |
295
- | `--ramp-up <s>` | 5 | Ramp-up time (VUs staggered over this window) |
296
- | `--timeout <ms>` | 10000 | Per-request timeout in ms |
297
-
298
- Output includes: HTTP Requests, HTTP Success Rate, Avg RPS, p50/p95/p99 latency, min/max, per-step breakdown, and separate Checks Passed/Failed count.
299
-
300
- **perf:compare** — diff two runs side by side to see if a deploy made things faster or slower:
301
-
302
- ```bash
303
- ghostrun perf:compare <run-A-id> <run-B-id>
304
338
  ```
339
+ Step Status Diff % Name
340
+ ───────────────────────────────────────────
341
+ 1 same 0.0% Navigate to homepage
342
+ 2 same 0.1% Click Login
343
+ 3 changed 12.4% Fill email field
344
+ 4 same 0.0% Submit form
305
345
 
306
- Shows p50/p95/p99/RPS for both runs with color-coded deltas (green = better, red = worse).
307
-
308
- **perf:export** generates a valid k6 JavaScript file with:
309
- - VU stages matching your `--vus`/`--duration`/`--ramp-up` config
310
- - `http.get`/`http.post` calls with headers and JSON body
311
- - `check()` assertions mapped to your `assert:response` steps
312
- - `Trend` metrics per step for p95 thresholds
313
- - `{{variable}}` → template literal interpolation
314
-
315
- ### MCP Server
316
-
317
- ```bash
318
- node mcp-server.js # start MCP server (Claude Desktop, Cursor, etc.)
346
+ 3 same 1 changed
347
+ Diff images: ~/.ghostrun/diffs/abc123_vs_def456/
319
348
  ```
320
349
 
321
- See [MCP-SETUP.md](MCP-SETUP.md) for connection setup.
322
-
323
- Tools exposed: `list_flows`, `get_flow`, `run_flow`, `get_run_result`, `list_runs`, `delete_flow`, `get_status`
324
-
325
350
  ---
326
351
 
327
352
  ## CI/CD Integration
328
353
 
329
- ### GitHub Actions
354
+ GhostRun exits with code `1` on failure and `0` on success — standard CI behaviour, no extra flags needed.
355
+
356
+ ### GitHub Actions example
330
357
 
331
358
  ```yaml
332
359
  # .github/workflows/ghostrun.yml
333
360
  name: GhostRun Tests
334
-
335
361
  on: [push, pull_request]
336
362
 
337
363
  jobs:
@@ -339,7 +365,6 @@ jobs:
339
365
  runs-on: ubuntu-latest
340
366
  steps:
341
367
  - uses: actions/checkout@v4
342
-
343
368
  - uses: actions/setup-node@v4
344
369
  with:
345
370
  node-version: 20
@@ -349,16 +374,12 @@ jobs:
349
374
 
350
375
  - name: Install Playwright browsers
351
376
  run: npx playwright install chromium --with-deps
377
+ # Skip this step for pure API flows — no browser needed
352
378
 
353
- - name: Import test flows
379
+ - name: Import and run flows
354
380
  run: |
355
- ghostrun flow:import test-flows/health-check.flow.json
356
- ghostrun flow:import test-flows/auth-and-users.flow.json
357
-
358
- - name: Run flows
359
- run: |
360
- ghostrun run "API Health Check" --report html
361
- ghostrun run "Auth + User List" --report html
381
+ ghostrun flow:import test-flows/auth.flow.json
382
+ ghostrun run "Auth Flow" --report html
362
383
 
363
384
  - name: Upload reports
364
385
  uses: actions/upload-artifact@v4
@@ -368,265 +389,85 @@ jobs:
368
389
  path: ghostrun-report-*.html
369
390
  ```
370
391
 
371
- ### Exit Codes
372
-
373
- GhostRun exits with code `1` on failure and `0` on pass — standard CI behaviour, no extra flags needed.
374
-
375
- ### API-only flows in CI
376
-
377
- API flows skip Playwright entirely — no `playwright install` step needed:
378
-
379
- ```yaml
380
- - name: Install GhostRun (API testing only)
381
- run: npm install -g ghostrun-cli
382
- # No playwright install needed for pure API flows
392
+ ---
383
393
 
384
- - name: Run API tests
385
- run: ghostrun run "Auth + User List"
386
- ```
394
+ ## AI Setup
387
395
 
388
- ---
396
+ Every core feature works with zero AI. AI adds failure explanations and a chat interface — both are optional.
389
397
 
390
- ## Selector Repair (`flow:fix`)
398
+ ### Option 1 — Ollama (local, recommended)
391
399
 
392
- When a flow fails because a selector broke:
400
+ No API key, no internet required. Runs on your machine.
393
401
 
394
402
  ```bash
395
- ghostrun flow:fix <id|name>
403
+ brew install ollama
404
+ ollama serve &
405
+ ollama pull gemma3:4b # 2.6 GB, fast on Apple Silicon
396
406
  ```
397
407
 
398
- Browser opens, replays all passing steps automatically, **pauses on broken ones**, and asks you to click the correct element. Selector is updated and saved. No manual editing.
399
-
400
- ---
408
+ | Model | Size | Best for |
409
+ |-------|------|---------|
410
+ | `gemma3:4b` | 2.6 GB | Apple Silicon M1/M2/M3 |
411
+ | `gemma2:9b` | 5.4 GB | Better quality |
412
+ | `llama3.2:3b` | 2.0 GB | Fastest, lighter quality |
401
413
 
402
- ## Screenshot Diff (`run:diff`)
414
+ Override: `export GHOSTRUN_OLLAMA_MODEL=llama3.2:3b`
403
415
 
404
- Compare any two runs pixel-by-pixel no AI needed:
416
+ ### Option 2Anthropic (cloud fallback)
405
417
 
406
418
  ```bash
407
- ghostrun run:diff <run1-id> <run2-id>
408
-
409
- Step Status Diff % Screenshot
410
- ──────────────────────────────────────────────────────────
411
- 1 same 0.0% Navigate to homepage
412
- 2 same 0.1% Click Login
413
- 3 changed 12.4% Fill email field
414
- 4 same 0.0% Submit form
415
-
416
- 3 same 1 changed
417
- Diff images: ~/.ghostrun/diffs/abc123_vs_def456/
419
+ export ANTHROPIC_API_KEY=sk-ant-...
418
420
  ```
419
421
 
420
- ---
421
-
422
- ## Flow Actions Reference
423
-
424
- All actions you can use in recorded or imported `.flow.json` files:
425
-
426
- ### Navigation
427
-
428
- | Action | Fields | Description |
429
- |--------|--------|-------------|
430
- | `navigate` | `url` | Go to URL |
431
- | `reload` | — | Reload the current page |
432
- | `back` | — | Browser back |
433
- | `forward` | — | Browser forward |
434
-
435
- ### Interaction
436
-
437
- | Action | Fields | Description |
438
- |--------|--------|-------------|
439
- | `click` | `selector` | Left-click an element |
440
- | `dblclick` | `selector` | Double-click an element |
441
- | `fill` | `selector`, `value` | Clear field and type value |
442
- | `type` | `selector`, `value`, `delay?` | Type with configurable key delay (ms) |
443
- | `clear` | `selector` | Clear a field |
444
- | `select` | `selector`, `value` | Select a dropdown option by value |
445
- | `check` | `selector`, `value: "true"\|"false"` | Check/uncheck a checkbox |
446
- | `focus` | `selector` | Focus an element |
447
- | `hover` | `selector` | Mouse hover |
448
- | `drag` | `selector`, `targetSelector` | Drag one element to another |
449
- | `keyboard` | `key`, `selector?` | Press a key (e.g. `Enter`, `Tab`, `Control+a`) |
450
- | `upload` | `selector`, `value` | Set file input (comma-separated paths) |
451
-
452
- ### Waiting
453
-
454
- | Action | Fields | Description |
455
- |--------|--------|-------------|
456
- | `wait` | `selector` | Wait for element to appear |
457
- | `wait:text` | `selector`, `value` | Wait until element contains text |
458
- | `wait:url` | `value` | Wait for URL to match pattern |
459
- | `wait:ms` | `value` | Wait for N milliseconds |
460
-
461
- ### Scrolling
462
-
463
- | Action | Fields | Description |
464
- |--------|--------|-------------|
465
- | `scroll` | `selector?` | Scroll to element (or page) |
466
- | `scroll:element` | `selector` | Scroll element into view |
467
- | `scroll:bottom` | — | Scroll to bottom of page |
468
- | `scroll:load` | `value?` | Scroll to bottom, wait for load (repeat N times) |
469
- | `next:page` | `selector?` | Click next page link and wait |
470
-
471
- ### Assertions
472
-
473
- | Action | Fields | Description |
474
- |--------|--------|-------------|
475
- | `assert:visible` | `selector` | Assert element is visible |
476
- | `assert:hidden` | `selector` | Assert element is not visible |
477
- | `assert:text` | `selector`, `value` | Assert element contains text |
478
- | `assert:not-text` | `selector`, `value` | Assert element does NOT contain text |
479
- | `assert:value` | `selector`, `value` | Assert input value |
480
- | `assert:count` | `selector`, `value` | Assert number of matching elements |
481
- | `assert:attr` | `selector`, `value: "attr=expected"` | Assert element attribute |
422
+ ### Fallback order
482
423
 
483
- ### Data Extraction
484
-
485
- | Action | Fields | Description |
486
- |--------|--------|-------------|
487
- | `extract` | `selector`, `value: "variableName"` | Extract text → variable |
488
- | `screenshot` | — | Capture screenshot at this step |
489
-
490
- ### Browser State
491
-
492
- | Action | Fields | Description |
493
- |--------|--------|-------------|
494
- | `cookie:set` | `value: "name=value; domain=..."` | Set a cookie |
495
- | `cookie:clear` | — | Clear all cookies |
496
- | `storage:set` | `selector: "key"`, `value: "val"` | Set localStorage item |
497
- | `eval` | `value` | Execute JavaScript on the page |
498
- | `iframe:enter` | `selector` | Enter an iframe context |
499
- | `iframe:exit` | — | Exit iframe context, return to main frame |
500
-
501
- ### API — HTTP Requests
502
-
503
- | Action | Fields | Description |
504
- |--------|--------|-------------|
505
- | `http:request` | `method`, `url`, `headers?`, `body?`, `auth?`, `extract?` | Make an HTTP request. `auth` supports `{ type: "bearer", token: "{{var}}" }`. `extract` is a map of `variableName → $.jsonPath`. |
506
-
507
- ### API — Assertions
508
-
509
- | Action | Fields | Description |
510
- |--------|--------|-------------|
511
- | `assert:response` | `assert: "status"`, `expected` | Assert HTTP status code |
512
- | `assert:response` | `assert: "json:path"`, `path`, `expected` | Assert JSONPath value equals expected |
513
- | `assert:response` | `assert: "json:exists"`, `path` | Assert JSONPath exists in response |
514
- | `assert:response` | `assert: "header"`, `header`, `expected` | Assert response header value |
515
- | `assert:response` | `assert: "body:contains"`, `expected` | Assert raw body contains string |
516
- | `assert:response` | `assert: "time"`, `expected` | Assert response time < expected ms |
517
-
518
- ### API — Variables & Flow Control
519
-
520
- | Action | Fields | Description |
521
- |--------|--------|-------------|
522
- | `set:variable` | `variable`, `value` | Set a named variable (supports `{{interpolation}}`) |
523
- | `extract:json` | `variable`, `path` | Extract a value from the last response body via JSONPath |
524
- | `env:switch` | `value` | Switch active environment mid-flow |
525
-
526
- ### Variables
527
-
528
- Use `{{variableName}}` in any `value`, `url`, `selector`, or `body` field to inject variables:
529
-
530
- ```json
531
- { "action": "fill", "selector": "#email", "value": "{{userEmail}}" }
532
- ```
533
-
534
- Pass at runtime: `ghostrun run <id> --var userEmail=user@example.com`
535
-
536
- Extracted values (from `extract:` steps) are automatically available as variables in subsequent steps.
424
+ ```
425
+ Run → try Ollama → if down → try Anthropic → if no key → skip AI silently
426
+ ```
537
427
 
538
- ---
428
+ ### Environment variables
539
429
 
540
- ## Unsupported / Limited Interactions
541
-
542
- The following browser patterns have limited or no support today:
543
-
544
- | Interaction | Status | Notes |
545
- |------------|--------|-------|
546
- | Canvas drawing | ❌ Not supported | `<canvas>` elements — no visual capture |
547
- | WebGL / Three.js | ❌ Not supported | GPU-rendered content |
548
- | Browser native dialogs | ⚠️ Partial | `alert()`/`confirm()`/`prompt()` auto-dismissed |
549
- | File download verification | ⚠️ Partial | Download triggers but content is not validated |
550
- | WebRTC / media streams | ❌ Not supported | Camera, mic, screen capture APIs |
551
- | Browser extensions | ❌ Not supported | Extension UI is not accessible via Playwright |
552
- | Shadow DOM (closed mode) | ⚠️ Limited | Open shadow DOM works; closed mode requires `eval:` workaround |
553
- | Multi-tab / popup flows | ⚠️ Partial | New tabs opened by click are not automatically followed |
554
- | OS-level dialogs | ❌ Not supported | Native file picker, print dialog, OS auth prompts |
555
- | CAPTCHAs | ❌ Not supported | By design — no circumvention |
556
- | Biometric auth | ❌ Not supported | Touch ID, Face ID, WebAuthn |
557
- | Browser gestures (pinch/zoom) | ❌ Not supported | Mobile multi-touch gestures |
558
- | Hover-only menus (CSS `:hover`) | ✅ Works | Use `hover` action before clicking submenu items |
559
- | Right-click context menus | ⚠️ Limited | Browser context menus not accessible; app-level menus often work |
560
- | Drag and drop | ✅ Works | Use `drag` action with `selector` + `targetSelector` |
561
- | Infinite scroll / lazy load | ✅ Works | Use `scroll:load` with repeat count |
562
-
563
- **Workarounds for unsupported interactions:**
564
- - Use `eval:` to run JavaScript directly: `{ "action": "eval", "value": "document.querySelector('#btn').click()" }`
565
- - Use `wait:ms:` to pause before difficult timing-sensitive interactions
566
- - For shadow DOM: `{ "action": "eval", "value": "document.querySelector('my-el').shadowRoot.querySelector('button').click()" }`
430
+ | Variable | Default | Description |
431
+ |----------|---------|-------------|
432
+ | `GHOSTRUN_AI_PROVIDER` | `auto` | `ollama`, `anthropic`, or `auto` |
433
+ | `GHOSTRUN_OLLAMA_URL` | `http://localhost:11434` | Ollama server URL |
434
+ | `GHOSTRUN_OLLAMA_MODEL` | auto-detected | Model to use with Ollama |
435
+ | `ANTHROPIC_API_KEY` | — | Anthropic API key (cloud fallback) |
567
436
 
568
437
  ---
569
438
 
570
- ## Data Storage
439
+ ## Data & Privacy
571
440
 
572
- All data is local in `~/.ghostrun/`:
441
+ All data lives locally in `~/.ghostrun/`:
573
442
 
574
443
  ```
575
444
  ~/.ghostrun/
576
- ├── data/ghostrun.db # SQLite: flows, runs, steps, schedules, extracted data,
577
- │ # environments, api_responses, perf_runs
445
+ ├── data/ghostrun.db # SQLite: flows, runs, steps, schedules, environments
578
446
  ├── screenshots/ # PNG per step per run
579
447
  ├── baselines/ # Visual baseline reference screenshots
580
448
  └── diffs/ # Screenshot diff images
581
449
  ```
582
450
 
583
- ---
584
-
585
- ## Privacy
586
-
587
- PII is sanitized before storage — emails, phones, cards, JWTs, API keys, passwords are replaced with `[EMAIL]`, `[PHONE]`, etc. Nothing sensitive is sent to AI unless you explicitly call `run:analyze`.
451
+ **PII sanitization:** Emails, phone numbers, credit cards, JWTs, API keys, and passwords are redacted before storage. Nothing sensitive is sent to AI unless you explicitly call `run:analyze`.
588
452
 
589
453
  ---
590
454
 
591
- ## Build from Source
592
-
593
- ```bash
594
- npm install
595
- npm run build # compiles .ts → .js via esbuild
596
- ```
455
+ ## Contributing
597
456
 
598
- ---
599
-
600
- ## Publishing to npm
601
-
602
- ```bash
603
- # 1. Log in to npm
604
- npm login
605
-
606
- # 2. Make sure the build is fresh
607
- npm run build
608
-
609
- # 3. Dry-run to verify what gets published
610
- npm publish --dry-run
611
-
612
- # 4. Publish
613
- npm publish --access public
614
- ```
615
-
616
- After publishing, users can install with:
617
- ```bash
618
- npm install -g ghostrun-cli
619
- ghostrun init
620
- ```
457
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for how to get started, and [REFERENCE.md](REFERENCE.md) for the full flow actions reference.
621
458
 
622
459
  ---
623
460
 
624
- ## Built with
461
+ ## Trust & Transparency
625
462
 
626
- This project was built with the help of [Claude](https://claude.ai) and [Goose](https://goose-docs.ai).
463
+ - **100% local by default** no cloud, no telemetry, no tracking
464
+ - **Open source (MIT)** — full source at [github.com/TechBuiltBySharan/ghostrun](https://github.com/TechBuiltBySharan/ghostrun)
465
+ - **No surprise costs** — AI works offline via [Ollama](https://ollama.com) (free); Anthropic key is optional
466
+ - **No vendor lock-in** — flows are plain JSON files you own; export, import, version-control them like code
467
+ - Built with the help of [Claude](https://claude.ai) and [Goose](https://goose-docs.ai)
627
468
 
628
469
  ---
629
470
 
630
471
  ## License
631
472
 
632
- MIT
473
+ MIT — see [LICENSE](LICENSE)