chrome-jig 0.4.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +159 -6
  2. package/SKILL.md +121 -57
  3. package/dist/chrome/connection.d.ts +6 -1
  4. package/dist/chrome/connection.d.ts.map +1 -1
  5. package/dist/chrome/connection.js +25 -7
  6. package/dist/chrome/connection.js.map +1 -1
  7. package/dist/chrome/launcher.d.ts +8 -2
  8. package/dist/chrome/launcher.d.ts.map +1 -1
  9. package/dist/chrome/launcher.js +9 -2
  10. package/dist/chrome/launcher.js.map +1 -1
  11. package/dist/chrome/resilience.d.ts +31 -0
  12. package/dist/chrome/resilience.d.ts.map +1 -0
  13. package/dist/chrome/resilience.js +78 -0
  14. package/dist/chrome/resilience.js.map +1 -0
  15. package/dist/cli.js +174 -11
  16. package/dist/cli.js.map +1 -1
  17. package/dist/commands/attach.d.ts +11 -0
  18. package/dist/commands/attach.d.ts.map +1 -0
  19. package/dist/commands/attach.js +34 -0
  20. package/dist/commands/attach.js.map +1 -0
  21. package/dist/commands/connection-info.d.ts +18 -0
  22. package/dist/commands/connection-info.d.ts.map +1 -0
  23. package/dist/commands/connection-info.js +30 -0
  24. package/dist/commands/connection-info.js.map +1 -0
  25. package/dist/commands/eval.d.ts +3 -0
  26. package/dist/commands/eval.d.ts.map +1 -1
  27. package/dist/commands/eval.js +9 -0
  28. package/dist/commands/eval.js.map +1 -1
  29. package/dist/commands/install-skill.d.ts.map +1 -1
  30. package/dist/commands/install-skill.js +30 -1
  31. package/dist/commands/install-skill.js.map +1 -1
  32. package/dist/commands/launch.d.ts +1 -0
  33. package/dist/commands/launch.d.ts.map +1 -1
  34. package/dist/commands/launch.js +5 -0
  35. package/dist/commands/launch.js.map +1 -1
  36. package/dist/commands/profiles.d.ts +24 -0
  37. package/dist/commands/profiles.d.ts.map +1 -0
  38. package/dist/commands/profiles.js +31 -0
  39. package/dist/commands/profiles.js.map +1 -0
  40. package/dist/config/loader.d.ts +3 -1
  41. package/dist/config/loader.d.ts.map +1 -1
  42. package/dist/config/loader.js +40 -0
  43. package/dist/config/loader.js.map +1 -1
  44. package/dist/config/profiles.d.ts +18 -0
  45. package/dist/config/profiles.d.ts.map +1 -0
  46. package/dist/config/profiles.js +60 -0
  47. package/dist/config/profiles.js.map +1 -0
  48. package/dist/config/schema.d.ts +20 -0
  49. package/dist/config/schema.d.ts.map +1 -1
  50. package/dist/config/schema.js.map +1 -1
  51. package/dist/errors.d.ts +28 -0
  52. package/dist/errors.d.ts.map +1 -0
  53. package/dist/errors.js +54 -0
  54. package/dist/errors.js.map +1 -0
  55. package/dist/index.d.ts +14 -4
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +9 -1
  58. package/dist/index.js.map +1 -1
  59. package/package.json +14 -15
package/README.md CHANGED
@@ -8,6 +8,8 @@ The DevTools console, from your terminal and editor.
8
8
 
9
9
  **Named script injection with auto-reload.** Register scripts in `.cjig.json`, inject by name, watch files for changes, auto re-inject. The modify → re-inject → exercise loop without leaving your editor.
10
10
 
11
+ **Chrome lifecycle management.** Launch Chrome with isolated profiles, load unpacked extensions, attach to running instances. `cjig connection-info` exports connection details so Playwright scripts (or MCP browser tools) can connect to the same Chrome.
12
+
11
13
  **Editor-native via nREPL.** Evaluate ClojureScript from Neovim/Conjure buffers directly in the browser. No browser tab switching, no copy-paste.
12
14
 
13
15
  **Independent developer workflow.** The CLI is usable without any LLM. `cjig launch && cjig inject my-script && cjig repl` is a complete development loop with no AI in the path.
@@ -44,6 +46,45 @@ cjig eval-file bundle.js
44
46
  cjig repl
45
47
  ```
46
48
 
49
+ ## Working with MCP Tools
50
+
51
+ cjig and MCP browser tools complement each other — both connect to Chrome via CDP on the same port.
52
+
53
+ **cjig manages Chrome, MCP provides automation:**
54
+
55
+ ```bash
56
+ # cjig launches Chrome with extensions and a debug port
57
+ cjig launch --extensions ./my-extension/dist
58
+
59
+ # Playwright MCP connects to the same Chrome
60
+ # In your MCP client config:
61
+ ```
62
+
63
+ ```json
64
+ {
65
+ "mcpServers": {
66
+ "playwright": {
67
+ "command": "npx",
68
+ "args": ["@playwright/mcp@latest", "--cdp-endpoint", "http://localhost:9222"]
69
+ }
70
+ }
71
+ }
72
+ ```
73
+
74
+ **If MCP already launched Chrome**, attach to it:
75
+
76
+ ```bash
77
+ cjig attach --port 9222
78
+ cjig eval "document.title" # Now cjig commands work against MCP's Chrome
79
+ ```
80
+
81
+ **Export connection info** for scripts:
82
+
83
+ ```bash
84
+ cjig connection-info --json
85
+ # {"host":"localhost","port":9222,"endpoint":"http://localhost:9222","webSocketDebuggerUrl":"ws://...","source":"launched","profile":"default"}
86
+ ```
87
+
47
88
  ## How It Works
48
89
 
49
90
  All evaluation uses CDP `Runtime.evaluate` in the page's **main world** — the same context as the DevTools console:
@@ -59,10 +100,13 @@ Each CLI invocation is a **fresh process**. Tab state does not persist between i
59
100
  ### Chrome Management
60
101
 
61
102
  ```bash
62
- cjig launch # Launch with default profile
63
- cjig launch --profile=testing # Named profile
64
- cjig status # Check if Chrome is running
65
- cjig status --host=192.168.1.5 # Check remote Chrome
103
+ cjig launch # Launch with default profile
104
+ cjig launch --profile=testing # Named profile
105
+ cjig launch --extensions /path/to/ext # Load unpacked extension
106
+ cjig attach --port 9333 # Attach to running Chrome
107
+ cjig status # Check if Chrome is running
108
+ cjig connection-info # Show connection details
109
+ cjig connection-info --json # JSON output for scripts
66
110
  ```
67
111
 
68
112
  ### Tab Operations
@@ -72,6 +116,9 @@ cjig tabs # List open tabs (index + title + URL)
72
116
  cjig tab "GitHub" # Select by title or URL fragment
73
117
  cjig tab 2 # Select by index
74
118
  cjig open https://example.com # Open new tab
119
+ cjig open --timeout 60000 https://heavy-page.com # Custom timeout
120
+ cjig open --wait-until domcontentloaded https://example.com
121
+ cjig open --no-wait https://slow-page.com # Fire-and-forget
75
122
  ```
76
123
 
77
124
  Tab selector: numbers are positional indices, strings search URL and title.
@@ -113,6 +160,45 @@ Editors discover the port via `.nrepl-port` written to the current directory.
113
160
 
114
161
  The REPL and nREPL share a single connection. Tab switches in the REPL (`.tab`) take effect for nREPL evaluations too — no reconnection needed.
115
162
 
163
+ ### Profiles
164
+
165
+ ```bash
166
+ cjig profiles list # List known profiles
167
+ cjig profiles create myext --extensions /path/ext # Create profile with extensions
168
+ cjig launch --profile=myext # Launch with profile config
169
+ ```
170
+
171
+ Profile configs live at `~/.config/cjig/profiles/<name>.json` and remember extensions, flags, and default URL. Login sessions persist across launches in the profile's Chrome user-data directory.
172
+
173
+ ### Extension Loading
174
+
175
+ ```bash
176
+ # Via CLI flag
177
+ cjig launch --extensions /path/to/unpacked-extension
178
+
179
+ # Via project config (.cjig.json)
180
+ {
181
+ "extensions": ["/path/to/unpacked-extension"]
182
+ }
183
+
184
+ # Via profile config
185
+ cjig profiles create dev --extensions /path/to/ext
186
+ cjig launch --profile=dev
187
+ ```
188
+
189
+ Extensions from CLI flags, project config, profile config, and global config are merged (deduplicated by path).
190
+
191
+ ## Connecting from Playwright Scripts
192
+
193
+ ```js
194
+ import { getConnectionInfo } from 'chrome-jig';
195
+ import { chromium } from 'playwright';
196
+
197
+ const { info } = await getConnectionInfo('localhost', 9222);
198
+ const browser = await chromium.connectOverCDP(info.endpoint);
199
+ // Now use Playwright's full API against cjig-managed Chrome
200
+ ```
201
+
116
202
  ## REPL Commands
117
203
 
118
204
  ```
@@ -144,6 +230,12 @@ The REPL and nREPL share a single connection. Tab switches in the REPL (`.tab`)
144
230
  "chrome": {
145
231
  "path": "/path/to/chrome",
146
232
  "flags": ["--disable-background-timer-throttling"]
233
+ },
234
+ "extensions": ["/path/to/global-extension"],
235
+ "connection": {
236
+ "retries": 3,
237
+ "retryDelayMs": 500,
238
+ "fallbackHosts": ["127.0.0.1"]
147
239
  }
148
240
  }
149
241
  ```
@@ -164,6 +256,7 @@ The REPL and nREPL share a single connection. Tab switches in the REPL (`.tab`)
164
256
  }
165
257
  }
166
258
  },
259
+ "extensions": ["/path/to/project-extension"],
167
260
  "watch": {
168
261
  "paths": ["dist/harnesses/*.js"],
169
262
  "debounce": 300
@@ -174,6 +267,64 @@ The REPL and nREPL share a single connection. Tab switches in the REPL (`.tab`)
174
267
  }
175
268
  ```
176
269
 
270
+ ### Profile Config (`~/.config/cjig/profiles/<name>.json`)
271
+
272
+ ```json
273
+ {
274
+ "extensions": ["/path/to/extension"],
275
+ "flags": ["--auto-open-devtools-for-tabs"],
276
+ "url": "http://localhost:3000"
277
+ }
278
+ ```
279
+
280
+ Extension merge priority: CLI flags > project config > profile config > global config.
281
+
282
+ ### Connection Settings
283
+
284
+ Connection resilience settings can be configured at any level (global, project, or CLI flags):
285
+
286
+ ```json
287
+ {
288
+ "connection": {
289
+ "retries": 3,
290
+ "retryDelayMs": 500,
291
+ "timeout": 30000,
292
+ "waitUntil": "domcontentloaded",
293
+ "fallbackHosts": ["127.0.0.1"]
294
+ }
295
+ }
296
+ ```
297
+
298
+ | Field | Default | Description |
299
+ |-------|---------|-------------|
300
+ | `retries` | `3` | Number of connection retry attempts |
301
+ | `retryDelayMs` | `500` | Initial delay between retries (doubles each attempt) |
302
+ | `timeout` | (Playwright default) | Navigation timeout in ms for `open` |
303
+ | `waitUntil` | `load` | Navigation strategy: `load`, `domcontentloaded`, `networkidle` |
304
+ | `fallbackHosts` | `[]` | Additional hosts to try on connect failure (e.g. `["127.0.0.1"]` for IPv6/IPv4 issues) |
305
+
306
+ CLI flags `--retries`, `--retry-delay`, `--timeout`, `--wait-until`, and `--no-wait` override config values.
307
+
308
+ ## Error Handling
309
+
310
+ cjig uses typed exit codes for machine-parseable error handling:
311
+
312
+ | Exit Code | Category | Retryable | Meaning |
313
+ |-----------|----------|-----------|---------|
314
+ | 0 | — | — | Success |
315
+ | 1 | — | — | Unknown error |
316
+ | 2 | `connection` | yes | Cannot connect to Chrome |
317
+ | 3 | `timeout` | yes | Navigation timed out |
318
+ | 4 | `no-page` | no | No page/tab available |
319
+ | 5 | `evaluation` | no | JavaScript evaluation error |
320
+
321
+ With `--json`, errors are emitted as structured JSON on stderr:
322
+
323
+ ```bash
324
+ cjig eval --json --port 9999 "1+1"
325
+ # stderr: {"error":"Failed to connect...","category":"connection","retryable":true,"exitCode":2}
326
+ ```
327
+
177
328
  ## Environment Variables
178
329
 
179
330
  | Variable | Default | Description |
@@ -210,11 +361,13 @@ Then Claude can use it via the SKILL.md instructions.
210
361
  ```
211
362
  ~/.config/cjig/
212
363
  ├── config.json # Global config
213
- └── profiles/ # Named config profiles
364
+ └── profiles/ # Named profile configs
365
+ └── myext.json
214
366
 
215
367
  ~/.local/share/cjig/
216
368
  └── chrome-profiles/ # Chrome user-data dirs
217
- └── default/
369
+ ├── default/
370
+ └── myext/
218
371
 
219
372
  ~/.local/state/cjig/
220
373
  └── last-session.json # Session state
package/SKILL.md CHANGED
@@ -1,24 +1,51 @@
1
+ ---
2
+ name: chrome-jig
3
+ description: CSP-proof browser debugging and JavaScript evaluation in Chrome via CDP. Use when you need to launch/attach Chrome, list tabs, inject scripts, evaluate JS/CLJS, or bridge Chrome to Playwright.
4
+ ---
5
+
1
6
  # Chrome Jig — Claude Skill
2
7
 
3
- ## Purpose
8
+ ## What Chrome Jig Is
9
+
10
+ CSP-proof JavaScript evaluation and injection CLI. Interactive browser debugging. Chrome lifecycle manager (profiles, extensions, sessions).
11
+
12
+ ## What Chrome Jig Is NOT
13
+
14
+ Not a browser automation framework. Not a Playwright replacement. For scripted navigation, screenshots, DOM assertions, multi-page workflows — use Playwright directly.
15
+
16
+ ## The Handoff Model
17
+
18
+ - cjig manages Chrome (launch, profiles, extensions, attach)
19
+ - cjig provides CSP-proof eval/injection (Runtime.evaluate via CDP)
20
+ - Playwright provides automation (connectOverCDP to cjig's Chrome)
21
+ - `cjig connection-info` bridges the two
4
22
 
5
- Drive harness development workflows in Chrome from the command line. Launch isolated Chrome sessions, inject scripts, evaluate JavaScript, and manage the full inject → exercise → modify → re-inject development loop.
23
+ ## When to Use cjig vs Playwright
6
24
 
7
- ## Mental Model
25
+ | Task | Use | Why |
26
+ |------|-----|-----|
27
+ | Eval JS on a page you don't own (CSP) | `cjig eval` | CDP Runtime.evaluate bypasses CSP |
28
+ | Inject a library into a live page | `cjig inject` | Server-side fetch + CDP eval, bypasses CSP and CORS |
29
+ | Evaluate a file on any page | `cjig eval-file` | CSP-proof file evaluation |
30
+ | Interactive browser debugging | `cjig repl` | Persistent session, dot-commands |
31
+ | Launch Chrome with extensions | `cjig launch --extensions` | Managed profiles, separate user-data-dir |
32
+ | Connect to MCP browser Chrome | `cjig attach` | Records session state for other cjig commands |
33
+ | Get connection details for Playwright | `cjig connection-info` | JSON output with endpoint and wsUrl |
34
+ | Scripted multi-page automation | Playwright directly | Not cjig's purpose |
35
+ | Screenshots, assertions, DOM queries | Playwright directly | Playwright's native strengths |
36
+ | Extension service worker testing | Playwright `launchPersistentContext` | Requires Target.attachToTarget |
8
37
 
9
- - **Session** = Chrome instance + profile + persisted state (cookies, localStorage, etc.)
10
- - **Harness** = named script from the project's script registry, injected into a page
11
- - **Lifecycle**: launch → navigate → inject → exercise → [modify → auto-reinject] → exercise
38
+ ## Before Using cjig for Automation
12
39
 
13
- The project's `.cjig.json` is the source of truth. Read it first to understand what scripts are available, what build hooks exist, and what file paths are watched.
40
+ If your task involves scripted navigation, clicking, form filling, or multi-step browser automation: skip cjig and use Playwright directly. cjig's value is in what Playwright can't easily do from the outside (CSP bypass, script registry, interactive REPL).
14
41
 
15
42
  ## How It Works: CDP Evaluation
16
43
 
17
- All evaluation uses CDP `Runtime.evaluate` — the same mechanism as the DevTools console. This means:
44
+ All evaluation uses CDP `Runtime.evaluate` in the page's **main world** — the same context as the DevTools console:
18
45
 
19
- - **CSP bypass**: Both `eval` and `inject` work on any page regardless of Content-Security-Policy headers. There are no script tags involved.
46
+ - **CSP bypass**: Both `eval` and `inject` work on any page regardless of Content-Security-Policy headers. No script tags involved.
20
47
  - **Globals persist**: Variables assigned via `globalThis.foo = ...` survive across calls and are visible to page scripts.
21
- - **`inject` fetches server-side**: `cjig inject` fetches the script URL in the Node.js process (bypassing CORS), then evaluates the content via CDP. It does not create `<script>` elements.
48
+ - **`inject` fetches server-side**: `cjig inject` fetches the script URL in the Node.js process (bypassing CORS), then evaluates the content via CDP.
22
49
 
23
50
  ## Speed Principle
24
51
 
@@ -31,59 +58,33 @@ Prefer `cjig` CLI commands over Chrome DevTools MCP tools whenever possible:
31
58
 
32
59
  **Fall back to Chrome DevTools MCP** only for capabilities the CLI lacks: screenshots, performance traces, network inspection, DOM snapshots, and visual page interaction.
33
60
 
34
- ## When to Use What
35
-
36
- | Need | Tool | Why |
37
- |------|------|-----|
38
- | One expression, current tab | `cjig eval "expr"` | One-shot, fast |
39
- | One expression, specific tab | `cjig eval --tab <sel> "expr"` | Tab targeting in one process |
40
- | Inject a file into any page | `cjig eval-file bundle.js` | CSP-proof file evaluation |
41
- | Inject a named harness | `cjig inject <name>` | Registry lookup + CSP-proof inject |
42
- | Multi-step exploration | `cjig repl` | Persistent session, dot-commands |
43
- | Live dev with file watching | `cjig repl` then `.watch on` | Auto re-inject on file save |
44
- | Multi-page scripted automation | Playwright | Not cjig's purpose |
45
-
46
- Each CLI invocation is a **fresh process** — tab state does not persist between invocations. Use `--tab` to target a specific tab per command, or use the REPL for persistent sessions.
47
-
48
61
  ## Session Management
49
62
 
50
- - `cjig status` — check if Chrome is running
51
- - `cjig launch` — start Chrome with default profile
52
- - `cjig launch --profile=testing` — start with a named profile
53
- - Profiles are isolated from the user's normal browser
54
- - State persists across runs in `~/.local/share/cjig/chrome-profiles/`
55
- - Session metadata stored at `~/.local/state/cjig/`
56
-
57
- ## Harness Workflow
58
-
59
- 1. **Read project config**: check `.cjig.json` in the project root for `scripts.registry`
60
- 2. **Launch Chrome** if not running: `cjig launch`
61
- 3. **Navigate** to the target page: `cjig eval "location.href = 'http://...'"`
62
- 4. **Inject harness** by name: `cjig inject <name>`
63
- 5. **Exercise** via eval using `windowApi` or `alias` from the registry: `cjig eval "BS.overlayOn()"`
64
- 6. **For iterative development**, suggest `.watch on` in the REPL for live reload on file save
65
-
66
- ## Command Reference
67
-
68
- ### Session
69
-
70
63
  | Command | Description |
71
64
  |---|---|
72
- | `cjig launch [--profile=NAME]` | Launch Chrome with debugging enabled |
65
+ | `cjig launch` | Launch Chrome with default profile |
66
+ | `cjig launch --profile=NAME` | Launch with named profile |
67
+ | `cjig launch --extensions /path/to/ext` | Launch with unpacked extension |
68
+ | `cjig attach --port 9333` | Attach to already-running Chrome |
73
69
  | `cjig status` | Check if Chrome is running |
70
+ | `cjig connection-info` | Export connection info as JSON |
71
+ | `cjig connection-info --json` | Machine-readable JSON output |
74
72
 
75
- ### Tab Targeting
73
+ ## Tab Targeting
76
74
 
77
75
  | Command | Description |
78
76
  |---|---|
79
77
  | `cjig tabs` | List open tabs (index + title + URL) |
80
78
  | `cjig tab <pattern\|index>` | Switch to a tab by title/URL pattern or index |
81
79
  | `cjig open <url>` | Open a new tab |
80
+ | `cjig open --timeout <ms> <url>` | Open with custom navigation timeout |
81
+ | `cjig open --wait-until <strategy> <url>` | Wait strategy: `domcontentloaded\|load\|networkidle` |
82
+ | `cjig open --no-wait <url>` | Fire-and-forget (don't wait for navigation) |
82
83
  | `--tab <selector>` | Flag for eval, eval-file, inject, cljs-eval |
83
84
 
84
85
  Tab selector: numbers select by index (0, 1, 2...), strings search URL and title.
85
86
 
86
- ### Evaluation
87
+ ## Evaluation
87
88
 
88
89
  | Command | Description |
89
90
  |---|---|
@@ -94,14 +95,24 @@ Tab selector: numbers select by index (0, 1, 2...), strings search URL and title
94
95
  | `cjig cljs-eval <code>` | Compile ClojureScript and evaluate |
95
96
  | `cjig repl` | Start interactive REPL |
96
97
 
97
- ### Harness
98
+ ## Harness
98
99
 
99
100
  | Command | Description |
100
101
  |---|---|
101
102
  | `cjig inject <name\|url>` | Inject a script by registry name or URL |
102
103
  | `cjig inject --tab <sel> <name>` | Inject into a specific tab |
103
104
 
104
- ### Configuration
105
+ ## Profiles
106
+
107
+ | Command | Description |
108
+ |---|---|
109
+ | `cjig profiles list` | List known profiles |
110
+ | `cjig profiles create <name> --extensions ...` | Create a named profile with extensions |
111
+ | `cjig launch --profile=NAME` | Launch with profile's saved config |
112
+
113
+ Profiles remember extensions, flags, and default URL. Config stored at `~/.config/cjig/profiles/<name>.json`.
114
+
115
+ ## Configuration
105
116
 
106
117
  | Command | Description |
107
118
  |---|---|
@@ -111,6 +122,26 @@ Tab selector: numbers select by index (0, 1, 2...), strings search URL and title
111
122
  | `cjig install-skill` | Symlink skill to `~/.claude/skills/` |
112
123
  | `cjig uninstall-skill` | Remove skill symlink |
113
124
 
125
+ ## Connecting Playwright to cjig's Chrome
126
+
127
+ ```js
128
+ import { getConnectionInfo } from 'chrome-jig';
129
+ import { chromium } from 'playwright';
130
+
131
+ const { info } = await getConnectionInfo('localhost', 9222);
132
+ const browser = await chromium.connectOverCDP(info.endpoint);
133
+ ```
134
+
135
+ Or from the command line:
136
+
137
+ ```bash
138
+ # Get the endpoint
139
+ cjig connection-info --json | jq -r '.endpoint'
140
+
141
+ # Use with Playwright MCP
142
+ # Configure --cdp-endpoint to point at cjig's Chrome port
143
+ ```
144
+
114
145
  ## Reading Project Config
115
146
 
116
147
  The `.cjig.json` file defines the development environment:
@@ -128,29 +159,61 @@ The `.cjig.json` file defines the development environment:
128
159
  }
129
160
  }
130
161
  },
162
+ "extensions": ["/path/to/unpacked-extension"],
163
+ "connection": {
164
+ "retries": 3,
165
+ "fallbackHosts": ["127.0.0.1"]
166
+ },
131
167
  "watch": {
132
168
  "paths": ["dist/harnesses/*.js"],
133
169
  "debounce": 300
134
- },
135
- "hooks": {
136
- "preBuild": "pnpm build:harnesses"
137
170
  }
138
171
  }
139
172
  ```
140
173
 
141
174
  Key fields:
142
175
 
176
+ - `extensions` — unpacked extension paths to load on launch
177
+ - `connection.retries` — retry count for transient connect failures (default: 3)
178
+ - `connection.fallbackHosts` — additional hosts to try (e.g. `["127.0.0.1"]` for IPv6 issues)
143
179
  - `scripts.registry[name].path` — script filename, resolved against `scripts.baseUrl`
144
- - `scripts.registry[name].windowApi` — the global object the script exposes (e.g., `window.BlockSegmenter`)
145
- - `scripts.registry[name].alias` — short name for the API (e.g., `BS`)
180
+ - `scripts.registry[name].windowApi` — the global object the script exposes
181
+ - `scripts.registry[name].alias` — short name for the API
146
182
  - `scripts.registry[name].quickStart` — example expression to try after injection
147
183
  - `watch.paths` — glob patterns for auto-reinject on file change
148
- - `hooks.preBuild` — build command run before injection
184
+
185
+ ## Harness Workflow
186
+
187
+ 1. **Read project config**: check `.cjig.json` in the project root for `scripts.registry`
188
+ 2. **Launch Chrome** if not running: `cjig launch`
189
+ 3. **Navigate** to the target page: `cjig eval "location.href = 'http://...'"`
190
+ 4. **Inject harness** by name: `cjig inject <name>`
191
+ 5. **Exercise** via eval using `windowApi` or `alias` from the registry
192
+ 6. **For iterative development**, suggest `.watch on` in the REPL for live reload
193
+
194
+ ## Connection Reliability
195
+
196
+ All connection-using commands automatically retry up to 3 times with exponential backoff on transient failures (EPERM, ECONNREFUSED, timeout). Override with `--retries <n>` and `--retry-delay <ms>`.
197
+
198
+ ## Error Handling
199
+
200
+ cjig uses typed exit codes:
201
+
202
+ | Exit Code | Category | Meaning |
203
+ |-----------|----------|---------|
204
+ | 0 | — | Success |
205
+ | 2 | `connection` | Cannot connect to Chrome |
206
+ | 3 | `timeout` | Navigation timed out |
207
+ | 4 | `no-page` | No page/tab available |
208
+ | 5 | `evaluation` | JavaScript evaluation error |
209
+
210
+ With `--json`, errors are structured JSON on stderr: `{"error":"...","category":"connection","retryable":true,"exitCode":2}`
149
211
 
150
212
  ## Limitations
151
213
 
152
- - Each `cjig` CLI invocation is a **fresh process**. Tab state does not persist between invocations. Use `--tab` to target a specific tab, or use `cjig repl` for a persistent session.
153
- - cjig is a **debugging and development tool**, not a browser automation framework. For scripted multi-page workflows across N URLs, use Playwright directly.
214
+ - **Main world only**: All evaluation runs in the page's main world. No isolated world or extension service worker eval.
215
+ - **Fresh process per invocation**: Tab state does not persist between CLI calls. Use `--tab` to target, or `cjig repl` for a persistent session.
216
+ - **Not a browser automation framework**: For scripted multi-page workflows, use Playwright directly.
154
217
  - The REPL and nREPL share a single connection. Tab switches in the REPL (`.tab`) affect nREPL evaluations too.
155
218
 
156
219
  ## Anti-Patterns
@@ -160,3 +223,4 @@ Key fields:
160
223
  - Do not forget to check `cjig status` before attempting to connect
161
224
  - Do not skip reading `.cjig.json` — it tells you what harnesses exist and how to use them
162
225
  - Do not chain separate `cjig tab` + `cjig eval` invocations expecting tab state to persist — use `cjig eval --tab` instead
226
+ - Do not use cjig for scripted automation — use Playwright and connect it to cjig's Chrome via `connection-info`
@@ -13,6 +13,11 @@ export interface ConnectionOptions {
13
13
  host: string;
14
14
  port: number;
15
15
  }
16
+ export interface OpenPageOptions {
17
+ timeout?: number;
18
+ waitUntil?: 'load' | 'domcontentloaded' | 'networkidle';
19
+ noWait?: boolean;
20
+ }
16
21
  export declare class ChromeConnection {
17
22
  private options;
18
23
  private browser;
@@ -62,7 +67,7 @@ export declare class ChromeConnection {
62
67
  /**
63
68
  * Open a new page with the given URL
64
69
  */
65
- openPage(url: string): Promise<Page>;
70
+ openPage(url: string, options?: OpenPageOptions): Promise<Page>;
66
71
  /**
67
72
  * Evaluate JavaScript in the current page via CDP Runtime.evaluate.
68
73
  * Runs in the page's main world (same as the browser console),
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/chrome/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqC,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEtF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,gBAAgB;IAMf,OAAO,CAAC,OAAO;IAL3B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,UAAU,CAA2B;gBAEzB,OAAO,EAAE,iBAAiB;IAE9C,OAAO,CAAC,cAAc;IAKtB,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IASnC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAU1D;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAU5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAKjC;;OAEG;IACH,cAAc,IAAI,IAAI,GAAG,IAAI;IAI7B;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAgBvD;;OAEG;IACG,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAW5D;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1C;;;;OAIG;IACG,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBjD;;;;OAIG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C;;;OAGG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;CAW3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAM,GAAG,gBAAgB,CAK3F"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/chrome/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqC,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGtF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,aAAa,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,gBAAgB;IAMf,OAAO,CAAC,OAAO;IAL3B,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,UAAU,CAA2B;gBAEzB,OAAO,EAAE,iBAAiB;IAE9C,OAAO,CAAC,cAAc;IAKtB,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IASnC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAU1D;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAU5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAe9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAKjC;;OAEG;IACH,cAAc,IAAI,IAAI,GAAG,IAAI;IAI7B;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAgBvD;;OAEG;IACG,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAW5D;;OAEG;IACG,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BrE;;;;OAIG;IACG,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBjD;;;;OAIG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS9C;;;OAGG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzD;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;CAW3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAM,GAAG,gBAAgB,CAK3F"}
@@ -2,6 +2,7 @@
2
2
  * Chrome DevTools Protocol connection via Playwright
3
3
  */
4
4
  import { chromium } from 'playwright-core';
5
+ import { NoPageError, EvaluationError, TimeoutError } from '../errors.js';
5
6
  export class ChromeConnection {
6
7
  options;
7
8
  browser = null;
@@ -136,12 +137,29 @@ export class ChromeConnection {
136
137
  /**
137
138
  * Open a new page with the given URL
138
139
  */
139
- async openPage(url) {
140
+ async openPage(url, options) {
140
141
  if (!this.context) {
141
- throw new Error('Not connected to Chrome');
142
+ throw new NoPageError('Not connected to Chrome');
142
143
  }
143
144
  const page = await this.context.newPage();
144
- await page.goto(url);
145
+ if (options?.noWait) {
146
+ page.goto(url).catch(() => { }); // fire-and-forget
147
+ }
148
+ else {
149
+ try {
150
+ await page.goto(url, {
151
+ timeout: options?.timeout,
152
+ waitUntil: options?.waitUntil,
153
+ });
154
+ }
155
+ catch (err) {
156
+ const msg = err instanceof Error ? err.message : String(err);
157
+ if (msg.toLowerCase().includes('timeout')) {
158
+ throw new TimeoutError(`Navigation timed out: ${url}`);
159
+ }
160
+ throw err;
161
+ }
162
+ }
145
163
  this.setCurrentPage(page);
146
164
  return page;
147
165
  }
@@ -152,7 +170,7 @@ export class ChromeConnection {
152
170
  */
153
171
  async evaluate(expression) {
154
172
  if (!this.currentPage) {
155
- throw new Error('No page selected');
173
+ throw new NoPageError();
156
174
  }
157
175
  const cdp = await this.getCDPSession();
158
176
  const result = await cdp.send('Runtime.evaluate', {
@@ -164,7 +182,7 @@ export class ChromeConnection {
164
182
  const text = result.exceptionDetails.exception?.description
165
183
  ?? result.exceptionDetails.text
166
184
  ?? 'Evaluation failed';
167
- throw new Error(text);
185
+ throw new EvaluationError(text);
168
186
  }
169
187
  return result.result.value;
170
188
  }
@@ -193,7 +211,7 @@ export class ChromeConnection {
193
211
  */
194
212
  async reload() {
195
213
  if (!this.currentPage) {
196
- throw new Error('No page selected');
214
+ throw new NoPageError();
197
215
  }
198
216
  await this.currentPage.reload();
199
217
  }
@@ -202,7 +220,7 @@ export class ChromeConnection {
202
220
  */
203
221
  async getCDPSession() {
204
222
  if (!this.currentPage) {
205
- throw new Error('No page selected');
223
+ throw new NoPageError();
206
224
  }
207
225
  if (!this.cdpSession) {
208
226
  this.cdpSession = await this.currentPage.context().newCDPSession(this.currentPage);
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/chrome/connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/chrome/connection.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export interface LaunchOptions {
6
6
  profile: string;
7
7
  chromePath?: string;
8
8
  chromeFlags?: string[];
9
+ extensions?: string[];
9
10
  url?: string;
10
11
  }
11
12
  export interface LaunchResult {
@@ -15,10 +16,12 @@ export interface LaunchResult {
15
16
  port?: number;
16
17
  profile?: string;
17
18
  }
18
- interface SessionState {
19
+ export interface SessionState {
19
20
  pid?: number;
20
21
  port: number;
22
+ host: string;
21
23
  profile: string;
24
+ source: 'launched' | 'attached';
22
25
  startedAt: string;
23
26
  }
24
27
  /**
@@ -33,6 +36,10 @@ export declare function isProfileLocked(profileDir: string): boolean;
33
36
  * Check if Chrome is already running on the specified port
34
37
  */
35
38
  export declare function isPortInUse(port: number, host?: string): Promise<boolean>;
39
+ /**
40
+ * Save session state for later recovery
41
+ */
42
+ export declare function saveSessionState(state: SessionState): void;
36
43
  /**
37
44
  * Load session state
38
45
  */
@@ -49,5 +56,4 @@ export declare function getStatus(host?: string, port?: number): Promise<{
49
56
  version?: Record<string, string>;
50
57
  session?: SessionState;
51
58
  }>;
52
- export {};
53
59
  //# sourceMappingURL=launcher.d.ts.map