stelz 0.2.0 → 0.2.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 +12 -6
- package/THIRD_PARTY_NOTICES.md +3 -1
- package/dist/cli.js +4295 -1291
- package/dist/plugin.js +92 -17
- package/dist/supervisor.js +137 -34
- package/dist/ui/assets/index-7xWId3LL.js +11 -0
- package/dist/ui/assets/index-By17r8AD.css +1 -0
- package/dist/ui/index.html +4 -3
- package/docs/README.md +24 -7
- package/docs/architecture.md +56 -5
- package/docs/bootstrap.md +195 -0
- package/docs/clients.md +5 -1
- package/docs/distribution.md +26 -17
- package/docs/onboarding-acceptance.md +79 -0
- package/docs/profile-transfer.md +89 -0
- package/docs/tests.md +76 -27
- package/docs/ui.md +31 -15
- package/examples/onboarding-fixture.html +22 -0
- package/package.json +62 -8
- package/skills/stelz-browser/SKILL.md +7 -3
- package/skills/stelz-browser/references/bootstrap.md +16 -0
- package/dist/ui/chunk-6y88c98t.css +0 -1
- package/dist/ui/chunk-jt6ajg4c.js +0 -11
- /package/dist/ui/{font-328d50b6ece9ca25.woff → assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff} +0 -0
- /package/dist/ui/{font-08949f728dc52d52.woff2 → assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2} +0 -0
- /package/dist/ui/{font-3b646991d30055a9.woff2 → assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2} +0 -0
- /package/dist/ui/{font-828907bfd14855c8.woff → assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff} +0 -0
- /package/dist/ui/{font-0717336fb31fcdcd.woff2 → assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2} +0 -0
- /package/dist/ui/{font-8d2c7b2eca91869d.woff → assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff} +0 -0
- /package/dist/ui/{font-7861a349af1e925a.woff → assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff} +0 -0
- /package/dist/ui/{font-8960851d691c054e.woff2 → assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2} +0 -0
- /package/dist/ui/{theme-j8bgvgsv.js → theme-fqsa3r76.js} +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Onboarding acceptance
|
|
2
|
+
|
|
3
|
+
## Reproduce the agent check
|
|
4
|
+
|
|
5
|
+
Use local macOS ARM64 with a signed-in coding agent. Keep its existing approval protections.
|
|
6
|
+
Build and pack a release candidate. Give a fresh agent only the bootstrap document, candidate archive, a new writable test directory, and this request:
|
|
7
|
+
|
|
8
|
+
> Follow the bootstrap document. Install this archive into the supplied test prefix, use the supplied temporary STELZ_HOME, and create or reuse profile work. Install the canonical skill in this test project's supported location. Preserve global client configuration. Configure a project-scoped MCP connection if supported, otherwise write the exact connection arguments for a new session. Verify through your actual browser tools. Report Installed, Browser ready, Client configured, and Verified separately. Do not claim unavailable tools work. Leave the browser running after release.
|
|
9
|
+
|
|
10
|
+
Record the agent's actions, errors, and intervention requests. A model must perform the browser interaction through its registered MCP tools.
|
|
11
|
+
An SDK script can inspect the resulting state but cannot replace that evidence.
|
|
12
|
+
If tools require a new session, start that session with the saved connection and the same profile. Resume only the verification step.
|
|
13
|
+
Repeat the original onboarding prompt afterward. Require the same profile ID, port, secret references, browser lifetime, and saved local-page marker.
|
|
14
|
+
|
|
15
|
+
After the agent demonstrates release and reuse, the test operator can explicitly stop the test profile and fixture server.
|
|
16
|
+
Do not stop or remove real service profiles. Keep failed test state for inspection.
|
|
17
|
+
|
|
18
|
+
## Automated coverage
|
|
19
|
+
|
|
20
|
+
`tests/integration/profile-cli.test.ts` covers direct and proxy creation, environment input, repeated creation, concurrent creation, legacy catalogs, interrupted transactions, conflicts, redacted results, missing initialization, and unsafe service files.
|
|
21
|
+
Existing catalog, lifecycle, and MCP suites cover port allocation, rollback, exclusive control, and browser survival after disconnect.
|
|
22
|
+
The release verifier checks the installed CLI and bundled onboarding resources outside the source checkout.
|
|
23
|
+
|
|
24
|
+
## Run record: 2026-11-05
|
|
25
|
+
|
|
26
|
+
The assisted Codex acceptance check passed on local macOS ARM64.
|
|
27
|
+
The host supplied Bun 1.4.4, Node.js 24.14.0, npm 11.16.0, and a compatible Camoufox executable.
|
|
28
|
+
The target client was Codex CLI 0.142.4.
|
|
29
|
+
The agent read the local bootstrap document and installed the supplied Stelz 0.2.0 archive into a new temporary npm prefix.
|
|
30
|
+
The archive SHA-256 was `17cdaa57f05f47060a33afe9b8502537fd65de06f30a3256bf8d68b7c339dd94`.
|
|
31
|
+
|
|
32
|
+
| State | Observed result |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| Installed | The fresh agent installed the archive with lifecycle scripts enabled, initialized an empty service directory, and prepared the runtime. |
|
|
35
|
+
| Browser ready | The agent created native profile `work` on port 9377. Start and doctor confirmed the running service and owned processes. |
|
|
36
|
+
| Client configured | The agent installed a symlink to the canonical skill and a project MCP entry. It preserved global client configuration. |
|
|
37
|
+
| Verified | A fresh Codex session acquired control, opened the local fixture, read snapshots, clicked the observed reference, and verified the result. |
|
|
38
|
+
|
|
39
|
+
The first session reported **Verified: pending** because it lacked the newly registered tools.
|
|
40
|
+
The next session used the actual `stelz-work` MCP tools. It did not use an SDK probe for browser interaction.
|
|
41
|
+
After release, status reported `ready` with no controller. Reacquisition returned the same page and result.
|
|
42
|
+
|
|
43
|
+
The agent then repeated initialization, profile creation, and startup.
|
|
44
|
+
Creation returned `created: false`. Profile ID, port, native storage, and catalog and secret-file hashes remained unchanged.
|
|
45
|
+
The instance remained `2211f6d7-15e5-4225-8f1d-01956bc44233`.
|
|
46
|
+
The fixture tab remained `086c8d6a-e9f9-4f10-9bbc-13a4d90171ef`.
|
|
47
|
+
Its persistent count increased from 1 to 2 after a second observed click.
|
|
48
|
+
The final release again left the same browser ready with no controller.
|
|
49
|
+
After recording that evidence, the test operator stopped only the temporary `work` profile.
|
|
50
|
+
The fixture server stopped separately. The test retained native profile data for inspection.
|
|
51
|
+
|
|
52
|
+
## Required interventions
|
|
53
|
+
|
|
54
|
+
- The installed Codex CLI initially rejected the user's model catalog before the agent could start.
|
|
55
|
+
The test operator supplied a temporary compatible catalog through a session-only flag.
|
|
56
|
+
The copy supplied missing model capability fields and disabled an incompatible optional response transport.
|
|
57
|
+
The global catalog, authentication, sandbox, and approval settings stayed unchanged.
|
|
58
|
+
This assistance prevents a claim of fully unattended onboarding on this host.
|
|
59
|
+
- The first sandboxed desktop browser launch aborted. The agent inspected ownership, stopped only the failed test lifetime, and requested normal launch permission.
|
|
60
|
+
The approved launch succeeded. Protected project skill and MCP directories also required normal permission escalation.
|
|
61
|
+
Stopping the temporary fixture also required scoped permission.
|
|
62
|
+
- The operator started a fresh Codex session after registration. The first session supplied exact connection arguments and a checkpoint.
|
|
63
|
+
- No website authentication or new credentials were necessary for the local fixture.
|
|
64
|
+
|
|
65
|
+
## Scope and limitations
|
|
66
|
+
|
|
67
|
+
The test used a fresh package prefix, service directory, and project configuration. It reused host dependencies and the browser executable.
|
|
68
|
+
It does not establish installation on a fresh operating system or exercise the missing-dependency download branches.
|
|
69
|
+
The public bootstrap URL and npm release path were not the input to this development run.
|
|
70
|
+
Publish the document and release before testing that public path.
|
|
71
|
+
|
|
72
|
+
Claude Code and Hermes setup paths follow their official documentation.
|
|
73
|
+
The installed Hermes skill loader also supports directory symlinks.
|
|
74
|
+
Neither client completed this onboarding acceptance run. Claude Code was unavailable.
|
|
75
|
+
Proxy creation, conflicts, legacy references, and interrupted transactions passed automated CLI checks. This agent check used direct networking.
|
|
76
|
+
|
|
77
|
+
The implementation checks passed: 484 Bun tests, 97 Node regression tests, typecheck, build, and isolated release verification.
|
|
78
|
+
Ten CLI tests include concurrent reuse, interrupted creation, and conflicting legacy paths.
|
|
79
|
+
Local evidence is retained under `.state/onboarding-acceptance/` and the temporary acceptance project.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Import and export profiles
|
|
2
|
+
|
|
3
|
+
Use a `.stelz-profiles.zip` archive to move one or more profiles between matching installations.
|
|
4
|
+
The archive includes saved browser data, device settings, typing preferences, and available proxy credentials.
|
|
5
|
+
It is not encrypted. Keep it private because saved browser data can contain active login sessions.
|
|
6
|
+
Initialize the destination with `stelz init`. Both installations need the matching Camoufox executable.
|
|
7
|
+
|
|
8
|
+
## Use the UI
|
|
9
|
+
|
|
10
|
+
Stop the profiles cleanly before export. Export never stops a browser automatically.
|
|
11
|
+
Open **Profiles**, select **Export**, and select the profiles to include.
|
|
12
|
+
Use **Select all stopped** to select every eligible profile.
|
|
13
|
+
Download the archive when preparation completes, then close the dialog.
|
|
14
|
+
A stopped profile also has an export action in its details.
|
|
15
|
+
|
|
16
|
+
Select **Import** and choose the ZIP archive.
|
|
17
|
+
Review the profiles and their proposed IDs and display names. Select the profiles to import.
|
|
18
|
+
Select **Import N**, where `N` is the selected count, to save the batch.
|
|
19
|
+
The new profiles remain stopped until you start them explicitly.
|
|
20
|
+
|
|
21
|
+
If an ID already exists, import proposes `ID-copy`, then `ID-copy-2`, and so on.
|
|
22
|
+
Existing profiles and their data stay unchanged.
|
|
23
|
+
A profile whose proxy credentials were unavailable at export remains blocked until you configure its proxy.
|
|
24
|
+
It never changes to a direct connection automatically.
|
|
25
|
+
|
|
26
|
+
The dialog reports transfer progress. Select **Cancel** to remove temporary files before you import profiles.
|
|
27
|
+
During import, wait for the result. Turning off the UI is unavailable during an active transfer.
|
|
28
|
+
Reloading the page restores an active transfer in the same UI session.
|
|
29
|
+
If an upload needs the file again after reload, choose the ZIP again or cancel the transfer.
|
|
30
|
+
A new UI server starts a new transfer session.
|
|
31
|
+
|
|
32
|
+
## Use the CLI
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
stelz profile export work personal --output ./profiles.stelz-profiles.zip
|
|
36
|
+
stelz profile export --all --output ./all-profiles.stelz-profiles.zip
|
|
37
|
+
stelz profile import ./profiles.stelz-profiles.zip
|
|
38
|
+
stelz profile import ./profiles.stelz-profiles.zip --profile work --rename work=work-laptop
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Export refuses an existing output file. Use another filename.
|
|
42
|
+
`--all` includes every configured profile. Every selected profile must be cleanly stopped.
|
|
43
|
+
Repeat `--profile SOURCE_ID` to import a subset. Omit it to import the complete archive.
|
|
44
|
+
Repeat `--rename SOURCE_ID=NEW_ID` to select explicit unused destination IDs.
|
|
45
|
+
Add `--json` for structured results. Results contain profile mappings and do not include credentials.
|
|
46
|
+
The destination service assigns new loopback ports and private secret references.
|
|
47
|
+
Export saves the effective typing mode, including a mode inherited from the source service.
|
|
48
|
+
Import saves that mode as a profile preference.
|
|
49
|
+
|
|
50
|
+
## Compatibility and saved data
|
|
51
|
+
|
|
52
|
+
Import requires the same operating system, CPU architecture, and exact Camoufox executable SHA-256.
|
|
53
|
+
Export also checks saved fingerprints against the local executable.
|
|
54
|
+
Stelz does not migrate browser versions or storage modes during import.
|
|
55
|
+
Both native profiles and legacy checkpoint profiles keep their storage mode.
|
|
56
|
+
Import maps checkpoint storage to the destination profile ID.
|
|
57
|
+
|
|
58
|
+
The ZIP64-compatible archive contains a versioned `manifest.json` and SHA-256 hashes for its files.
|
|
59
|
+
Native browser data remains intact, including SQLite sidecar files.
|
|
60
|
+
The archive includes saved cookie inputs and reusable uploads.
|
|
61
|
+
Export omits service files, including process records, `access-key`, logs, and temporary files.
|
|
62
|
+
It also omits native browser lock files at the root of `browser-data/`.
|
|
63
|
+
The archive contains neither the browser executable nor global service or client configuration.
|
|
64
|
+
|
|
65
|
+
Import checks the archive before it changes the profile catalog.
|
|
66
|
+
It rejects unsafe paths, links, unsupported entry types, duplicate entries, and failed file hashes.
|
|
67
|
+
Import installs the data and secrets, then publishes the selected batch in one catalog update.
|
|
68
|
+
An interrupted commit leaves a private journal. The next configuration operation or explicit start completes recovery.
|
|
69
|
+
Read-only status does not change the journal. Conflicting manual edits require inspection.
|
|
70
|
+
The private journal is `STELZ_HOME/.profile-import-transaction.json`.
|
|
71
|
+
Run `stelz doctor ID` to inspect a pending import.
|
|
72
|
+
Keep its journal and staging directories while recovery is pending.
|
|
73
|
+
|
|
74
|
+
## Transfer limits
|
|
75
|
+
|
|
76
|
+
Archives and expanded profile data each have a default limit of 10 GiB.
|
|
77
|
+
The default entry limit is 100,000. The manifest limit is 64 MiB.
|
|
78
|
+
Set these environment variables before starting the UI or CLI to change the transfer limits:
|
|
79
|
+
|
|
80
|
+
| Variable | Unit |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `STELZ_TRANSFER_ARCHIVE_BYTES` | Compressed archive bytes |
|
|
83
|
+
| `STELZ_TRANSFER_EXPANDED_BYTES` | Expanded file bytes |
|
|
84
|
+
| `STELZ_TRANSFER_ENTRIES` | ZIP entries |
|
|
85
|
+
| `STELZ_TRANSFER_MANIFEST_BYTES` | Manifest bytes |
|
|
86
|
+
|
|
87
|
+
Use positive integers. These limits apply to each transfer, not to the saved-profile count.
|
|
88
|
+
Allow free disk space for the archive, the extracted data, and the staged import or export snapshot.
|
|
89
|
+
Inactive UI transfer files expire after 30 minutes. Finish or cancel a transfer before turning off the UI.
|
package/docs/tests.md
CHANGED
|
@@ -6,19 +6,25 @@ Use the runtime requirements in [Use the service](README.md).
|
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
bun install --frozen-lockfile --ignore-scripts
|
|
9
|
-
bun run
|
|
9
|
+
bun run check
|
|
10
10
|
bun run pack
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Build regenerates `
|
|
13
|
+
Build regenerates `dist/` from source.
|
|
14
|
+
Bun builds the CLI, supervisor, browser plugin, and early theme script. Vite builds the UI and emits local font files.
|
|
15
|
+
The theme script runs before the first page frame. The build preserves the bundled UI licenses.
|
|
14
16
|
The archive contains the CLI, supervisor, browser plugin, built local UI, documentation, client examples, and third-party notices.
|
|
15
17
|
The diagnostic client runs from source. The archive excludes Stelz source files, tests, and browser state.
|
|
16
18
|
It includes the prepared Camofox and camoufox-js dependencies. See [Distribution](distribution.md).
|
|
17
19
|
|
|
18
20
|
## Checks
|
|
19
21
|
|
|
22
|
+
See [Onboarding acceptance](onboarding-acceptance.md) for the real-agent installation, restart, and browser-control check.
|
|
23
|
+
`tests/integration/profile-cli.test.ts` checks profile creation, safe reuse, conflicts, and interrupted transactions through the CLI.
|
|
24
|
+
|
|
20
25
|
| Command | Coverage |
|
|
21
26
|
| --- | --- |
|
|
27
|
+
| `bun run check` | Build, TypeScript checks, and all browser-free tests. No release archive. |
|
|
22
28
|
| `bun run typecheck` | TypeScript checks. |
|
|
23
29
|
| `bun run test:ui` | UI sessions, lifecycle dispatch, profile creation and deletion, interrupted saves, safe network edits, and redaction. |
|
|
24
30
|
| `bun run test:ui:browser` | Built UI in Chrome, local sessions, offline assets, forms, and responsive layouts. |
|
|
@@ -26,20 +32,25 @@ It includes the prepared Camofox and camoufox-js dependencies. See [Distribution
|
|
|
26
32
|
| `bun run test:integration` | Two checkpoint profiles, exclusive control, handoff, disconnect, client crash, pause, and restart. |
|
|
27
33
|
| `bun run test:concurrency` | Three temporary native profiles, simultaneous starts, isolated storage, duplicate starts, and controller handoff on a local fixture. |
|
|
28
34
|
| `bun run test:native` | Two native profiles, storage isolation, and repeated fingerprint samples across three browser lifetimes. |
|
|
35
|
+
| `bun run test:transfer` | Native ZIP export/import, batch copies, saved sessions, fingerprint bytes, fresh access keys, and copied-profile window controls. |
|
|
29
36
|
| `bun run test:window-close` | Close one isolated test window when prompted. Check clean shutdown, Stopped UI state, and explicit restart. |
|
|
30
37
|
| `bun run test:windows` | Native profile labels, window focus, unchanged website titles, and controller preservation in two isolated Camoufox profiles. |
|
|
31
38
|
| `bun run test:proxy` | Two distinct proxy exits, three browser lifetimes, expected IP pins, and isolated route failures during cached verification. |
|
|
32
39
|
| `bun run test:manual` | Human interaction while paused, followed by MCP resume in the same browser and tab. |
|
|
33
|
-
| `bun run test:public
|
|
34
|
-
| `bun run
|
|
35
|
-
| `bun run
|
|
40
|
+
| `bun run test:public` | Four public fingerprint checks in a disposable native profile, with screenshots and verdict reports. |
|
|
41
|
+
| `bun run pack` | Build once and save one release archive with its hash and source metadata in `release-artifacts/`. |
|
|
42
|
+
| `bun run verify:release` | Check the saved archive, installed dependencies, CLI, HTTP UI, and staged setup with a fake executable. No browser or rebuild. |
|
|
43
|
+
| `bun run verify:release --archive FILE --native` | Ordinary isolated npm installation, SQLite queries, and Impit construction from the installed package and staged runtime. No browser. |
|
|
44
|
+
| `bun run test:package` | Install the saved archive in an isolated npm prefix. Run checkpoint and native browser acceptance. |
|
|
36
45
|
| `bun run test:package --archive FILE --native --proxy --manual` | Full supported-platform acceptance against one unchanged release candidate, including a real human action. |
|
|
46
|
+
| `bun run test:package --archive FILE --native --proxy --waive-manual` | The owner-approved `0.2.1` release exception. All automated gates remain required. Human takeover remains untested in the record. |
|
|
37
47
|
|
|
38
48
|
The earlier browser acceptance run passed on 2026-11-02 with macOS 26.5.2 on Apple Silicon.
|
|
39
49
|
That run used Bun 1.4.4, Node.js 24.14.0, TypeScript 5.9.3, and Camoufox 152.0.4 beta.30.
|
|
40
50
|
Camofox remains pinned to npm version 1.18.1.
|
|
41
51
|
|
|
42
|
-
|
|
52
|
+
Tests in `tests/unit` and `tests/integration` run with Bun through directory discovery.
|
|
53
|
+
Tests in `tests/regression` run directly with Node. They do not require a browser.
|
|
43
54
|
The plugin tests use the actual hooks with simulated browser and network interfaces.
|
|
44
55
|
They cover stalled actions, failed IP checks, explicit recheck, action serialization, cache expiry, and independent provider fallback.
|
|
45
56
|
One hundred queued actions require one IP check with the default cache, compared with 101 checks in strict mode.
|
|
@@ -57,23 +68,58 @@ That check uses the actual UI API and isolated service files with simulated life
|
|
|
57
68
|
It does not start Camoufox profiles.
|
|
58
69
|
It uses installed Chrome on macOS. Set `STELZ_UI_CHROME` to select another Chrome or Chromium executable.
|
|
59
70
|
Screenshots and its report are in `.state/ui-browser/`.
|
|
60
|
-
The UI check also creates profiles with and without a proxy
|
|
71
|
+
The UI check also creates profiles with and without a proxy and checks deletion archives.
|
|
72
|
+
|
|
73
|
+
## Profile transfer acceptance
|
|
74
|
+
|
|
75
|
+
The default test command includes ZIP format, transfer API, CLI, and import transaction checks.
|
|
76
|
+
They cover ZIP64, unsafe paths and links, checksum failures, size limits, cancellation, credential redaction, conflicts, and crash recovery.
|
|
77
|
+
|
|
78
|
+
Build the service, then run the native transfer check:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
bun run build
|
|
82
|
+
bun run test:transfer
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This check requires desktop access for Camoufox.
|
|
86
|
+
It creates a fresh `.state/transfer-native-*` service directory and uses synthetic data on a local fixture.
|
|
87
|
+
It verifies cookies, localStorage, IndexedDB, fingerprint bytes, a fresh access key, and window controls after import.
|
|
88
|
+
Its report is `.state/profile-transfer/report.json`. Cleanup stops only its test profiles.
|
|
89
|
+
Native transfer acceptance passed on macOS arm64 on 2026-11-05.
|
|
90
|
+
|
|
91
|
+
To check ZIP commands in an installed release without starting browsers, run this from the source checkout:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
STELZ_TEST_CLI=/absolute/path/to/installed/stelz \
|
|
95
|
+
bun test tests/integration/profile-transfer-cli.test.ts
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
These tests use disposable service directories and a synthetic executable for compatibility hashes.
|
|
99
|
+
They check batch copies, credentials, explicit destination IDs, output-file protection, mismatched engines, and unclean lifetimes.
|
|
100
|
+
See [Import and export profiles](profile-transfer.md) for the supported behavior.
|
|
61
101
|
|
|
62
102
|
## Continuous integration
|
|
63
103
|
|
|
64
|
-
GitHub Actions runs frozen installation
|
|
104
|
+
GitHub Actions runs frozen installation and `bun run check` on Linux and macOS.
|
|
105
|
+
Normal checks do not pack archives or start live browsers.
|
|
65
106
|
CI and release workflows use the root `package.json` `packageManager` pin (`bun@1.4.4`), Node.js 24, and read-only repository permissions.
|
|
66
|
-
Release preparation requires these checks on both platforms, then uploads one
|
|
107
|
+
Release preparation requires these checks on both platforms, then builds and uploads one candidate archive.
|
|
108
|
+
Linux and macOS download that same archive and check installation with scripts disabled and with ordinary native installation.
|
|
67
109
|
The workflows skip browser downloads. Browser, proxy, and human acceptance checks run locally.
|
|
68
110
|
|
|
69
111
|
## Test data
|
|
70
112
|
|
|
71
113
|
Browser checks use independent MCP SDK clients. Most checks use two profiles. `test:concurrency` uses three native profiles simultaneously.
|
|
114
|
+
Routine tests use temporary catalogs and mocked browser or service interfaces.
|
|
115
|
+
Lifecycle fixtures copy source into test packages and use mock plugin bytes. They do not require workspace build output.
|
|
116
|
+
Live browser checks create disposable profiles in separate service directories. They never select an operator's saved profile.
|
|
72
117
|
Checkpoint, native, and manual checks use explicit direct development mode. Proxy acceptance requires two supplied HTTP proxies.
|
|
73
118
|
The isolated acceptance checks stop their test browsers. The public-site check saves its artifacts, then stops its selected browser.
|
|
74
119
|
These checks require no model credentials.
|
|
75
120
|
|
|
76
|
-
- `test:integration`
|
|
121
|
+
- `test:integration` creates a fresh `.state/standalone-acceptance-*` directory.
|
|
122
|
+
`STELZ_TEST_HOME` can select only a directory created by `tests/helpers/test-home.ts`.
|
|
77
123
|
- `test:native` creates a fresh `.state/native-acceptance-*` directory.
|
|
78
124
|
- `test:windows` creates a fresh `.state/profile-windows-*` directory with native and checkpoint profiles.
|
|
79
125
|
- `test:package` uses temporary install and service directories. Its report is `.state/package-test/report.json`.
|
|
@@ -130,11 +176,11 @@ Window acceptance passed on 2026-11-03 with both storage modes.
|
|
|
130
176
|
|
|
131
177
|
## Public fingerprint checks
|
|
132
178
|
|
|
133
|
-
|
|
179
|
+
Build the service before this check:
|
|
134
180
|
|
|
135
181
|
```sh
|
|
136
|
-
bun run
|
|
137
|
-
bun run test:public
|
|
182
|
+
bun run build
|
|
183
|
+
bun run test:public
|
|
138
184
|
```
|
|
139
185
|
|
|
140
186
|
The suite uses stelz MCP tools to visit these sites in order:
|
|
@@ -155,12 +201,11 @@ The suite does not request location permission or trigger Rebrowser's scripted p
|
|
|
155
201
|
Rebrowser reports each native probe separately. Skipped and untriggered probes do not count as passed checks.
|
|
156
202
|
Its overall result describes the applicable checks and states the remaining coverage limits.
|
|
157
203
|
|
|
158
|
-
The suite
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
The suite
|
|
163
|
-
An active controller prevents acquisition. Release that controller before you retry.
|
|
204
|
+
The suite creates its own native profile and starts one browser. It creates four tabs sequentially.
|
|
205
|
+
After saving its artifacts, it stops that disposable profile. Cleanup also runs after failed or interrupted checks.
|
|
206
|
+
The suite rejects `--profile` and ignores the operator's `STELZ_HOME`.
|
|
207
|
+
To test a proxy route, set `PROXY_TEST_ENV` to a private file with `PROXY_TEST_URL` and optional `PROXY_TEST_EXPECTED_IP`.
|
|
208
|
+
The suite copies these inputs into its temporary service directory and removes that credential copy after cleanup.
|
|
164
209
|
|
|
165
210
|
The suite checks each page every two seconds for up to 120 seconds, excluding human authentication time.
|
|
166
211
|
It waits for each MCP operation to finish. A service deadline blocks further browser actions and requires an explicit stop and start.
|
|
@@ -168,7 +213,7 @@ Individual site errors do not prevent later checks when the profile remains usab
|
|
|
168
213
|
|
|
169
214
|
Authentication pauses the profile. Complete authentication in the same Camoufox window, then type `done` in the terminal.
|
|
170
215
|
Without an interactive terminal, the suite records an incomplete result and stops the browser during cleanup.
|
|
171
|
-
Cancelling authentication also ends the run and stops the browser.
|
|
216
|
+
Cancelling authentication also ends the run and stops the browser. The next run creates another disposable profile.
|
|
172
217
|
|
|
173
218
|
Artifacts are in `.state/public-sites/<run>/`. Each run creates `report.json` and `report.md`.
|
|
174
219
|
Visited sites also have a PNG screenshot and a snapshot JSON file when capture succeeds.
|
|
@@ -202,10 +247,7 @@ The check explicitly stops its browser. Results are in `.state/typing-acceptance
|
|
|
202
247
|
The default test command checks typing logic and runtime setup without starting a browser.
|
|
203
248
|
It executes the upstream type route and tab lock with virtual timers to check long input, terminal timeouts, and action serialization.
|
|
204
249
|
|
|
205
|
-
|
|
206
|
-
Its service must already contain the current typing runtime.
|
|
207
|
-
This mode starts and stops the selected profile once. It tests per-call overrides and skips profile default changes.
|
|
208
|
-
The profile catalog and secrets file remain unchanged.
|
|
250
|
+
The check rejects `--profile`. Every run creates a disposable profile.
|
|
209
251
|
|
|
210
252
|
## Diagnostics
|
|
211
253
|
|
|
@@ -251,14 +293,21 @@ Claude Code was not installed, so that client remains untested.
|
|
|
251
293
|
Browser executable changes require an explicit migration.
|
|
252
294
|
No test establishes that websites cannot detect automation.
|
|
253
295
|
|
|
296
|
+
Broader validation on 2026-11-05 found a 30-second `camofox_scroll` timeout with one set of saved fingerprints.
|
|
297
|
+
The same fingerprints reproduced the timeout on the pre-transfer baseline.
|
|
298
|
+
The current version passed with the baseline fingerprints. Successful ZIP transfer checks do not establish complete browser acceptance.
|
|
299
|
+
|
|
254
300
|
## Source layout
|
|
255
301
|
|
|
256
|
-
- `tests/unit/`: offline logic
|
|
302
|
+
- `tests/unit/`: offline logic, archive format, UI API, and verdict tests.
|
|
303
|
+
- `tests/regression/`: browser plugin and persistence tests that run directly with Node.
|
|
257
304
|
- `tests/integration/`: offline process, setup, catalog, and transaction checks.
|
|
258
305
|
- `tests/browser/`: explicit browser acceptance commands.
|
|
259
306
|
- `tests/qa/`: package, public-site, and human acceptance commands.
|
|
260
307
|
- `tests/helpers/`: shared fixtures and verdict readers.
|
|
261
308
|
- `scripts/call.ts`: development MCP diagnostic client.
|
|
262
309
|
|
|
263
|
-
UI source is in `
|
|
264
|
-
|
|
310
|
+
UI source is in `ui/src/`.
|
|
311
|
+
It shares profile and transfer types through `src/api/contracts.ts` and `src/api/transfer-contracts.ts`.
|
|
312
|
+
Server types use type-only imports. Server runtime modules stay on the backend.
|
|
313
|
+
These contracts are not a public package API.
|
package/docs/ui.md
CHANGED
|
@@ -11,7 +11,7 @@ The browsers and their open pages remain active.
|
|
|
11
11
|
Select **Turn off UI** in the header to end the UI session and stop its server.
|
|
12
12
|
The button also expires the session cookie. Running browsers stay open.
|
|
13
13
|
Finish active UI operations before using the button.
|
|
14
|
-
The UI asks before discarding unsaved
|
|
14
|
+
The UI asks before discarding unsaved edits.
|
|
15
15
|
Start `stelz ui` again to obtain a new session URL.
|
|
16
16
|
|
|
17
17
|
For a source checkout, first run `bun run build`.
|
|
@@ -45,7 +45,8 @@ Open **Profiles**. Select **New profile** and enter a name.
|
|
|
45
45
|
Supply a proxy URL if necessary. Leave it blank to use a direct connection.
|
|
46
46
|
Creation saves the profile without starting a browser.
|
|
47
47
|
The service assigns its port and uses a native persistent profile.
|
|
48
|
-
|
|
48
|
+
Overview contains its connection settings, typing preferences, and browser windows.
|
|
49
|
+
Device and Logs contain the technical information.
|
|
49
50
|
|
|
50
51
|
The profile table shows browser phase and controller ownership separately.
|
|
51
52
|
A ready browser can still have an active MCP controller.
|
|
@@ -68,16 +69,31 @@ A failed IP check keeps actions blocked.
|
|
|
68
69
|
An operation timeout can require an explicit stop and start.
|
|
69
70
|
See [Use the service](README.md) for process inspection and recovery procedures.
|
|
70
71
|
|
|
72
|
+
## Rename a profile
|
|
73
|
+
|
|
74
|
+
Select the pencil beside the profile name. Enter the new name and select **Save name**.
|
|
75
|
+
Escape or **Cancel rename** discards the edit.
|
|
76
|
+
The name updates in the profile list and heading. It can change while the browser is running.
|
|
77
|
+
The profile ID, saved data, proxy references, and MCP commands remain unchanged.
|
|
78
|
+
Browser window title prefixes continue to show the stable profile ID.
|
|
79
|
+
|
|
80
|
+
## Import and export
|
|
81
|
+
|
|
82
|
+
Use **Import** or **Export** in the Profiles heading to transfer one or more profiles as a ZIP archive.
|
|
83
|
+
Export requires cleanly stopped profiles. Import previews destination IDs and display names before saving the selected batch.
|
|
84
|
+
The archive includes saved logins and available proxy credentials. Keep it private.
|
|
85
|
+
See [Import and export profiles](profile-transfer.md) for compatibility requirements and CLI commands.
|
|
86
|
+
|
|
71
87
|
## Typing mode
|
|
72
88
|
|
|
73
89
|
Open a profile's Overview tab. Select **Default typing mode** under **Typing**:
|
|
74
90
|
|
|
75
|
-
- **Service default** inherits the service setting. Its label shows the inherited mode.
|
|
76
91
|
- **Automatic** uses random pauses for text with an estimated typing duration of at most 10 seconds. Longer text uses bulk entry.
|
|
77
92
|
- **Keyboard input** sends individual keystrokes without artificial delays.
|
|
78
93
|
- **Instant input** enters the complete text at once.
|
|
79
94
|
|
|
80
95
|
Changes save automatically and apply to future typing actions without a browser restart.
|
|
96
|
+
The selector shows the profile's effective mode. Profiles without an override use the service setting until you choose another mode.
|
|
81
97
|
Typing changes preserve unsaved network edits. Pending profile operations temporarily disable the selector.
|
|
82
98
|
The setting applies only to the selected profile. Each agent can override it with the `camofox_type` tool's `mode` argument.
|
|
83
99
|
|
|
@@ -123,7 +139,7 @@ The installed Camoufox app remains unchanged.
|
|
|
123
139
|
## Delete a profile
|
|
124
140
|
|
|
125
141
|
Stop the profile cleanly. Open its details and select **Delete profile**.
|
|
126
|
-
Type its exact
|
|
142
|
+
Type its exact profile ID, shown above the confirmation field, to confirm deletion.
|
|
127
143
|
The service removes the profile from the list and archives its complete directory under `STELZ_HOME/trash/`.
|
|
128
144
|
The archive includes its configuration in `profile.json` and its saved browser data in `profile/`.
|
|
129
145
|
The service retains secret values because other profiles can share them.
|
|
@@ -137,18 +153,18 @@ Read-only status does not change the transaction. Conflicting manual edits block
|
|
|
137
153
|
## Network configuration
|
|
138
154
|
|
|
139
155
|
Stop a profile before you edit its network configuration.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
A
|
|
146
|
-
An empty expected IP removes that
|
|
147
|
-
|
|
156
|
+
A proxy is optional. An empty **Proxy URL** uses a direct connection.
|
|
157
|
+
The **Connection** section in Overview shows the saved proxy address and optional expected exit IP.
|
|
158
|
+
Change the address to replace the proxy. Clear it and save to remove the proxy.
|
|
159
|
+
An unchanged address preserves its saved authentication, including when you change only the expected IP.
|
|
160
|
+
These fields are visible without opening a disclosure or selecting a connection mode.
|
|
161
|
+
A direct connection requires no IP lookup unless you set an expected exit IP.
|
|
162
|
+
An empty expected IP removes that requirement for a direct connection.
|
|
163
|
+
A proxy connection always requires a successful browser-side IP check.
|
|
148
164
|
|
|
149
165
|
The UI never shows saved proxy authentication.
|
|
150
|
-
Environment overrides
|
|
151
|
-
|
|
166
|
+
Environment overrides and shared secrets keep their values read-only.
|
|
167
|
+
**Remove proxy** disconnects this profile from a managed proxy. It preserves the secret for other profiles.
|
|
152
168
|
A conflicting save requires a fresh configuration before another save.
|
|
153
169
|
The backend checks process ownership and configuration again before it writes.
|
|
154
170
|
|
|
@@ -158,7 +174,7 @@ Read-only status does not complete the transaction.
|
|
|
158
174
|
Conflicting manual edits block recovery.
|
|
159
175
|
Run `stelz doctor ID` to inspect the failure.
|
|
160
176
|
|
|
161
|
-
|
|
177
|
+
Display names are editable. Profile IDs, storage mode, saved device properties, and browser versions remain read-only.
|
|
162
178
|
All profile state stays under `STELZ_HOME`.
|
|
163
179
|
The service has no saved-profile count limit or global active-browser limit.
|
|
164
180
|
Each profile has at most one browser instance. Other running profiles do not disable Start.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<meta charset="utf-8">
|
|
4
|
+
<title>Stelz onboarding check</title>
|
|
5
|
+
<h1>Stelz onboarding check</h1>
|
|
6
|
+
<p>This page contains only local test data.</p>
|
|
7
|
+
<button id="verify" type="button">Verify Stelz</button>
|
|
8
|
+
<p id="result" role="status">Not verified</p>
|
|
9
|
+
<p id="count"></p>
|
|
10
|
+
<script>
|
|
11
|
+
const count = document.getElementById("count");
|
|
12
|
+
const saved = Number(localStorage.getItem("stelz-onboarding-count") || 0);
|
|
13
|
+
let checks = Number.isSafeInteger(saved) && saved >= 0 ? saved : 0;
|
|
14
|
+
count.textContent = `Persistent check count: ${checks}`;
|
|
15
|
+
document.getElementById("verify").onclick = () => {
|
|
16
|
+
checks++;
|
|
17
|
+
localStorage.setItem("stelz-onboarding-count", String(checks));
|
|
18
|
+
document.getElementById("result").textContent = "Stelz verified";
|
|
19
|
+
count.textContent = `Persistent check count: ${checks}`;
|
|
20
|
+
};
|
|
21
|
+
</script>
|
|
22
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stelz",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Standalone persistent Camoufox profiles with exclusive MCP control",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/souljorje/stelz#readme",
|
|
7
7
|
"bugs": {
|
|
8
8
|
"url": "https://github.com/souljorje/stelz/issues"
|
|
9
9
|
},
|
|
10
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"browser",
|
|
12
|
+
"automation",
|
|
13
|
+
"camoufox",
|
|
14
|
+
"playwright",
|
|
15
|
+
"mcp",
|
|
16
|
+
"persistent-profiles"
|
|
17
|
+
],
|
|
11
18
|
"bin": {
|
|
12
19
|
"stelz": "dist/cli.js"
|
|
13
20
|
},
|
|
@@ -29,8 +36,7 @@
|
|
|
29
36
|
},
|
|
30
37
|
"repository": {
|
|
31
38
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/souljorje/stelz.git"
|
|
33
|
-
"directory": "packages/stelz"
|
|
39
|
+
"url": "https://github.com/souljorje/stelz.git"
|
|
34
40
|
},
|
|
35
41
|
"publishConfig": {
|
|
36
42
|
"access": "public",
|
|
@@ -39,8 +45,36 @@
|
|
|
39
45
|
"type": "module",
|
|
40
46
|
"packageManager": "bun@1.4.4",
|
|
41
47
|
"scripts": {
|
|
42
|
-
"build": "bun
|
|
43
|
-
"
|
|
48
|
+
"build": "bun scripts/build.ts",
|
|
49
|
+
"pack": "bun scripts/pack.ts",
|
|
50
|
+
"setup": "bun src/cli/cli.ts setup",
|
|
51
|
+
"start": "bun src/cli/cli.ts start",
|
|
52
|
+
"status": "bun src/cli/cli.ts status",
|
|
53
|
+
"stop": "bun src/cli/cli.ts stop",
|
|
54
|
+
"pause": "bun src/cli/cli.ts pause",
|
|
55
|
+
"resume": "bun src/cli/cli.ts resume",
|
|
56
|
+
"mcp": "bun src/cli/cli.ts mcp",
|
|
57
|
+
"ui": "bun --no-env-file src/cli/cli.ts ui",
|
|
58
|
+
"browser": "bun scripts/call.ts",
|
|
59
|
+
"fixture": "bun tests/helpers/fixture.ts",
|
|
60
|
+
"test": "bun test ./tests/unit ./tests/integration && bun run test:regression",
|
|
61
|
+
"test:ui": "bun test tests/integration/catalog-limits.test.ts tests/unit/profile-windows.test.ts tests/unit/ui-server.test.ts tests/integration/ui-model.test.ts tests/integration/profile-configuration.test.ts tests/integration/profile-rename.test.ts tests/unit/ui-api.test.ts tests/unit/ui-display.test.ts",
|
|
62
|
+
"test:ui:browser": "bun tests/browser/ui-browser.ts",
|
|
63
|
+
"test:regression": "node --experimental-transform-types --test tests/regression/*.test.ts",
|
|
64
|
+
"test:integration": "bun tests/browser/integration.ts",
|
|
65
|
+
"test:native": "bun tests/browser/native-integration.ts",
|
|
66
|
+
"test:window-close": "bun tests/browser/window-close.ts",
|
|
67
|
+
"test:windows": "bun --no-env-file tests/browser/profile-windows-browser.ts",
|
|
68
|
+
"test:proxy": "bun tests/browser/proxy-integration.ts",
|
|
69
|
+
"test:manual": "bun tests/qa/manual-integration.ts",
|
|
70
|
+
"test:typing": "bun --no-env-file tests/browser/typing-browser.ts",
|
|
71
|
+
"test:public": "bun --no-env-file tests/qa/public-sites.ts",
|
|
72
|
+
"test:package": "bun tests/qa/package.ts",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"verify:release": "bun scripts/verify-release.ts",
|
|
75
|
+
"test:concurrency": "bun --no-env-file tests/browser/concurrency.ts",
|
|
76
|
+
"check": "bun run build && bun run typecheck && bun run test",
|
|
77
|
+
"test:transfer": "bun --no-env-file tests/browser/profile-transfer.ts"
|
|
44
78
|
},
|
|
45
79
|
"dependencies": {
|
|
46
80
|
"@askjo/camofox-browser": "1.18.1",
|
|
@@ -49,10 +83,30 @@
|
|
|
49
83
|
"hono": "4.13.16",
|
|
50
84
|
"playwright-core": "1.62.1",
|
|
51
85
|
"better-sqlite3": "13.0.1",
|
|
52
|
-
"impit": "0.14.8"
|
|
86
|
+
"impit": "0.14.8",
|
|
87
|
+
"stream-json": "3.8.0",
|
|
88
|
+
"yauzl": "3.4.0",
|
|
89
|
+
"yazl": "3.3.1"
|
|
53
90
|
},
|
|
54
91
|
"bundleDependencies": [
|
|
55
92
|
"@askjo/camofox-browser",
|
|
56
93
|
"camoufox-js"
|
|
57
|
-
]
|
|
94
|
+
],
|
|
95
|
+
"devDependencies": {
|
|
96
|
+
"@fontsource/ibm-plex-mono": "5.3.0",
|
|
97
|
+
"@fontsource/ibm-plex-sans": "5.3.0",
|
|
98
|
+
"@types/bun": "1.4.4",
|
|
99
|
+
"@types/react": "19.3.0",
|
|
100
|
+
"@types/react-dom": "19.3.0",
|
|
101
|
+
"react": "19.3.1",
|
|
102
|
+
"react-dom": "19.3.1",
|
|
103
|
+
"typescript": "5.9.3",
|
|
104
|
+
"vite": "8.3.6",
|
|
105
|
+
"@types/yauzl": "3.4.0",
|
|
106
|
+
"@types/yazl": "3.3.1"
|
|
107
|
+
},
|
|
108
|
+
"patchedDependencies": {
|
|
109
|
+
"@askjo/camofox-browser@1.18.1": "patches/@askjo%2Fcamofox-browser@1.18.1.patch",
|
|
110
|
+
"camoufox-js@0.11.5": "patches/camoufox-js@0.11.5.patch"
|
|
111
|
+
}
|
|
58
112
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: stelz-browser
|
|
3
|
-
description:
|
|
3
|
+
description: Set up Stelz, create or reuse a persistent browser profile, connect the current agent, and control the browser through MCP with exclusive control and human authentication.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Instructions for agents
|
|
@@ -11,14 +11,18 @@ Each profile has at most one browser instance. Multiple windows can belong to th
|
|
|
11
11
|
|
|
12
12
|
## Procedure
|
|
13
13
|
|
|
14
|
+
For installation, a missing profile, or missing tools, read [Onboarding](references/bootstrap.md).
|
|
15
|
+
Use the authorized CLI setup and start commands when available. Reuse existing state and client settings.
|
|
16
|
+
Do not treat MCP registration as proof that tools are available in this session.
|
|
17
|
+
|
|
14
18
|
1. Call `profile_status`.
|
|
15
|
-
2.
|
|
19
|
+
2. If the profile is missing or stopped, follow onboarding and run `stelz profile create ID --json` or `stelz start ID` as needed.
|
|
16
20
|
3. Call `profile_acquire`.
|
|
17
21
|
4. Read the open tabs with `camofox_list_tabs`.
|
|
18
22
|
5. Read a fresh `camofox_snapshot` before you select an action.
|
|
19
23
|
6. Use the returned element references for clicks and typing.
|
|
20
24
|
7. Check the result with a fresh snapshot.
|
|
21
|
-
8. Call `profile_release` when another client needs control.
|
|
25
|
+
8. Call `profile_release` when the task is complete or another client needs control. Keep the browser available.
|
|
22
26
|
|
|
23
27
|
An active controller causes another acquisition to fail. Wait for deliberate release or operator handoff.
|
|
24
28
|
Do not start another browser to avoid a controller conflict.
|