camou 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is loosely based on Keep a Changelog and uses semantic versioning.
6
+
7
+ ## [0.2.0] - 2026-03-15
8
+
9
+ ### Added
10
+
11
+ - Added a public Node API so `camou` can be used from scripts, not just the CLI.
12
+ - Added `launchCamoufox()`, `launchCamoufoxContext()`, and `withCamoufox()` for Playwright-based programmatic control.
13
+ - Exported browser management helpers from the package root for script usage.
14
+
15
+ ### Changed
16
+
17
+ - Documented the new Node script workflow in `README.md`.
18
+ - Updated the `camou` skill to explain when to use the CLI vs the Node API and how to drive Camou from scripts.
19
+
20
+ ## [0.1.1] - 2026-03-15
21
+
22
+ ### Added
23
+
24
+ - Added `skills/camou/` with a reusable Camou skill and workflow reference for AI assistants.
25
+ - Added this `CHANGELOG.md` so future releases have a maintained change history.
26
+
27
+ ### Changed
28
+
29
+ - Reworked `README.md` to be more useful for npm users, first-time visitors, and agent-style workflows.
30
+ - Improved default non-JSON CLI output for common commands so everyday use is easier to scan.
31
+
32
+ ### Fixed
33
+
34
+ - Fixed `camou session list` and `camou tab list` to print human-readable output instead of raw JSON when `--json` is not enabled.
35
+ - Added a readable non-JSON summary for `camou doctor` while preserving the full structured payload under `--json`.
36
+ - Cleaned up non-JSON output for actions like `open`, `click`, `fill`, `press`, `wait`, `session stop`, `tab new`, and `tab close`.
37
+
38
+ ## [0.1.0] - 2026-03-15
39
+
40
+ ### Added
41
+
42
+ - Initial public release of the `camou` npm package.
43
+ - Local CLI and daemon for driving Camoufox through Playwright without the Python SDK.
44
+ - Camoufox install, remove, version switching, compatibility probes, and doctor diagnostics.
45
+ - Persistent sessions, named tabs, snapshot refs, JSON output mode, presets, and integration tests.
package/README.md CHANGED
@@ -1,202 +1,393 @@
1
1
  # Camoucli
2
2
 
3
- Camoucli is a Node.js-first CLI and local daemon for driving Camoufox through Playwright.
3
+ Camoucli is a local-first CLI and background daemon for driving [Camoufox](https://github.com/daijro/camoufox) through Playwright, without depending on the Camoufox Python SDK.
4
4
 
5
- The published npm package is `camou`, and the installed command is `camou`.
5
+ - npm package: `camou`
6
+ - installed command: `camou`
7
+ - project/repo name: Camoucli
6
8
 
7
- It is built for local agent-style workflows:
9
+ Camou is built for agent-style browser workflows:
8
10
 
9
- - keep a browser session alive across CLI invocations
11
+ - keep a browser session alive across separate CLI invocations
10
12
  - preserve login state with persistent profiles
11
- - target named tabs and sessions
12
- - work with stable `@eN` refs from text snapshots
13
- - install and switch Camoufox versions without the Python SDK
13
+ - operate named tabs in parallel without ref collisions
14
+ - interact through stable `@eN` refs from text snapshots
15
+ - install, switch, and diagnose Camoufox browser versions from the CLI
14
16
 
15
- ## Requirements
17
+ Camou takes strong inspiration from [vercel-labs/agent-browser](https://github.com/vercel-labs/agent-browser) and [BUNotesAI/agent-browser-session](https://github.com/BUNotesAI/agent-browser-session), but is built for the Camoufox + Playwright Firefox path and persistent local daemon workflows.
16
18
 
17
- - Node.js `>=20`
18
- - a supported OS for Camoufox releases
19
+ ## Why Camou
20
+
21
+ | Feature | Why it matters |
22
+ | --- | --- |
23
+ | Persistent profiles | Login once and reuse the same authenticated browser state later |
24
+ | Named sessions | Keep separate workspaces like `work`, `shopping`, or `github` isolated |
25
+ | Named tabs | Run multiple agents against the same browser session without fighting over one active page |
26
+ | Snapshot refs | Use `@e1`, `@e2`, ... from `snapshot` instead of brittle selectors when driving pages |
27
+ | Version manager | Install and switch Camoufox builds without bundling the browser into the npm package |
28
+ | Doctor diagnostics | Check launch compatibility, bundle health, and Linux shared-library issues quickly |
19
29
 
20
30
  ## Install
21
31
 
22
- End users:
32
+ Requirements:
33
+
34
+ - Node.js `>=20`
35
+ - a supported Camoufox release for your OS
36
+
37
+ Global install (recommended):
23
38
 
24
39
  ```bash
25
40
  npm install -g camou
41
+ camou install
26
42
  ```
27
43
 
28
- Contributors / local development:
44
+ One-off usage with `npx`:
29
45
 
30
46
  ```bash
31
- npm install
32
- npm run build
47
+ npx camou install
48
+ npx camou open https://example.com
33
49
  ```
34
50
 
35
- For local development:
51
+ From this repo:
36
52
 
37
53
  ```bash
54
+ npm install
55
+ npm run build
38
56
  npm run dev -- --help
39
- npm run dev:daemon
40
57
  ```
41
58
 
42
- ## Quick Start
59
+ Notes:
60
+
61
+ - Browser download is explicit. Installing the npm package does not download Camoufox.
62
+ - `camou install` runs a quick headless launch probe after download.
63
+ - `camou use <version>` runs the same compatibility check when you switch versions.
64
+
65
+ ## Install The Skill
66
+
67
+ Camou also ships an agent skill that can be installed through the open skills ecosystem at [skills.sh](https://skills.sh).
43
68
 
44
- Install a browser build:
69
+ Install it from this repo:
45
70
 
46
71
  ```bash
47
- camou install
72
+ npx skills add txchen/camoucli --skill camou
48
73
  ```
49
74
 
50
- `install` runs a quick launch probe after download so it can warn if the installed browser does not work with the current `playwright-core` version.
51
- `use` runs the same check when you switch versions.
75
+ Useful variants:
76
+
77
+ ```bash
78
+ # Preview available skills in the repo
79
+ npx skills add txchen/camoucli --list
52
80
 
53
- Open a page and capture refs:
81
+ # Install globally for a specific agent
82
+ npx skills add txchen/camoucli --skill camou -g -a opencode
83
+ ```
84
+
85
+ The skill teaches agents the recommended Camou workflow: `open -> snapshot -i -> interact with @refs -> re-snapshot`, plus session/tab/version troubleshooting guidance.
86
+
87
+ ## Quick Start
54
88
 
55
89
  ```bash
90
+ camou install
56
91
  camou open https://example.com
57
92
  camou snapshot -i
93
+ # @e1 a "Learn more"
94
+ camou click @e1
95
+ camou get title
96
+ ```
97
+
98
+ What happens behind the scenes:
99
+
100
+ 1. `camou open` auto-starts the local daemon if needed.
101
+ 2. Camoufox launches with a persistent profile for the default session.
102
+ 3. `snapshot -i` returns interactive elements with refs like `@e1`.
103
+ 4. Later commands reuse the same browser session and profile.
104
+
105
+ Important ref rule:
106
+
107
+ - Re-run `snapshot` after navigation or major page changes. Refs are per tab and are invalidated on navigation or a new snapshot.
108
+
109
+ ## Use From Node Scripts
110
+
111
+ Camou can also be used as a Node library, not just a CLI.
112
+
113
+ The programmatic API is Playwright-based: it launches Camoufox for you and gives you a real Playwright `BrowserContext`, similar in spirit to the Camoufox Python wrapper.
114
+
115
+ ```ts
116
+ import { launchCamoufox } from 'camou';
117
+
118
+ const camou = await launchCamoufox({
119
+ session: 'script',
120
+ headless: false,
121
+ });
122
+
123
+ const page = await camou.context.newPage();
124
+ await page.goto('https://example.com');
125
+ console.log(await page.title());
126
+
127
+ await camou.close();
58
128
  ```
59
129
 
60
- Use refs in later commands:
130
+ If you prefer a scoped helper:
131
+
132
+ ```ts
133
+ import { withCamoufox } from 'camou';
134
+
135
+ await withCamoufox({ session: 'script' }, async ({ context }) => {
136
+ const page = await context.newPage();
137
+ await page.goto('https://example.com');
138
+ console.log(await page.title());
139
+ });
140
+ ```
141
+
142
+ Useful exported helpers include:
143
+
144
+ - `launchCamoufox()`
145
+ - `launchCamoufoxContext()`
146
+ - `withCamoufox()`
147
+ - `installCamoufox()`
148
+ - `listInstalledBrowsers()`
149
+ - `setCurrentBrowser()`
150
+ - `doctorCamoufox()`
151
+
152
+ Notes:
153
+
154
+ - install a browser first with `camou install` or `installCamoufox()`
155
+ - use a dedicated `session` name in scripts if you do not want to share the default CLI profile
156
+ - the returned context is a normal Playwright context, so you can use standard Playwright APIs from there
157
+
158
+ ## Recommended Agent Workflow
159
+
160
+ For agents and automation loops, this is the happy path:
61
161
 
62
162
  ```bash
63
- camou click @e1
64
- camou fill @e2 "hello"
65
- camou get title
163
+ camou open https://target.site
164
+ camou snapshot -i --json
165
+ camou click @e3
166
+ camou fill @e5 "hello"
167
+ camou snapshot -i --json
66
168
  ```
67
169
 
68
- When working from this repo without a global install, prefix commands with `npm run dev --`.
170
+ Why this works well:
69
171
 
70
- The daemon auto-starts on demand, so later commands reuse the same session and profile.
172
+ - `snapshot` gives a stable text representation of the page
173
+ - refs are deterministic within the current tab snapshot
174
+ - `--json` gives machine-readable success and error payloads
175
+ - the daemon keeps browser state alive between commands
71
176
 
72
- ## What Works Today
177
+ ## Core Concepts
73
178
 
74
- ### Browser management
179
+ ### Session
75
180
 
76
- - `camou install [version]`
77
- - `camou remove [version]`
78
- - `camou use <version>`
79
- - `camou versions`
80
- - `camou presets`
81
- - `camou version`
82
- - `camou path`
83
- - `camou doctor`
181
+ A session is a named browser workspace selected with `--session <name>`.
84
182
 
85
- ### Page automation
183
+ - sessions have separate persistent profile directories
184
+ - different sessions isolate cookies, storage, downloads, and artifacts
185
+ - reuse the same session name to keep login state across runs
86
186
 
87
- - `camou open <url>`
88
- - `camou snapshot [-i]`
89
- - `camou click <selectorOrRef>`
90
- - `camou fill <selectorOrRef> <text>`
91
- - `camou press <key>`
92
- - `camou wait <selectorOrRef>`
93
- - `camou screenshot [path]`
94
- - `camou get url`
95
- - `camou get title`
96
- - `camou get text <selectorOrRef>`
97
-
98
- ### Session and tab management
99
-
100
- - `camou session list`
101
- - `camou session stop [name]`
102
- - `camou tab list`
103
- - `camou tab new [url]`
104
- - `camou tab close [nameOrIndex]`
187
+ Example:
105
188
 
106
- ## Common Flags
189
+ ```bash
190
+ camou open https://github.com --session work
191
+ camou open https://mail.google.com --session personal
192
+ ```
107
193
 
108
- Most browser commands support:
194
+ ### Tab
109
195
 
110
- - `--session <name>`
111
- - `--tabname <name>`
112
- - `--headless`
113
- - `--browser <version>`
114
- - `--config <path>`
115
- - `--config-json <json>`
116
- - `--prefs <path>`
117
- - `--prefs-json <json>`
118
- - `--preset <name>`
119
- - `--proxy <url>`
120
- - `--locale <locale>`
121
- - `--timezone <timezone>`
122
- - `--width <px>` / `--height <px>`
123
- - `--json`
124
- - `--verbose`
196
+ A tab is a named page binding inside a session selected with `--tabname <name>`.
125
197
 
126
- ## Example Flows
198
+ - tabs in the same session share browser profile state
199
+ - tabs keep separate page bindings and separate ref maps
200
+ - named tabs make concurrent agent workflows much safer
127
201
 
128
- Use a named session and tab:
202
+ Example:
129
203
 
130
204
  ```bash
131
- camou open https://github.com --session work --tabname github
132
- camou snapshot -i --session work --tabname github
205
+ camou open https://reddit.com --session work --tabname reddit
206
+ camou open https://news.ycombinator.com --session work --tabname hn
133
207
  ```
134
208
 
135
- Install and switch versions:
209
+ ### Ref
210
+
211
+ A ref is a snapshot-generated handle like `@e1` or `@e2`.
212
+
213
+ - refs come from `camou snapshot` or `camou snapshot -i`
214
+ - refs are only valid for the tab that created them
215
+ - refs are cleared when the page navigates or you take a new snapshot
216
+
217
+ ### Browser version
218
+
219
+ Camou keeps an active Camoufox version, but you can also pick a version per command.
220
+
221
+ - `camou use <version>` changes the active default version
222
+ - `camou <command> ... --browser <version>` runs a command against a specific installed version without changing the default
223
+
224
+ ## Common Workflows
225
+
226
+ ### Persistent login session
136
227
 
137
228
  ```bash
138
- camou install 135.0.1-beta.24
139
- camou install 134.0.0-beta.20
140
- camou versions
141
- camou use 134.0.0-beta.20
142
- camou version
229
+ camou open https://github.com/login --session work --tabname github
230
+ # log in once in the browser
231
+ camou open https://github.com/settings/profile --session work --tabname github
232
+ ```
233
+
234
+ Use the same `--session` name later and the login state is still there.
235
+
236
+ ### Multi-tab parallel-safe browsing
237
+
238
+ ```bash
239
+ camou open https://reddit.com --session research --tabname reddit
240
+ camou open https://news.ycombinator.com --session research --tabname hn
241
+
242
+ camou snapshot -i --session research --tabname reddit
243
+ camou snapshot -i --session research --tabname hn
143
244
  ```
144
245
 
145
- Check the current install inventory and launch compatibility:
246
+ Both tabs share the same browser profile, but each tab has its own page and ref map.
247
+
248
+ ### Install and switch versions
146
249
 
147
250
  ```bash
251
+ camou install 135.0.1-beta.24
252
+ camou install 135.0.1-beta.23
253
+ camou versions
254
+ camou use 135.0.1-beta.24
148
255
  camou doctor --json
149
256
  ```
150
257
 
151
- Launch a session with an explicit installed browser version without changing the global default:
258
+ ### Use a specific browser version for one session
152
259
 
153
260
  ```bash
154
261
  camou open https://example.com --session canary --browser 135.0.1-beta.24
155
262
  ```
156
263
 
157
- Save a screenshot to the session artifacts directory:
264
+ ### JSON output for automation
158
265
 
159
266
  ```bash
160
- camou screenshot --session work --tabname github
267
+ camou snapshot -i --json
268
+ camou get title --json
269
+ camou doctor --json
161
270
  ```
162
271
 
163
- ## Storage Layout
272
+ Errors are also structured when `--json` is enabled.
273
+
274
+ ## Command Reference
275
+
276
+ ### Browser management
277
+
278
+ ```bash
279
+ camou install [version]
280
+ camou remove [version]
281
+ camou use <version>
282
+ camou versions
283
+ camou presets
284
+ camou version
285
+ camou path
286
+ camou doctor
287
+ ```
288
+
289
+ ### Page automation
164
290
 
165
- Camoucli uses platform-specific app directories for its own state and profiles.
291
+ ```bash
292
+ camou open <url>
293
+ camou snapshot [-i]
294
+ camou click <selectorOrRef>
295
+ camou fill <selectorOrRef> <text>
296
+ camou press <key>
297
+ camou wait <selectorOrRef>
298
+ camou screenshot [path]
299
+ camou get url
300
+ camou get title
301
+ camou get text <selectorOrRef>
302
+ ```
166
303
 
167
- - session profiles live under `profiles/<session>/{user-data,downloads,artifacts}`
168
- - daemon state and logs live under the platform state/runtime dirs
304
+ ### Sessions and tabs
169
305
 
170
- Camoufox binaries are stored in the shared cache layout used by the Python library when possible:
306
+ ```bash
307
+ camou session list
308
+ camou session stop [name]
309
+ camou tab list
310
+ camou tab new [url]
311
+ camou tab close [nameOrIndex]
312
+ ```
171
313
 
172
- - Linux: `~/.cache/camoufox/browsers/official/<version>/`
173
- - macOS: `~/Library/Caches/camoufox/browsers/official/<version>/`
174
- - Windows: `%LOCALAPPDATA%\camoufox\Cache\browsers\official\<version>\`
314
+ ## Common Flags
315
+
316
+ Most browser commands support:
175
317
 
176
- This lets Camoucli reuse compatible Camoufox installs from the Python ecosystem and vice versa.
318
+ - `--session <name>`
319
+ - `--tabname <name>`
320
+ - `--headless`
321
+ - `--browser <version>`
322
+ - `--config <path>`
323
+ - `--config-json <json>`
324
+ - `--prefs <path>`
325
+ - `--prefs-json <json>`
326
+ - `--preset <name>`
327
+ - `--proxy <url>`
328
+ - `--locale <locale>`
329
+ - `--timezone <timezone>`
330
+ - `--width <px>`
331
+ - `--height <px>`
332
+ - `--json`
333
+ - `--verbose`
177
334
 
178
335
  ## Presets
179
336
 
180
- Built-in presets give you a small layer of tested ergonomics on top of raw config and prefs JSON:
337
+ Built-in presets give you a small layer of tested ergonomics on top of raw config and prefs JSON.
181
338
 
182
- - `default` - baseline launch with no additional overrides
183
- - `cache` - enables the Firefox cache/session prefs used by the Python library
184
- - `low-bandwidth` - blocks images and speculative requests for lighter automation sessions
185
- - `disable-coop` - relaxes Cross-Origin-Opener-Policy isolation for troublesome embedded flows
339
+ | Preset | What it does |
340
+ | --- | --- |
341
+ | `default` | Baseline launch with no extra overrides |
342
+ | `cache` | Enables the Firefox cache/session prefs used by the Python library |
343
+ | `low-bandwidth` | Blocks images and speculative requests for lighter automation sessions |
344
+ | `disable-coop` | Relaxes Cross-Origin-Opener-Policy isolation for troublesome embedded flows |
186
345
 
187
- List them from the CLI:
346
+ List them:
188
347
 
189
348
  ```bash
190
349
  camou presets
191
350
  ```
192
351
 
193
- Apply one or more presets to a browser command:
352
+ Apply one or more:
194
353
 
195
354
  ```bash
196
355
  camou open https://example.com --preset cache --preset low-bandwidth
197
356
  ```
198
357
 
199
- ## Compatibility Matrix
358
+ ## Doctor And Troubleshooting
359
+
360
+ `camou doctor --json` reports:
361
+
362
+ - installed Camoufox versions
363
+ - which version is active
364
+ - whether each version can launch with the current `playwright-core`
365
+ - bundle file checks
366
+ - Linux shared-library diagnostics
367
+ - remediation hints
368
+
369
+ Useful commands:
370
+
371
+ ```bash
372
+ camou versions
373
+ camou use 135.0.1-beta.24
374
+ camou doctor --json
375
+ ```
376
+
377
+ Common fixes:
378
+
379
+ - `Browser.setContrast is not supported`
380
+ - the selected Camoufox build is older than the bundled Playwright runtime
381
+ - switch to a newer browser version with `camou use <version>`
382
+ - profile/session locked
383
+ - another browser process is using that session profile
384
+ - stop the other browser or use a different `--session`
385
+ - executable missing or damaged
386
+ - reinstall with `camou install --force`
387
+ - Linux launch failures
388
+ - run `camou doctor --json` and install the missing shared libraries it reports
389
+
390
+ ## Current Compatibility
200
391
 
201
392
  Current local verification with `playwright-core` `1.51.1`:
202
393
 
@@ -205,14 +396,18 @@ Current local verification with `playwright-core` `1.51.1`:
205
396
  | `135.0.1-beta.24` | launches | smoke-tested successfully |
206
397
  | `135.0.1-beta.23` | incompatible | `Browser.setContrast` is not supported |
207
398
 
208
- ## Notes
399
+ ## Storage Layout
400
+
401
+ Camou keeps its own runtime state and profiles, but stores browser binaries in the shared Camoufox cache layout when possible.
402
+
403
+ - session data lives under `profiles/<session>/{user-data,downloads,artifacts}`
404
+ - daemon state and logs live under platform runtime/state directories
405
+ - Camoufox binaries live in the shared cache used by the Python library:
406
+ - Linux: `~/.cache/camoufox/browsers/official/<version>/`
407
+ - macOS: `~/Library/Caches/camoufox/browsers/official/<version>/`
408
+ - Windows: `%LOCALAPPDATA%\camoufox\Cache\browsers\official\<version>\`
209
409
 
210
- - The CLI is intentionally thin; the daemon owns browser lifecycle and persistent state.
211
- - `snapshot` creates per-tab `@eN` refs, and refs are cleared after navigation or a new snapshot.
212
- - Browser installation is explicit; the package does not download Camoufox during `npm install`.
213
- - `install` and `use` include a quick compatibility hint based on a real headless launch probe of the selected version.
214
- - `doctor` reports installed versions, a per-version launch compatibility matrix, shared-library diagnostics, and remediation hints.
215
- - Passing `--json` returns structured machine-readable errors for both top-level CLI failures and daemon responses.
410
+ This lets Camou reuse compatible Camoufox installs from the Python ecosystem and vice versa.
216
411
 
217
412
  ## Development
218
413
 
@@ -227,3 +422,17 @@ Optional targeted integration suite:
227
422
  ```bash
228
423
  npm run test:integration
229
424
  ```
425
+
426
+ Local development commands:
427
+
428
+ ```bash
429
+ npm run dev -- --help
430
+ npm run dev:daemon
431
+ ```
432
+
433
+ ## Acknowledgements
434
+
435
+ Camoucli learned a lot from these projects:
436
+
437
+ - [vercel-labs/agent-browser](https://github.com/vercel-labs/agent-browser) for the agent-oriented command workflow and skill ecosystem patterns
438
+ - [BUNotesAI/agent-browser-session](https://github.com/BUNotesAI/agent-browser-session) for persistent-session and named-tab ergonomics
package/dist/api.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import type { BrowserContext, Page } from 'playwright-core';
2
+ import type { LaunchInput, ResolvedLaunchConfig } from './camoufox/config.js';
3
+ import { type CamoucliPaths } from './state/paths.js';
4
+ export interface LaunchCamoufoxOptions extends LaunchInput {
5
+ session?: string | undefined;
6
+ paths?: CamoucliPaths | undefined;
7
+ verbose?: boolean | undefined;
8
+ }
9
+ export declare class CamoufoxSession {
10
+ readonly context: BrowserContext;
11
+ readonly sessionName: string;
12
+ readonly browserVersion: string;
13
+ readonly executablePath: string;
14
+ readonly profileDir: string;
15
+ readonly downloadsDir: string;
16
+ readonly artifactsDir: string;
17
+ readonly resolvedConfig: ResolvedLaunchConfig;
18
+ constructor(input: {
19
+ context: BrowserContext;
20
+ sessionName: string;
21
+ browserVersion: string;
22
+ executablePath: string;
23
+ profileDir: string;
24
+ downloadsDir: string;
25
+ artifactsDir: string;
26
+ resolvedConfig: ResolvedLaunchConfig;
27
+ });
28
+ newPage(): Promise<Page>;
29
+ pages(): Page[];
30
+ close(): Promise<void>;
31
+ }
32
+ export declare function launchCamoufox(options?: LaunchCamoufoxOptions): Promise<CamoufoxSession>;
33
+ export declare function launchCamoufoxContext(options?: LaunchCamoufoxOptions): Promise<BrowserContext>;
34
+ export declare function withCamoufox<T>(options: LaunchCamoufoxOptions, callback: (session: CamoufoxSession) => Promise<T> | T): Promise<T>;