cloak22 2.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.
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ repo_root=$(git rev-parse --show-toplevel)
5
+ cd "$repo_root"
6
+
7
+ if ! git diff --cached --name-only --diff-filter=ACMR | grep -qx 'README.org'; then
8
+ exit 0
9
+ fi
10
+
11
+ node scripts/render-readme.cjs
12
+ git add README.md
@@ -0,0 +1,37 @@
1
+ #!/bin/sh
2
+ set -eu
3
+
4
+ repo_root=$(git rev-parse --show-toplevel)
5
+ cd "$repo_root"
6
+
7
+ readme_changed=false
8
+
9
+ while read -r local_ref local_sha remote_ref remote_sha
10
+ do
11
+ if [ -z "${local_ref:-}" ]; then
12
+ continue
13
+ fi
14
+
15
+ if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
16
+ continue
17
+ fi
18
+
19
+ if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
20
+ if git rev-list "$local_sha" --not --remotes | while read -r commit; do git diff-tree --no-commit-id --name-only -r "$commit"; done | grep -qx 'README.org'; then
21
+ readme_changed=true
22
+ break
23
+ fi
24
+ continue
25
+ fi
26
+
27
+ if git diff --name-only "$remote_sha" "$local_sha" | grep -qx 'README.org'; then
28
+ readme_changed=true
29
+ break
30
+ fi
31
+ done
32
+
33
+ if [ "$readme_changed" = false ]; then
34
+ exit 0
35
+ fi
36
+
37
+ node scripts/render-readme.cjs --check
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Louai Misto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,181 @@
1
+ <!-- Generated from README.org by scripts/render-readme.cjs. Do not edit README.md directly. -->
2
+
3
+ ![cloak logo](docs/assets/cloak-logo-readme-centered.png)
4
+
5
+ # what it is
6
+
7
+ `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.
8
+
9
+ # motivation
10
+
11
+ 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.
12
+
13
+ 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.
14
+
15
+ `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.
16
+
17
+ 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.
18
+
19
+ This solves a specific product gap:
20
+
21
+ - OpenCLI assumes extension-in-profile session reuse.
22
+ - A dedicated secondary browser profile avoids touching the main profile, but it still requires installing the extension and maintaining separate logged-in state.
23
+ - `cloak` keeps the extension out of the daily browser profile while making cookie reuse explicit, scoped, and disposable.
24
+
25
+ In practical terms, that gives `cloak` three concrete reasons to exist:
26
+
27
+ - isolated runtime: the automation browser is fresh and disposable instead of being the user's normal browser profile
28
+ - 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
29
+ - cleaner trust boundary: the extension does not need to live in the user's day-to-day browser profile
30
+
31
+ 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.
32
+
33
+ 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`.
34
+
35
+ # install
36
+
37
+ Install `cloak` globally and verify the CLI:
38
+
39
+ ``` bash
40
+ npm install -g cloak22
41
+ cloak --help
42
+ ```
43
+
44
+ The published package name is `cloak22`. The installed CLI command remains `cloak`.
45
+
46
+ During `npm install`, `cloak` tries to:
47
+
48
+ - warm the pinned OpenCLI extension cache
49
+ - install the Patchright Chromium browser
50
+
51
+ If the browser download step gets skipped or fails in your environment, retry it manually:
52
+
53
+ ``` bash
54
+ npx patchright install chromium
55
+ ```
56
+
57
+ If you use OpenCLI with it, install that separately:
58
+
59
+ ``` bash
60
+ npm install -g @jackwener/opencli
61
+ npx skills add jackwener/opencli
62
+ ```
63
+
64
+ # usage
65
+
66
+ If you installed from a checkout but did not run `npm install -g .`, use `node dist/main.js` everywhere below in place of `cloak`.
67
+
68
+ Check the installed version:
69
+
70
+ ``` bash
71
+ cloak version
72
+ ```
73
+
74
+ Pick a default Chrome profile once:
75
+
76
+ ``` bash
77
+ cloak profile list
78
+ cloak profile use "Profile 7"
79
+ cloak profile show
80
+ ```
81
+
82
+ See the cookie-bearing URLs for the default profile and optionally remember a subset for future runs:
83
+
84
+ ``` bash
85
+ cloak sites list
86
+ cloak sites list --no-pager --limit 25
87
+ ```
88
+
89
+ Run headless with the remembered profile and remembered URLs:
90
+
91
+ ``` bash
92
+ cloak run
93
+ ```
94
+
95
+ Run visibly instead of headless:
96
+
97
+ ``` bash
98
+ cloak run --window
99
+ ```
100
+
101
+ Run from a cookie export file without selecting a Chrome profile:
102
+
103
+ ``` bash
104
+ cloak run --cookie-file ./cookies.json
105
+ ```
106
+
107
+ Non-interactive path, using the saved default profile and remembering the URL without a prompt:
108
+
109
+ ``` bash
110
+ cloak run --persist-cookies --consent --cookie-url https://x.com
111
+ ```
112
+
113
+ Non-interactive path, using an explicit profile:
114
+
115
+ ``` bash
116
+ cloak run --profile "Profile 7" --persist-cookies --consent --cookie-url https://x.com
117
+ ```
118
+
119
+ Run as a daemon and manage it later:
120
+
121
+ ``` bash
122
+ cloak daemon start --profile "Profile 7" --persist-cookies --consent --cookie-url https://x.com
123
+ cloak daemon status
124
+ cloak daemon logs
125
+ cloak daemon stop
126
+ cloak daemon restart
127
+ ```
128
+
129
+ See where `cloak` keeps its state, then destroy it if you really mean it:
130
+
131
+ ``` bash
132
+ cloak storage show
133
+ cloak storage destroy
134
+ ```
135
+
136
+ # runtime and storage
137
+
138
+ `cloak` launches headless by default. Pass `--window` when you want a visible browser window.
139
+
140
+ 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.
141
+
142
+ 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.
143
+
144
+ \(1\) What persists:
145
+
146
+ - `~/.cache/cloak/opencli-extension.zip`
147
+ - `~/.config/cloak/state.sqlite` with the default profile, remembered cookie URLs, and daemon state
148
+ - `~/.cache/cloak/daemon.log` when you use `cloak daemon start`
149
+
150
+ Use `cloak storage show` to print those paths, and `cloak storage destroy` to remove the whole config tree after a confirmation prompt.
151
+
152
+ \(2\) What stays ephemeral:
153
+
154
+ - the extracted extension directory in the OS temp directory
155
+ - the Patchright user data directory in the OS temp directory
156
+ - the injected cookie set itself
157
+
158
+ # build from source
159
+
160
+ If you want to work on `cloak` itself, use the repository directly:
161
+
162
+ ``` bash
163
+ git clone https://github.com/lmist/cloak.git
164
+ cd cloak
165
+ npm install
166
+ npm run build
167
+ node dist/main.js --help
168
+ ```
169
+
170
+ If you want a global `cloak` command built from that checkout:
171
+
172
+ ``` bash
173
+ npm install -g .
174
+ cloak --help
175
+ ```
176
+
177
+ # one sharp edge
178
+
179
+ 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.
180
+
181
+ 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.
package/README.org ADDED
@@ -0,0 +1,187 @@
1
+ #+title: cloak
2
+ #+property: header-args:sh :results output verbatim :exports code
3
+
4
+ [[docs/assets/cloak-logo-readme-centered.png]]
5
+
6
+ #+TOC: headlines 2
7
+
8
+ * what it is
9
+
10
+ =cloak= is the browser sidecar for [[https://github.com/jackwener/opencli][OpenCLI]]. It launches a fresh [[https://github.com/Kaliiiiiiiiii-Vinyzu/patchright/][Patchright]] browser with the pinned [[https://github.com/jackwener/opencli/releases/download/v1.6.8/opencli-extension.zip][OpenCLI extension archive]] loaded every time it starts.
11
+
12
+ * motivation
13
+
14
+ 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.
15
+
16
+ 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.
17
+
18
+ =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.
19
+
20
+ 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.
21
+
22
+ This solves a specific product gap:
23
+
24
+ - OpenCLI assumes extension-in-profile session reuse.
25
+ - A dedicated secondary browser profile avoids touching the main profile, but it still requires installing the extension and maintaining separate logged-in state.
26
+ - =cloak= keeps the extension out of the daily browser profile while making cookie reuse explicit, scoped, and disposable.
27
+
28
+ In practical terms, that gives =cloak= three concrete reasons to exist:
29
+
30
+ - isolated runtime: the automation browser is fresh and disposable instead of being the user's normal browser profile
31
+ - 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
32
+ - cleaner trust boundary: the extension does not need to live in the user's day-to-day browser profile
33
+
34
+ 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.
35
+
36
+ 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=.
37
+
38
+ * install
39
+
40
+ Install =cloak= globally and verify the CLI:
41
+
42
+ #+name: install-from-npm
43
+ #+begin_src sh
44
+ npm install -g cloak22
45
+ cloak --help
46
+ #+end_src
47
+
48
+ The published package name is =cloak22=. The installed CLI command remains =cloak=.
49
+
50
+ During =npm install=, =cloak= tries to:
51
+
52
+ - warm the pinned OpenCLI extension cache
53
+ - install the Patchright Chromium browser
54
+
55
+ If the browser download step gets skipped or fails in your environment, retry it manually:
56
+
57
+ #+begin_src sh
58
+ npx patchright install chromium
59
+ #+end_src
60
+
61
+ If you use OpenCLI with it, install that separately:
62
+
63
+ #+name: install-opencli-optional
64
+ #+begin_src sh
65
+ npm install -g @jackwener/opencli
66
+ npx skills add jackwener/opencli
67
+ #+end_src
68
+
69
+ * usage
70
+
71
+ If you installed from a checkout but did not run =npm install -g .=, use =node dist/main.js= everywhere below in place of =cloak=.
72
+
73
+ Check the installed version:
74
+
75
+ #+begin_src sh
76
+ cloak version
77
+ #+end_src
78
+
79
+ Pick a default Chrome profile once:
80
+
81
+ #+begin_src sh
82
+ cloak profile list
83
+ cloak profile use "Profile 7"
84
+ cloak profile show
85
+ #+end_src
86
+
87
+ See the cookie-bearing URLs for the default profile and optionally remember a subset for future runs:
88
+
89
+ #+begin_src sh
90
+ cloak sites list
91
+ cloak sites list --no-pager --limit 25
92
+ #+end_src
93
+
94
+ Run headless with the remembered profile and remembered URLs:
95
+
96
+ #+begin_src sh
97
+ cloak run
98
+ #+end_src
99
+
100
+ Run visibly instead of headless:
101
+
102
+ #+begin_src sh
103
+ cloak run --window
104
+ #+end_src
105
+
106
+ Run from a cookie export file without selecting a Chrome profile:
107
+
108
+ #+begin_src sh
109
+ cloak run --cookie-file ./cookies.json
110
+ #+end_src
111
+
112
+ Non-interactive path, using the saved default profile and remembering the URL without a prompt:
113
+
114
+ #+begin_src sh
115
+ cloak run --persist-cookies --consent --cookie-url https://x.com
116
+ #+end_src
117
+
118
+ Non-interactive path, using an explicit profile:
119
+
120
+ #+begin_src sh
121
+ cloak run --profile "Profile 7" --persist-cookies --consent --cookie-url https://x.com
122
+ #+end_src
123
+
124
+ Run as a daemon and manage it later:
125
+
126
+ #+begin_src sh
127
+ cloak daemon start --profile "Profile 7" --persist-cookies --consent --cookie-url https://x.com
128
+ cloak daemon status
129
+ cloak daemon logs
130
+ cloak daemon stop
131
+ cloak daemon restart
132
+ #+end_src
133
+
134
+ See where =cloak= keeps its state, then destroy it if you really mean it:
135
+
136
+ #+begin_src sh
137
+ cloak storage show
138
+ cloak storage destroy
139
+ #+end_src
140
+
141
+ * runtime and storage
142
+
143
+ =cloak= launches headless by default. Pass =--window= when you want a visible browser window.
144
+
145
+ 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.
146
+
147
+ 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.
148
+
149
+ (1) What persists:
150
+
151
+ - =~/.cache/cloak/opencli-extension.zip=
152
+ - =~/.config/cloak/state.sqlite= with the default profile, remembered cookie URLs, and daemon state
153
+ - =~/.cache/cloak/daemon.log= when you use =cloak daemon start=
154
+
155
+ Use =cloak storage show= to print those paths, and =cloak storage destroy= to remove the whole config tree after a confirmation prompt.
156
+
157
+ (2) What stays ephemeral:
158
+
159
+ - the extracted extension directory in the OS temp directory
160
+ - the Patchright user data directory in the OS temp directory
161
+ - the injected cookie set itself
162
+
163
+ * build from source
164
+ If you want to work on =cloak= itself, use the repository directly:
165
+
166
+ #+name: install-from-source
167
+ #+begin_src sh
168
+ git clone https://github.com/lmist/cloak.git
169
+ cd cloak
170
+ npm install
171
+ npm run build
172
+ node dist/main.js --help
173
+ #+end_src
174
+
175
+ If you want a global =cloak= command built from that checkout:
176
+
177
+ #+name: install-from-source-globally
178
+ #+begin_src sh
179
+ npm install -g .
180
+ cloak --help
181
+ #+end_src
182
+
183
+ * one sharp edge
184
+
185
+ 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.
186
+
187
+ 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.
package/bin/cloak.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+ const { spawnSync } = require("node:child_process");
6
+
7
+ const packageRoot = path.resolve(__dirname, "..");
8
+ const distEntrypoint = path.join(packageRoot, "dist", "main.js");
9
+ const sourceEntrypoint = path.join(packageRoot, "src", "main.ts");
10
+
11
+ const childArgs = fs.existsSync(distEntrypoint)
12
+ ? [distEntrypoint, ...process.argv.slice(2)]
13
+ : ["--import", "tsx", sourceEntrypoint, ...process.argv.slice(2)];
14
+
15
+ const result = spawnSync(process.execPath, childArgs, {
16
+ stdio: "inherit",
17
+ cwd: packageRoot,
18
+ });
19
+
20
+ if (result.error) {
21
+ throw result.error;
22
+ }
23
+
24
+ process.exit(result.status ?? 0);
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.defaultAppRootDir = defaultAppRootDir;
7
+ exports.defaultConfigRootDir = defaultConfigRootDir;
8
+ exports.resolveAppPaths = resolveAppPaths;
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ function defaultAppRootDir(dependencies = {}) {
12
+ const homedir = dependencies.homedir ?? node_os_1.default.homedir;
13
+ return node_path_1.default.join(homedir(), ".cache", "cloak");
14
+ }
15
+ function defaultConfigRootDir(dependencies = {}) {
16
+ const homedir = dependencies.homedir ?? node_os_1.default.homedir;
17
+ return node_path_1.default.join(homedir(), ".config", "cloak");
18
+ }
19
+ function resolveAppPaths(rootDir = defaultAppRootDir(), configDir = defaultConfigRootDir()) {
20
+ return {
21
+ extensionsDir: rootDir,
22
+ configDir,
23
+ stateDbPath: node_path_1.default.join(configDir, "state.sqlite"),
24
+ daemonLogPath: node_path_1.default.join(rootDir, "daemon.log"),
25
+ };
26
+ }