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.
- package/README.md +159 -6
- package/SKILL.md +121 -57
- package/dist/chrome/connection.d.ts +6 -1
- package/dist/chrome/connection.d.ts.map +1 -1
- package/dist/chrome/connection.js +25 -7
- package/dist/chrome/connection.js.map +1 -1
- package/dist/chrome/launcher.d.ts +8 -2
- package/dist/chrome/launcher.d.ts.map +1 -1
- package/dist/chrome/launcher.js +9 -2
- package/dist/chrome/launcher.js.map +1 -1
- package/dist/chrome/resilience.d.ts +31 -0
- package/dist/chrome/resilience.d.ts.map +1 -0
- package/dist/chrome/resilience.js +78 -0
- package/dist/chrome/resilience.js.map +1 -0
- package/dist/cli.js +174 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/attach.d.ts +11 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +34 -0
- package/dist/commands/attach.js.map +1 -0
- package/dist/commands/connection-info.d.ts +18 -0
- package/dist/commands/connection-info.d.ts.map +1 -0
- package/dist/commands/connection-info.js +30 -0
- package/dist/commands/connection-info.js.map +1 -0
- package/dist/commands/eval.d.ts +3 -0
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +9 -0
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/install-skill.d.ts.map +1 -1
- package/dist/commands/install-skill.js +30 -1
- package/dist/commands/install-skill.js.map +1 -1
- package/dist/commands/launch.d.ts +1 -0
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +5 -0
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/profiles.d.ts +24 -0
- package/dist/commands/profiles.d.ts.map +1 -0
- package/dist/commands/profiles.js +31 -0
- package/dist/commands/profiles.js.map +1 -0
- package/dist/config/loader.d.ts +3 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +40 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/profiles.d.ts +18 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +60 -0
- package/dist/config/profiles.js.map +1 -0
- package/dist/config/schema.d.ts +20 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/errors.d.ts +28 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +54 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +14 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- 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
|
|
63
|
-
cjig launch --profile=testing
|
|
64
|
-
cjig
|
|
65
|
-
cjig
|
|
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
|
|
364
|
+
└── profiles/ # Named profile configs
|
|
365
|
+
└── myext.json
|
|
214
366
|
|
|
215
367
|
~/.local/share/cjig/
|
|
216
368
|
└── chrome-profiles/ # Chrome user-data dirs
|
|
217
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
23
|
+
## When to Use cjig vs Playwright
|
|
6
24
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
145
|
-
- `scripts.registry[name].alias` — short name for the API
|
|
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
|
-
|
|
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
|
-
-
|
|
153
|
-
-
|
|
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;
|
|
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
|
|
142
|
+
throw new NoPageError('Not connected to Chrome');
|
|
142
143
|
}
|
|
143
144
|
const page = await this.context.newPage();
|
|
144
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAA6C,MAAM,iBAAiB,CAAC;
|
|
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
|