npm package: @lmist/cloak
Description: Chrome sidecar for OpenCLI with daemonized Patchright startup and remembered cookie URLs
Latest version: 2.2.0

<!-- Generated from README.org by scripts/render-readme.cjs. Do not edit README.md directly. -->

![cloak logo](docs/assets/cloak-logo-readme-centered.png)

# what it is

`cloak` is the browser sidecar for [OpenCLI](https://github.com/jackwener/opencli). It launches a fresh [Patchright](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright/) browser with the pinned [OpenCLI extension archive](https://github.com/jackwener/opencli/releases/download/v1.6.8/opencli-extension.zip) loaded every time it starts.

# motivation

OpenCLI's default browser-backed flow still centers a browser profile that already has the OpenCLI Browser Bridge installed and logged into the target sites. The daemon is real, but it is only the local bridge in the path `opencli CLI -> local daemon -> Browser Bridge extension -> Chrome APIs`. It is not, by itself, a disposable browser runner with its own cookie import workflow.

That means a user who is comfortable creating a separate Chrome or Chromium profile for OpenCLI, installing the extension there, and logging into sites there may not need `cloak`. That setup is simpler and has fewer moving parts.

`cloak` exists for the narrower case where that tradeoff is not acceptable: keep the OpenCLI extension out of the browser profile used for daily browsing, while still reusing login state from that profile when needed.

It does that by launching a fresh Patchright Chromium with the pinned OpenCLI extension loaded and, when requested, importing cookies from a chosen local Chrome profile into that temporary browser context.

This solves a specific product gap:

- OpenCLI assumes extension-in-profile session reuse.
- A dedicated secondary browser profile avoids touching the main profile, but it still requires installing the extension and maintaining separate logged-in state.
- `cloak` keeps the extension out of the daily browser profile while making cookie reuse explicit, scoped, and disposable.

In practical terms, that gives `cloak` three concrete reasons to exist:

- isolated runtime: the automation browser is fresh and disposable instead of being the user's normal browser profile
- explicit cookie reuse: cookies can be imported for a selected site and profile on demand instead of assuming the active browser profile is the automation target
- cleaner trust boundary: the extension does not need to live in the user's day-to-day browser profile

That separation does not remove trust assumptions; it moves them. Instead of trusting the extension inside the daily browser profile, the user trusts `cloak` to read local Chrome cookies correctly and inject them into its temporary browser context. That is why `cloak` documents cookie-import limitations and keeps persisted cookie snapshots opt-in.

OpenCLI also documents a direct CDP path for some remote and headless setups, but its regular website adapter model is still built around the Browser Bridge extension and browser-session cookie reuse. In that sense, `cloak` is not a duplicate of OpenCLI's daemon. It is the sidecar that fills the current gap between `install the extension in a browser profile` and `use a disposable browser while borrowing an existing Chrome session`.

# install

Install `cloak` globally and verify the CLI:

``` bash
npm install -g @lmist/cloak
cloak --help
```

During `npm install`, `cloak` tries to:

- warm the pinned OpenCLI extension cache
- install the Patchright Chromium browser

If the browser download step gets skipped or fails in your environment, retry it manually:

``` bash
npx patchright install chromium
```

If you use OpenCLI with it, install that separately:

``` bash
npm install -g @jackwener/opencli
npx skills add jackwener/opencli
```

# usage

If you installed from a checkout but did not run `npm install -g .`, use `node dist/main.js` everywhere below in place of `cloak`.

Check the installed version:

``` bash
cloak version
```

Pick a default Chrome profile once:

``` bash
cloak profile list
cloak profile use "Profile 7"
cloak profile show
```

See the cookie-bearing URLs for the default profile and optionally remember a subset for future runs:

``` bash
cloak sites list
cloak sites list --no-pager --limit 25
```

Run headless with the remembered profile and remembered URLs:

``` bash
cloak run
```

Run visibly instead of headless:

``` bash
cloak run --window
```

Run from a cookie export file without selecting a Chrome profile:

``` bash
cloak run --cookie-file ./cookies.json
```

Non-interactive path, using the saved default profile and remembering the URL without a prompt:

``` bash
cloak run --persist-cookies --consent --cookie-url https://x.com
```

Non-interactive path, using an explicit profile:

``` bash
cloak run --profile "Profile 7" --persist-cookies --consent --cookie-url https://x.com
```

Run as a daemon and manage it later:

``` bash
cloak daemon start --profile "Profile 7" --persist-cookies --consent --cookie-url https://x.com
cloak daemon status
cloak daemon logs
cloak daemon stop
cloak daemon restart
```

See where `cloak` keeps its state, then destroy it if you really mean it:

``` bash
cloak storage show
cloak storage destroy
```

# runtime and storage

`cloak` launches headless by default. Pass `--window` when you want a visible browser window.

If you import Chrome cookies, `cloak` reads them live from the selected local Chrome profile at startup and injects them into the fresh browser context for that run.

If you use `--cookie-file`, `cloak` reads cookies from a JSON file instead. It accepts either a plain JSON array of cookies or a Playwright storage-state JSON object with a top-level `cookies` array. That path does not require a Chrome profile.

\(1\) What persists:

- `~/.cache/cloak/opencli-extension.zip`
- `~/.config/cloak/state.sqlite` with the default profile, remembered cookie URLs, and daemon state
- `~/.cache/cloak/daemon.log` when you use `cloak daemon start`

Use `cloak storage show` to print those paths, and `cloak storage destroy` to remove the whole config tree after a confirmation prompt.

\(2\) What stays ephemeral:

- the extracted extension directory in the OS temp directory
- the Patchright user data directory in the OS temp directory
- the injected cookie set itself

# build from source

If you want to work on `cloak` itself, use the repository directly:

``` bash
git clone https://github.com/lmist/cloak.git
cd cloak
npm install
npm run build
node dist/main.js --help
```

If you want a global `cloak` command built from that checkout:

``` bash
npm install -g .
cloak --help
```

# one sharp edge

Chrome cookie extraction now uses `cloak`'s in-tree reader instead of the old external helper. That removes the install-time native dependency warnings and preserves distinct same-name cookies across different paths and subdomains.

The sharp edge that remains is platform crypto. `cloak` still has to ask the OS for the key Chrome uses to encrypt cookies. If `cloak run --cookie-url https://x.com` tells you Chrome cookie support is unavailable, it could not reach that secret storage in the current environment. On Windows, Chrome app-bound cookie encryption is not supported yet.