Compare commits
3 Commits
feature/we
...
4078073f0b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4078073f0b | ||
|
|
c9254ed7eb | ||
|
|
49d0236a52 |
@@ -20,7 +20,7 @@ This repository contains practical OpenClaw skills and companion integrations. I
|
|||||||
| `gitea-api` | Interact with Gitea via REST API (repos, issues, PRs, releases, branches, user info). | `skills/gitea-api` |
|
| `gitea-api` | Interact with Gitea via REST API (repos, issues, PRs, releases, branches, user info). | `skills/gitea-api` |
|
||||||
| `portainer` | Manage Portainer stacks via API (list, start/stop/restart, update, prune images). | `skills/portainer` |
|
| `portainer` | Manage Portainer stacks via API (list, start/stop/restart, update, prune images). | `skills/portainer` |
|
||||||
| `searxng` | Search through a local or self-hosted SearXNG instance for web, news, images, and more. | `skills/searxng` |
|
| `searxng` | Search through a local or self-hosted SearXNG instance for web, news, images, and more. | `skills/searxng` |
|
||||||
| `web-automation` | One-shot extraction plus broader browsing/scraping with Playwright + Camoufox (auth flows, extraction, bot-protected sites). | `skills/web-automation` |
|
| `web-automation` | One-shot extraction plus broader browsing/scraping with Playwright-compatible CloakBrowser (auth flows, extraction, bot-protected sites). | `skills/web-automation` |
|
||||||
|
|
||||||
## Integrations
|
## Integrations
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ This folder contains detailed docs for each skill in this repository.
|
|||||||
- [`gitea-api`](gitea-api.md) — REST-based Gitea automation (no `tea` CLI required)
|
- [`gitea-api`](gitea-api.md) — REST-based Gitea automation (no `tea` CLI required)
|
||||||
- [`portainer`](portainer.md) — Portainer stack management (list, lifecycle, updates, image pruning)
|
- [`portainer`](portainer.md) — Portainer stack management (list, lifecycle, updates, image pruning)
|
||||||
- [`searxng`](searxng.md) — Privacy-respecting metasearch via a local or self-hosted SearXNG instance
|
- [`searxng`](searxng.md) — Privacy-respecting metasearch via a local or self-hosted SearXNG instance
|
||||||
- [`web-automation`](web-automation.md) — One-shot extraction plus Playwright + Camoufox browser automation and scraping
|
- [`web-automation`](web-automation.md) — One-shot extraction plus Playwright-compatible CloakBrowser browser automation and scraping
|
||||||
|
|
||||||
## Integrations
|
## Integrations
|
||||||
|
|
||||||
|
|||||||
21
docs/plans/2026-03-10-web-automation-consolidation-design.md
Normal file
21
docs/plans/2026-03-10-web-automation-consolidation-design.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Web Automation Consolidation Design
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Consolidate `playwright-safe` into `web-automation` so the repo exposes a single web skill. Keep the proven one-shot extractor behavior, rename it to `extract.js`, and remove the separate `playwright-safe` skill and docs.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
`web-automation` remains the only published skill. It will expose two capability bands under one skill: one-shot extraction via `scripts/extract.js`, and broader stateful automation via the existing `auth.ts`, `browse.ts`, `flow.ts`, and `scrape.ts` commands. The one-shot extractor will keep the current safe Playwright behavior: single URL, JSON output, bounded stealth/anti-bot handling, and no sandbox-disabling Chromium flags.
|
||||||
|
|
||||||
|
## Migration
|
||||||
|
- Copy the working extractor into `skills/web-automation/scripts/extract.js`
|
||||||
|
- Update `skills/web-automation/SKILL.md` and `docs/web-automation.md` to describe both one-shot extraction and full automation
|
||||||
|
- Remove `skills/playwright-safe/`
|
||||||
|
- Remove `docs/playwright-safe.md`
|
||||||
|
- Remove README/doc index references to `playwright-safe`
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
- `node skills/web-automation/scripts/extract.js` -> JSON error for missing URL
|
||||||
|
- `node skills/web-automation/scripts/extract.js ftp://example.com` -> JSON error for invalid scheme
|
||||||
|
- `node skills/web-automation/scripts/extract.js https://example.com` -> valid JSON result with title/status
|
||||||
|
- Repo text scan confirms no remaining published references directing users to `playwright-safe`
|
||||||
|
- Commit, push, and clean up the worktree
|
||||||
132
docs/plans/2026-03-10-web-automation-consolidation.md
Normal file
132
docs/plans/2026-03-10-web-automation-consolidation.md
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Web Automation Consolidation Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Consolidate the separate `playwright-safe` skill into `web-automation` and publish a single web skill with both one-shot extraction and broader automation.
|
||||||
|
|
||||||
|
**Architecture:** Move the proven safe one-shot extractor into `skills/web-automation/scripts/extract.js`, update `web-automation` docs to expose it as the simple path, and remove the separate `playwright-safe` skill and docs. Keep the extractor behavior unchanged except for its new location/name.
|
||||||
|
|
||||||
|
**Tech Stack:** Node.js, Playwright, Camoufox skill docs, git
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Create isolated worktree
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: repo git metadata only
|
||||||
|
|
||||||
|
**Step 1: Create worktree**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git -C /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills worktree add /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-consolidation -b feature/web-automation-consolidation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Verify baseline**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git -C /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-consolidation status --short --branch
|
||||||
|
```
|
||||||
|
Expected: clean feature branch
|
||||||
|
|
||||||
|
### Task 2: Move the extractor into web-automation
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `skills/web-automation/scripts/extract.js`
|
||||||
|
- Read: `skills/playwright-safe/scripts/playwright-safe.js`
|
||||||
|
|
||||||
|
**Step 1: Copy the extractor**
|
||||||
|
- Copy the proven script content into `skills/web-automation/scripts/extract.js`
|
||||||
|
- Adjust only relative paths/messages if needed
|
||||||
|
|
||||||
|
**Step 2: Preserve behavior**
|
||||||
|
- Keep JSON-only output
|
||||||
|
- Keep URL validation
|
||||||
|
- Keep stealth/anti-bot behavior
|
||||||
|
- Keep sandbox enabled
|
||||||
|
|
||||||
|
### Task 3: Update skill and docs
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/web-automation/SKILL.md`
|
||||||
|
- Modify: `docs/web-automation.md`
|
||||||
|
- Modify: `README.md`
|
||||||
|
- Modify: `docs/README.md`
|
||||||
|
- Delete: `skills/playwright-safe/SKILL.md`
|
||||||
|
- Delete: `skills/playwright-safe/package.json`
|
||||||
|
- Delete: `skills/playwright-safe/package-lock.json`
|
||||||
|
- Delete: `skills/playwright-safe/.gitignore`
|
||||||
|
- Delete: `skills/playwright-safe/scripts/playwright-safe.js`
|
||||||
|
- Delete: `docs/playwright-safe.md`
|
||||||
|
|
||||||
|
**Step 1: Update docs**
|
||||||
|
- Make `web-automation` the only published web skill
|
||||||
|
- Document `extract.js` as the one-shot extraction path
|
||||||
|
- Remove published references to `playwright-safe`
|
||||||
|
|
||||||
|
**Step 2: Remove redundant skill**
|
||||||
|
- Delete the separate `playwright-safe` skill files and doc
|
||||||
|
|
||||||
|
### Task 4: Verify behavior
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Test: `skills/web-automation/scripts/extract.js`
|
||||||
|
|
||||||
|
**Step 1: Missing URL check**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-consolidation && node skills/web-automation/scripts/extract.js
|
||||||
|
```
|
||||||
|
Expected: JSON error about missing URL
|
||||||
|
|
||||||
|
**Step 2: Invalid scheme check**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-consolidation && node skills/web-automation/scripts/extract.js ftp://example.com
|
||||||
|
```
|
||||||
|
Expected: JSON error about only http/https URLs allowed
|
||||||
|
|
||||||
|
**Step 3: Smoke test**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-consolidation && node skills/web-automation/scripts/extract.js https://example.com
|
||||||
|
```
|
||||||
|
Expected: JSON with title `Example Domain`, status `200`, and no sandbox-disabling flags in code
|
||||||
|
|
||||||
|
**Step 4: Reference scan**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-consolidation && rg -n "playwright-safe" README.md docs skills
|
||||||
|
```
|
||||||
|
Expected: no remaining published references, or only intentional historical plan docs
|
||||||
|
|
||||||
|
### Task 5: Commit, push, and clean up
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: git history only
|
||||||
|
|
||||||
|
**Step 1: Commit**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git add skills/web-automation docs README.md
|
||||||
|
git commit -m "refactor: consolidate web scraping into web-automation"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Push**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git push -u origin feature/web-automation-consolidation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Merge and cleanup**
|
||||||
|
- Fast-forward or merge to `main`
|
||||||
|
- Push `main`
|
||||||
|
- Remove the worktree
|
||||||
|
- Delete the feature branch
|
||||||
33
docs/plans/2026-03-11-web-automation-cloakbrowser-design.md
Normal file
33
docs/plans/2026-03-11-web-automation-cloakbrowser-design.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Web Automation CloakBrowser Migration Design
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Replace all Camoufox and direct Playwright Chromium usage in `web-automation` with CloakBrowser, while preserving the existing feature set: one-shot extraction, persistent browsing sessions, authenticated flows, multi-step automation, and markdown scraping. After local validation, keep the repo copy and docs as the canonical published version, then commit and push.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
`web-automation` will become CloakBrowser-only. A single browser-launch layer in `skills/web-automation/scripts/browse.ts` will provide the canonical runtime for the other scripts. Stateful flows will use CloakBrowser persistent contexts; one-shot extraction will also use CloakBrowser instead of raw `playwright.chromium`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
- Replace `camoufox-js` in `browse.ts` and any helper/test scripts
|
||||||
|
- Replace direct `playwright.chromium` launch in `extract.js`
|
||||||
|
- Update shared types/imports to match the CloakBrowser Playwright-compatible API
|
||||||
|
- Remove Camoufox/Chromium-specific setup instructions from skill docs
|
||||||
|
- Update package metadata and lockfile to depend on `cloakbrowser`
|
||||||
|
- Keep the user-facing command surface stable where possible
|
||||||
|
|
||||||
|
## Compatibility Strategy
|
||||||
|
To minimize user breakage:
|
||||||
|
- keep the script filenames and CLI interfaces stable
|
||||||
|
- support old `CAMOUFOX_*` env vars as temporary aliases where practical
|
||||||
|
- introduce neutral naming in docs and code for the new canonical path
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
- Verify launcher setup directly through `browse.ts`
|
||||||
|
- Verify `extract.js` still handles: missing URL, invalid scheme, smoke extraction from `https://example.com`
|
||||||
|
- Verify one persistent-context path and one higher-level consumer (`scrape.ts` or `flow.ts`) still works
|
||||||
|
- Update docs only after the runtime is validated
|
||||||
|
|
||||||
|
## Rollout
|
||||||
|
1. Implement and verify locally in the repo worktree
|
||||||
|
2. Update repo docs/indexes to describe CloakBrowser-based `web-automation`
|
||||||
|
3. Commit and push the repo changes
|
||||||
|
4. If needed, sync the installed OpenClaw workspace copy from the validated repo version
|
||||||
136
docs/plans/2026-03-11-web-automation-cloakbrowser.md
Normal file
136
docs/plans/2026-03-11-web-automation-cloakbrowser.md
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# Web Automation CloakBrowser Migration Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Replace Camoufox and direct Chromium launches in `web-automation` with CloakBrowser and publish the updated repo/docs.
|
||||||
|
|
||||||
|
**Architecture:** Use a single CloakBrowser-backed launch path in `skills/web-automation/scripts/browse.ts`, migrate `extract.js` to the same backend, update dependent scripts and tests, then update docs and publish the repo changes.
|
||||||
|
|
||||||
|
**Tech Stack:** Node.js, TypeScript, JavaScript, Playwright-compatible browser automation, CloakBrowser, git
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Create isolated worktree
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: repo git metadata only
|
||||||
|
|
||||||
|
**Step 1: Create worktree**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git -C /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills worktree add /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-cloakbrowser -b feature/web-automation-cloakbrowser
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Verify baseline**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git -C /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-cloakbrowser status --short --branch
|
||||||
|
```
|
||||||
|
Expected: clean feature branch
|
||||||
|
|
||||||
|
### Task 2: Migrate the browser launcher
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/web-automation/scripts/browse.ts`
|
||||||
|
- Modify: `skills/web-automation/scripts/package.json`
|
||||||
|
- Modify: `skills/web-automation/scripts/pnpm-lock.yaml`
|
||||||
|
- Optional Modify: test helper scripts under `skills/web-automation/scripts/`
|
||||||
|
|
||||||
|
**Step 1: Write the failing verification**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-cloakbrowser/skills/web-automation/scripts && node -e "require.resolve('cloakbrowser/package.json')"
|
||||||
|
```
|
||||||
|
Expected: fail before dependency migration
|
||||||
|
|
||||||
|
**Step 2: Replace backend dependency**
|
||||||
|
- remove `camoufox-js`
|
||||||
|
- add `cloakbrowser`
|
||||||
|
- update `browse.ts` to launch CloakBrowser contexts
|
||||||
|
- preserve persistent profile support
|
||||||
|
|
||||||
|
**Step 3: Verify launcher wiring**
|
||||||
|
|
||||||
|
Run a direct browse smoke test after install/update.
|
||||||
|
|
||||||
|
### Task 3: Migrate dependent scripts
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/web-automation/scripts/extract.js`
|
||||||
|
- Modify: `skills/web-automation/scripts/auth.ts`
|
||||||
|
- Modify: `skills/web-automation/scripts/flow.ts`
|
||||||
|
- Modify: `skills/web-automation/scripts/scrape.ts`
|
||||||
|
- Modify: `skills/web-automation/scripts/test-minimal.ts`
|
||||||
|
- Modify: `skills/web-automation/scripts/test-full.ts`
|
||||||
|
- Modify: `skills/web-automation/scripts/test-profile.ts`
|
||||||
|
|
||||||
|
**Step 1: Keep interfaces stable**
|
||||||
|
- preserve CLI usage where possible
|
||||||
|
- use CloakBrowser through shared launcher code
|
||||||
|
- keep one-shot extraction JSON output unchanged except for backend wording if needed
|
||||||
|
|
||||||
|
**Step 2: Add compatibility aliases**
|
||||||
|
- support old `CAMOUFOX_*` env vars where practical
|
||||||
|
- document new canonical naming
|
||||||
|
|
||||||
|
### Task 4: Verify behavior
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Test: `skills/web-automation/scripts/*`
|
||||||
|
|
||||||
|
**Step 1: Extractor error checks**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-cloakbrowser && node skills/web-automation/scripts/extract.js
|
||||||
|
```
|
||||||
|
Expected: JSON error for missing URL
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-cloakbrowser && node skills/web-automation/scripts/extract.js ftp://example.com
|
||||||
|
```
|
||||||
|
Expected: JSON error for invalid scheme
|
||||||
|
|
||||||
|
**Step 2: Extractor smoke test**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
cd /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/web-automation-cloakbrowser && node skills/web-automation/scripts/extract.js https://example.com
|
||||||
|
```
|
||||||
|
Expected: JSON result with title `Example Domain` and status `200`
|
||||||
|
|
||||||
|
**Step 3: Stateful path verification**
|
||||||
|
- run one direct `browse.ts`, `scrape.ts`, or `flow.ts` command using the CloakBrowser backend
|
||||||
|
- confirm persistent-context code still initializes successfully
|
||||||
|
|
||||||
|
### Task 5: Update docs and publish
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `skills/web-automation/SKILL.md`
|
||||||
|
- Modify: `docs/web-automation.md`
|
||||||
|
- Modify: `README.md`
|
||||||
|
- Modify: `docs/README.md`
|
||||||
|
|
||||||
|
**Step 1: Update docs**
|
||||||
|
- replace Camoufox wording with CloakBrowser wording
|
||||||
|
- replace old setup/install steps
|
||||||
|
- document any compatibility env vars and new canonical names
|
||||||
|
|
||||||
|
**Step 2: Commit and push**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```bash
|
||||||
|
git add skills/web-automation docs README.md
|
||||||
|
git commit -m "refactor: migrate web-automation to cloakbrowser"
|
||||||
|
git push -u origin feature/web-automation-cloakbrowser
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Merge and cleanup**
|
||||||
|
- fast-forward or merge to `main`
|
||||||
|
- push `main`
|
||||||
|
- remove the worktree
|
||||||
|
- delete the feature branch
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# web-automation
|
# web-automation
|
||||||
|
|
||||||
Automated web browsing and scraping using Playwright, with one-shot extraction and broader Camoufox-based automation under a single skill.
|
Automated web browsing and scraping using Playwright-compatible CloakBrowser, with one-shot extraction and broader persistent automation under a single skill.
|
||||||
|
|
||||||
## What this skill is for
|
## What this skill is for
|
||||||
|
|
||||||
@@ -20,15 +20,14 @@ Automated web browsing and scraping using Playwright, with one-shot extraction a
|
|||||||
|
|
||||||
- Node.js 20+
|
- Node.js 20+
|
||||||
- `pnpm`
|
- `pnpm`
|
||||||
- Network access to download browser binaries
|
- Network access to download the CloakBrowser binary on first use or via preinstall
|
||||||
|
|
||||||
## First-time setup
|
## First-time setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/.openclaw/workspace/skills/web-automation/scripts
|
cd ~/.openclaw/workspace/skills/web-automation/scripts
|
||||||
pnpm install
|
pnpm install
|
||||||
npx playwright install chromium
|
npx cloakbrowser install
|
||||||
npx camoufox-js fetch
|
|
||||||
pnpm approve-builds
|
pnpm approve-builds
|
||||||
pnpm rebuild better-sqlite3 esbuild
|
pnpm rebuild better-sqlite3 esbuild
|
||||||
```
|
```
|
||||||
@@ -48,7 +47,7 @@ pnpm approve-builds
|
|||||||
pnpm rebuild better-sqlite3 esbuild
|
pnpm rebuild better-sqlite3 esbuild
|
||||||
```
|
```
|
||||||
|
|
||||||
Without this, `browse.ts` and `scrape.ts` may fail before launch because the native bindings are missing.
|
Without this, helper scripts may fail before launch because the native bindings are missing.
|
||||||
|
|
||||||
## Common commands
|
## Common commands
|
||||||
|
|
||||||
@@ -56,7 +55,7 @@ Without this, `browse.ts` and `scrape.ts` may fail before launch because the nat
|
|||||||
# One-shot JSON extraction
|
# One-shot JSON extraction
|
||||||
node skills/web-automation/scripts/extract.js "https://example.com"
|
node skills/web-automation/scripts/extract.js "https://example.com"
|
||||||
|
|
||||||
# Browse a page
|
# Browse a page with persistent profile
|
||||||
npx tsx browse.ts --url "https://example.com"
|
npx tsx browse.ts --url "https://example.com"
|
||||||
|
|
||||||
# Scrape markdown
|
# Scrape markdown
|
||||||
@@ -104,6 +103,24 @@ USER_AGENT="Mozilla/5.0 ..." node skills/web-automation/scripts/extract.js "http
|
|||||||
- optional `screenshot`
|
- optional `screenshot`
|
||||||
- optional `htmlFile`
|
- optional `htmlFile`
|
||||||
|
|
||||||
|
## Persistent browsing profile
|
||||||
|
|
||||||
|
`browse.ts`, `auth.ts`, `flow.ts`, and `scrape.ts` use a persistent CloakBrowser profile so sessions survive across runs.
|
||||||
|
|
||||||
|
Canonical env vars:
|
||||||
|
|
||||||
|
- `CLOAKBROWSER_PROFILE_PATH`
|
||||||
|
- `CLOAKBROWSER_HEADLESS`
|
||||||
|
- `CLOAKBROWSER_USERNAME`
|
||||||
|
- `CLOAKBROWSER_PASSWORD`
|
||||||
|
|
||||||
|
Legacy aliases still supported for compatibility:
|
||||||
|
|
||||||
|
- `CAMOUFOX_PROFILE_PATH`
|
||||||
|
- `CAMOUFOX_HEADLESS`
|
||||||
|
- `CAMOUFOX_USERNAME`
|
||||||
|
- `CAMOUFOX_PASSWORD`
|
||||||
|
|
||||||
## Natural-language flow runner (`flow.ts`)
|
## Natural-language flow runner (`flow.ts`)
|
||||||
|
|
||||||
Use `flow.ts` when you want a general command style like:
|
Use `flow.ts` when you want a general command style like:
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
---
|
---
|
||||||
name: web-automation
|
name: web-automation
|
||||||
description: Browse and scrape web pages using Playwright with Camoufox anti-detection browser. Use when automating web workflows, extracting rendered page content, handling authenticated sessions, or scraping websites with bot protection.
|
description: Browse and scrape web pages using Playwright-compatible CloakBrowser. Use when automating web workflows, extracting rendered page content, handling authenticated sessions, or scraping websites with bot protection.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Web Automation with Camoufox (Codex)
|
# Web Automation with CloakBrowser (Codex)
|
||||||
|
|
||||||
Automated web browsing and scraping using Playwright with two execution paths under one skill:
|
Automated web browsing and scraping using Playwright-compatible CloakBrowser with two execution paths under one skill:
|
||||||
|
|
||||||
- one-shot extraction via `extract.js`
|
- one-shot extraction via `extract.js`
|
||||||
- broader stateful automation via Camoufox and the existing `auth.ts`, `browse.ts`, `flow.ts`, and `scrape.ts`
|
- broader stateful automation via CloakBrowser and the existing `auth.ts`, `browse.ts`, `flow.ts`, and `scrape.ts`
|
||||||
|
|
||||||
## When To Use Which Command
|
## When To Use Which Command
|
||||||
|
|
||||||
@@ -20,32 +20,31 @@ Automated web browsing and scraping using Playwright with two execution paths un
|
|||||||
|
|
||||||
- Node.js 20+
|
- Node.js 20+
|
||||||
- pnpm
|
- pnpm
|
||||||
- Network access to download browser binaries
|
- Network access to download the CloakBrowser binary on first use or via preinstall
|
||||||
|
|
||||||
## First-Time Setup
|
## First-Time Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/.openclaw/workspace/skills/web-automation/scripts
|
cd ~/.openclaw/workspace/skills/web-automation/scripts
|
||||||
pnpm install
|
pnpm install
|
||||||
npx playwright install chromium
|
npx cloakbrowser install
|
||||||
npx camoufox-js fetch
|
|
||||||
pnpm approve-builds
|
pnpm approve-builds
|
||||||
pnpm rebuild better-sqlite3 esbuild
|
pnpm rebuild better-sqlite3 esbuild
|
||||||
```
|
```
|
||||||
|
|
||||||
## Prerequisite Check (MANDATORY)
|
## Prerequisite Check (MANDATORY)
|
||||||
|
|
||||||
Before running any automation, verify Playwright + Camoufox dependencies are installed and scripts are configured to use Camoufox.
|
Before running any automation, verify CloakBrowser and Playwright Core dependencies are installed and scripts are configured to use CloakBrowser.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/.openclaw/workspace/skills/web-automation/scripts
|
cd ~/.openclaw/workspace/skills/web-automation/scripts
|
||||||
node -e "require.resolve('playwright/package.json');require.resolve('playwright-core/package.json');require.resolve('camoufox-js/package.json');console.log('OK: playwright + playwright-core + camoufox-js installed')"
|
node -e "require.resolve('cloakbrowser');require.resolve('playwright-core/package.json');console.log('OK: cloakbrowser + playwright-core installed')"
|
||||||
node -e "const fs=require('fs');const t=fs.readFileSync('browse.ts','utf8');if(!/camoufox-js/.test(t)){throw new Error('browse.ts is not configured for Camoufox')}console.log('OK: Camoufox integration detected in browse.ts')"
|
node -e "const fs=require('fs');const t=fs.readFileSync('browse.ts','utf8');if(!/launchPersistentContext\s*from\s*\'cloakbrowser\'/.test(t)){throw new Error('browse.ts is not configured for CloakBrowser')}console.log('OK: CloakBrowser integration detected in browse.ts')"
|
||||||
```
|
```
|
||||||
|
|
||||||
If any check fails, stop and return:
|
If any check fails, stop and return:
|
||||||
|
|
||||||
"Missing dependency/config: web-automation requires `playwright`, `playwright-core`, and `camoufox-js` with Camoufox-based scripts. Run setup in this skill, then retry."
|
"Missing dependency/config: web-automation requires `cloakbrowser` and `playwright-core` with CloakBrowser-based scripts. Run setup in this skill, then retry."
|
||||||
|
|
||||||
If runtime fails with missing native bindings for `better-sqlite3` or `esbuild`, run:
|
If runtime fails with missing native bindings for `better-sqlite3` or `esbuild`, run:
|
||||||
|
|
||||||
@@ -96,9 +95,15 @@ Example:
|
|||||||
npx tsx flow.ts --instruction 'go to https://search.fiorinis.com then type "pippo" then press enter then wait 2s'
|
npx tsx flow.ts --instruction 'go to https://search.fiorinis.com then type "pippo" then press enter then wait 2s'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Compatibility Aliases
|
||||||
|
|
||||||
|
- `CAMOUFOX_PROFILE_PATH` still works as a legacy alias for `CLOAKBROWSER_PROFILE_PATH`
|
||||||
|
- `CAMOUFOX_HEADLESS` still works as a legacy alias for `CLOAKBROWSER_HEADLESS`
|
||||||
|
- `CAMOUFOX_USERNAME` and `CAMOUFOX_PASSWORD` still work as legacy aliases for `CLOAKBROWSER_USERNAME` and `CLOAKBROWSER_PASSWORD`
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Sessions persist in Camoufox profile storage.
|
- Sessions persist in CloakBrowser profile storage.
|
||||||
- Use `--wait` for dynamic pages.
|
- Use `--wait` for dynamic pages.
|
||||||
- Use `--mode selector --selector "..."` for targeted extraction.
|
- Use `--mode selector --selector "..."` for targeted extraction.
|
||||||
- `extract.js` keeps stealth and bounded anti-bot shaping while keeping the Chromium sandbox enabled.
|
- `extract.js` keeps stealth and bounded anti-bot shaping while keeping the browser sandbox enabled.
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ function getCredentials(options?: {
|
|||||||
username?: string;
|
username?: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
}): { username: string; password: string } | null {
|
}): { username: string; password: string } | null {
|
||||||
const username = options?.username || process.env.CAMOUFOX_USERNAME;
|
const username = options?.username || process.env.CLOAKBROWSER_USERNAME || process.env.CAMOUFOX_USERNAME;
|
||||||
const password = options?.password || process.env.CAMOUFOX_PASSWORD;
|
const password = options?.password || process.env.CLOAKBROWSER_PASSWORD || process.env.CAMOUFOX_PASSWORD;
|
||||||
|
|
||||||
if (!username || !password) {
|
if (!username || !password) {
|
||||||
return null;
|
return null;
|
||||||
@@ -450,7 +450,7 @@ export async function navigateAuthenticated(
|
|||||||
if (!credentials) {
|
if (!credentials) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Authentication required but no credentials provided. ' +
|
'Authentication required but no credentials provided. ' +
|
||||||
'Set CAMOUFOX_USERNAME and CAMOUFOX_PASSWORD environment variables.'
|
'Set CLOAKBROWSER_USERNAME and CLOAKBROWSER_PASSWORD environment variables. Legacy aliases CAMOUFOX_USERNAME and CAMOUFOX_PASSWORD are also supported.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,8 +504,8 @@ Usage:
|
|||||||
Options:
|
Options:
|
||||||
-u, --url <url> URL to authenticate (required)
|
-u, --url <url> URL to authenticate (required)
|
||||||
-t, --type <type> Auth type: auto, form, or msal (default: auto)
|
-t, --type <type> Auth type: auto, form, or msal (default: auto)
|
||||||
--username <user> Username/email (or set CAMOUFOX_USERNAME env var)
|
--username <user> Username/email (or set CLOAKBROWSER_USERNAME env var)
|
||||||
--password <pass> Password (or set CAMOUFOX_PASSWORD env var)
|
--password <pass> Password (or set CLOAKBROWSER_PASSWORD env var)
|
||||||
--headless <bool> Run in headless mode (default: false for auth)
|
--headless <bool> Run in headless mode (default: false for auth)
|
||||||
-h, --help Show this help message
|
-h, --help Show this help message
|
||||||
|
|
||||||
@@ -515,8 +515,12 @@ Auth Types:
|
|||||||
msal Microsoft SSO (login.microsoftonline.com)
|
msal Microsoft SSO (login.microsoftonline.com)
|
||||||
|
|
||||||
Environment Variables:
|
Environment Variables:
|
||||||
CAMOUFOX_USERNAME Default username/email for authentication
|
CLOAKBROWSER_USERNAME Default username/email for authentication
|
||||||
CAMOUFOX_PASSWORD Default password for authentication
|
CLOAKBROWSER_PASSWORD Default password for authentication
|
||||||
|
|
||||||
|
Compatibility Aliases:
|
||||||
|
CAMOUFOX_USERNAME Legacy alias for CLOAKBROWSER_USERNAME
|
||||||
|
CAMOUFOX_PASSWORD Legacy alias for CLOAKBROWSER_PASSWORD
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
# Interactive login (no credentials, opens browser)
|
# Interactive login (no credentials, opens browser)
|
||||||
@@ -527,11 +531,11 @@ Examples:
|
|||||||
--username "user@example.com" --password "secret"
|
--username "user@example.com" --password "secret"
|
||||||
|
|
||||||
# Microsoft SSO login
|
# Microsoft SSO login
|
||||||
CAMOUFOX_USERNAME=user@company.com CAMOUFOX_PASSWORD=secret \\
|
CLOAKBROWSER_USERNAME=user@company.com CLOAKBROWSER_PASSWORD=secret \\
|
||||||
npx tsx auth.ts --url "https://internal.company.com" --type msal
|
npx tsx auth.ts --url "https://internal.company.com" --type msal
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Session is saved to ~/.camoufox-profile/ for persistence
|
- Session is saved to ~/.cloakbrowser-profile/ for persistence
|
||||||
- After successful auth, subsequent browses will be authenticated
|
- After successful auth, subsequent browses will be authenticated
|
||||||
- Use --headless false if you need to handle MFA manually
|
- Use --headless false if you need to handle MFA manually
|
||||||
`);
|
`);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env npx tsx
|
#!/usr/bin/env npx tsx
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Browser launcher using Camoufox with persistent profile
|
* Browser launcher using CloakBrowser with persistent profile
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* npx tsx browse.ts --url "https://example.com"
|
* npx tsx browse.ts --url "https://example.com"
|
||||||
@@ -9,14 +9,13 @@
|
|||||||
* npx tsx browse.ts --url "https://example.com" --headless false --wait 5000
|
* npx tsx browse.ts --url "https://example.com" --headless false --wait 5000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Camoufox } from 'camoufox-js';
|
import { launchPersistentContext } from 'cloakbrowser';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { existsSync, mkdirSync } from 'fs';
|
import { existsSync, mkdirSync } from 'fs';
|
||||||
import parseArgs from 'minimist';
|
import parseArgs from 'minimist';
|
||||||
import type { Page, BrowserContext } from 'playwright-core';
|
import type { Page, BrowserContext } from 'playwright-core';
|
||||||
|
|
||||||
// Types
|
|
||||||
interface BrowseOptions {
|
interface BrowseOptions {
|
||||||
url: string;
|
url: string;
|
||||||
headless?: boolean;
|
headless?: boolean;
|
||||||
@@ -33,55 +32,54 @@ interface BrowseResult {
|
|||||||
screenshotPath?: string;
|
screenshotPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get profile directory
|
function sleep(ms: number): Promise<void> {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
const getProfilePath = (): string => {
|
const getProfilePath = (): string => {
|
||||||
const customPath = process.env.CAMOUFOX_PROFILE_PATH;
|
const customPath = process.env.CLOAKBROWSER_PROFILE_PATH || process.env.CAMOUFOX_PROFILE_PATH;
|
||||||
if (customPath) return customPath;
|
if (customPath) return customPath;
|
||||||
|
|
||||||
const profileDir = join(homedir(), '.camoufox-profile');
|
const profileDir = join(homedir(), '.cloakbrowser-profile');
|
||||||
if (!existsSync(profileDir)) {
|
if (!existsSync(profileDir)) {
|
||||||
mkdirSync(profileDir, { recursive: true });
|
mkdirSync(profileDir, { recursive: true });
|
||||||
}
|
}
|
||||||
return profileDir;
|
return profileDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Launch browser with persistent profile
|
|
||||||
export async function launchBrowser(options: {
|
export async function launchBrowser(options: {
|
||||||
headless?: boolean;
|
headless?: boolean;
|
||||||
}): Promise<BrowserContext> {
|
}): Promise<BrowserContext> {
|
||||||
const profilePath = getProfilePath();
|
const profilePath = getProfilePath();
|
||||||
const headless =
|
const envHeadless = process.env.CLOAKBROWSER_HEADLESS ?? process.env.CAMOUFOX_HEADLESS;
|
||||||
options.headless ??
|
const headless = options.headless ?? (envHeadless ? envHeadless === 'true' : true);
|
||||||
(process.env.CAMOUFOX_HEADLESS ? process.env.CAMOUFOX_HEADLESS === 'true' : true);
|
|
||||||
|
|
||||||
console.log(`Using profile: ${profilePath}`);
|
console.log(`Using profile: ${profilePath}`);
|
||||||
console.log(`Headless mode: ${headless}`);
|
console.log(`Headless mode: ${headless}`);
|
||||||
|
|
||||||
const browser = await Camoufox({
|
const context = await launchPersistentContext({
|
||||||
user_data_dir: profilePath,
|
userDataDir: profilePath,
|
||||||
headless,
|
headless,
|
||||||
|
humanize: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return browser;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Browse to URL and optionally take screenshot
|
|
||||||
export async function browse(options: BrowseOptions): Promise<BrowseResult> {
|
export async function browse(options: BrowseOptions): Promise<BrowseResult> {
|
||||||
const browser = await launchBrowser({ headless: options.headless });
|
const browser = await launchBrowser({ headless: options.headless });
|
||||||
const page = await browser.newPage();
|
const page = browser.pages()[0] || await browser.newPage();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Navigate to URL
|
|
||||||
console.log(`Navigating to: ${options.url}`);
|
console.log(`Navigating to: ${options.url}`);
|
||||||
await page.goto(options.url, {
|
await page.goto(options.url, {
|
||||||
timeout: options.timeout ?? 60000,
|
timeout: options.timeout ?? 60000,
|
||||||
waitUntil: 'domcontentloaded',
|
waitUntil: 'domcontentloaded',
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait if specified
|
|
||||||
if (options.wait) {
|
if (options.wait) {
|
||||||
console.log(`Waiting ${options.wait}ms...`);
|
console.log(`Waiting ${options.wait}ms...`);
|
||||||
await page.waitForTimeout(options.wait);
|
await sleep(options.wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result: BrowseResult = {
|
const result: BrowseResult = {
|
||||||
@@ -92,7 +90,6 @@ export async function browse(options: BrowseOptions): Promise<BrowseResult> {
|
|||||||
console.log(`Page title: ${result.title}`);
|
console.log(`Page title: ${result.title}`);
|
||||||
console.log(`Final URL: ${result.url}`);
|
console.log(`Final URL: ${result.url}`);
|
||||||
|
|
||||||
// Take screenshot if requested
|
|
||||||
if (options.screenshot) {
|
if (options.screenshot) {
|
||||||
const outputPath = options.output ?? 'screenshot.png';
|
const outputPath = options.output ?? 'screenshot.png';
|
||||||
await page.screenshot({ path: outputPath, fullPage: true });
|
await page.screenshot({ path: outputPath, fullPage: true });
|
||||||
@@ -100,11 +97,10 @@ export async function browse(options: BrowseOptions): Promise<BrowseResult> {
|
|||||||
console.log(`Screenshot saved: ${outputPath}`);
|
console.log(`Screenshot saved: ${outputPath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If interactive mode, keep browser open
|
|
||||||
if (options.interactive) {
|
if (options.interactive) {
|
||||||
console.log('\nInteractive mode - browser will stay open.');
|
console.log('\nInteractive mode - browser will stay open.');
|
||||||
console.log('Press Ctrl+C to close.');
|
console.log('Press Ctrl+C to close.');
|
||||||
await new Promise(() => {}); // Keep running
|
await new Promise(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -115,16 +111,14 @@ export async function browse(options: BrowseOptions): Promise<BrowseResult> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export page for use in other scripts
|
|
||||||
export async function getPage(options?: {
|
export async function getPage(options?: {
|
||||||
headless?: boolean;
|
headless?: boolean;
|
||||||
}): Promise<{ page: Page; browser: BrowserContext }> {
|
}): Promise<{ page: Page; browser: BrowserContext }> {
|
||||||
const browser = await launchBrowser({ headless: options?.headless });
|
const browser = await launchBrowser({ headless: options?.headless });
|
||||||
const page = await browser.newPage();
|
const page = browser.pages()[0] || await browser.newPage();
|
||||||
return { page, browser };
|
return { page, browser };
|
||||||
}
|
}
|
||||||
|
|
||||||
// CLI entry point
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const args = parseArgs(process.argv.slice(2), {
|
const args = parseArgs(process.argv.slice(2), {
|
||||||
string: ['url', 'output'],
|
string: ['url', 'output'],
|
||||||
@@ -145,7 +139,7 @@ async function main() {
|
|||||||
|
|
||||||
if (args.help || !args.url) {
|
if (args.help || !args.url) {
|
||||||
console.log(`
|
console.log(`
|
||||||
Web Browser with Camoufox
|
Web Browser with CloakBrowser
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
npx tsx browse.ts --url <url> [options]
|
npx tsx browse.ts --url <url> [options]
|
||||||
@@ -166,8 +160,12 @@ Examples:
|
|||||||
npx tsx browse.ts --url "https://example.com" --headless false --interactive
|
npx tsx browse.ts --url "https://example.com" --headless false --interactive
|
||||||
|
|
||||||
Environment Variables:
|
Environment Variables:
|
||||||
CAMOUFOX_PROFILE_PATH Custom profile directory (default: ~/.camoufox-profile/)
|
CLOAKBROWSER_PROFILE_PATH Custom profile directory (default: ~/.cloakbrowser-profile/)
|
||||||
CAMOUFOX_HEADLESS Default headless mode (true/false)
|
CLOAKBROWSER_HEADLESS Default headless mode (true/false)
|
||||||
|
|
||||||
|
Compatibility Aliases:
|
||||||
|
CAMOUFOX_PROFILE_PATH Legacy alias for CLOAKBROWSER_PROFILE_PATH
|
||||||
|
CAMOUFOX_HEADLESS Legacy alias for CLOAKBROWSER_HEADLESS
|
||||||
`);
|
`);
|
||||||
process.exit(args.help ? 0 : 1);
|
process.exit(args.help ? 0 : 1);
|
||||||
}
|
}
|
||||||
@@ -188,7 +186,6 @@ Environment Variables:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run if executed directly
|
|
||||||
const isMainModule = process.argv[1]?.includes('browse.ts');
|
const isMainModule = process.argv[1]?.includes('browse.ts');
|
||||||
if (isMainModule) {
|
if (isMainModule) {
|
||||||
main();
|
main();
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ const MAX_WAIT_MS = 20000;
|
|||||||
const NAV_TIMEOUT_MS = 30000;
|
const NAV_TIMEOUT_MS = 30000;
|
||||||
const EXTRA_CHALLENGE_WAIT_MS = 8000;
|
const EXTRA_CHALLENGE_WAIT_MS = 8000;
|
||||||
const CONTENT_LIMIT = 12000;
|
const CONTENT_LIMIT = 12000;
|
||||||
const DEFAULT_USER_AGENT =
|
|
||||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36";
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
@@ -52,6 +50,10 @@ function ensureParentDir(filePath) {
|
|||||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sleep(ms) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
async function detectChallenge(page) {
|
async function detectChallenge(page) {
|
||||||
try {
|
try {
|
||||||
return await page.evaluate(() => {
|
return await page.evaluate(() => {
|
||||||
@@ -70,73 +72,51 @@ async function detectChallenge(page) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadPlaywright() {
|
async function loadCloakBrowser() {
|
||||||
try {
|
try {
|
||||||
return await import("playwright");
|
return await import("cloakbrowser");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
fail(
|
fail(
|
||||||
"Playwright is not installed for this skill. Run pnpm install and npx playwright install chromium in skills/web-automation/scripts first.",
|
"CloakBrowser is not installed for this skill. Run pnpm install in skills/web-automation/scripts first.",
|
||||||
error.message
|
error.message
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function runWithStderrLogs(fn) {
|
||||||
|
const originalLog = console.log;
|
||||||
|
const originalError = console.error;
|
||||||
|
console.log = (...args) => process.stderr.write(`${args.join(" ")}\n`);
|
||||||
|
console.error = (...args) => process.stderr.write(`${args.join(" ")}\n`);
|
||||||
|
try {
|
||||||
|
return await fn();
|
||||||
|
} finally {
|
||||||
|
console.log = originalLog;
|
||||||
|
console.error = originalError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const requestedUrl = parseTarget(process.argv[2]);
|
const requestedUrl = parseTarget(process.argv[2]);
|
||||||
const waitTime = parseWaitTime(process.env.WAIT_TIME);
|
const waitTime = parseWaitTime(process.env.WAIT_TIME);
|
||||||
const screenshotPath = process.env.SCREENSHOT_PATH || "";
|
const screenshotPath = process.env.SCREENSHOT_PATH || "";
|
||||||
const saveHtml = process.env.SAVE_HTML === "true";
|
const saveHtml = process.env.SAVE_HTML === "true";
|
||||||
const headless = process.env.HEADLESS !== "false";
|
const headless = process.env.HEADLESS !== "false";
|
||||||
const userAgent = process.env.USER_AGENT || DEFAULT_USER_AGENT;
|
const userAgent = process.env.USER_AGENT || undefined;
|
||||||
const startedAt = Date.now();
|
const startedAt = Date.now();
|
||||||
const { chromium } = await loadPlaywright();
|
const { ensureBinary, launchContext } = await loadCloakBrowser();
|
||||||
|
|
||||||
let browser;
|
let context;
|
||||||
try {
|
try {
|
||||||
browser = await chromium.launch({
|
await runWithStderrLogs(() => ensureBinary());
|
||||||
headless,
|
|
||||||
ignoreDefaultArgs: ["--enable-automation"],
|
|
||||||
args: [
|
|
||||||
"--disable-blink-features=AutomationControlled",
|
|
||||||
"--disable-features=IsolateOrigins,site-per-process"
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const context = await browser.newContext({
|
context = await runWithStderrLogs(() => launchContext({
|
||||||
|
headless,
|
||||||
userAgent,
|
userAgent,
|
||||||
locale: "en-US",
|
locale: "en-US",
|
||||||
viewport: { width: 1440, height: 900 },
|
viewport: { width: 1440, height: 900 },
|
||||||
extraHTTPHeaders: {
|
humanize: true,
|
||||||
"Accept-Language": "en-US,en;q=0.9",
|
}));
|
||||||
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await context.addInitScript(() => {
|
|
||||||
Object.defineProperty(navigator, "webdriver", {
|
|
||||||
get: () => false
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(navigator, "languages", {
|
|
||||||
get: () => ["en-US", "en"]
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(navigator, "plugins", {
|
|
||||||
get: () => [1, 2, 3, 4, 5]
|
|
||||||
});
|
|
||||||
|
|
||||||
window.chrome = window.chrome || { runtime: {} };
|
|
||||||
|
|
||||||
const originalQuery = window.navigator.permissions?.query?.bind(window.navigator.permissions);
|
|
||||||
if (originalQuery) {
|
|
||||||
window.navigator.permissions.query = (parameters) => {
|
|
||||||
if (parameters?.name === "notifications") {
|
|
||||||
return Promise.resolve({ state: Notification.permission });
|
|
||||||
}
|
|
||||||
return originalQuery(parameters);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
const response = await page.goto(requestedUrl, {
|
const response = await page.goto(requestedUrl, {
|
||||||
@@ -144,11 +124,11 @@ async function main() {
|
|||||||
timeout: NAV_TIMEOUT_MS
|
timeout: NAV_TIMEOUT_MS
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.waitForTimeout(waitTime);
|
await sleep(waitTime);
|
||||||
|
|
||||||
let challengeDetected = await detectChallenge(page);
|
let challengeDetected = await detectChallenge(page);
|
||||||
if (challengeDetected) {
|
if (challengeDetected) {
|
||||||
await page.waitForTimeout(EXTRA_CHALLENGE_WAIT_MS);
|
await sleep(EXTRA_CHALLENGE_WAIT_MS);
|
||||||
challengeDetected = await detectChallenge(page);
|
challengeDetected = await detectChallenge(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,11 +172,11 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
||||||
await browser.close();
|
await context.close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (browser) {
|
if (context) {
|
||||||
try {
|
try {
|
||||||
await browser.close();
|
await context.close();
|
||||||
} catch {
|
} catch {
|
||||||
// Ignore close errors after the primary failure.
|
// Ignore close errors after the primary failure.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ async function main() {
|
|||||||
|
|
||||||
if (args.help || (!args.instruction && !args.steps)) {
|
if (args.help || (!args.instruction && !args.steps)) {
|
||||||
console.log(`
|
console.log(`
|
||||||
General Web Flow Runner (Camoufox)
|
General Web Flow Runner (CloakBrowser)
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
npx tsx flow.ts --instruction "go to https://example.com then type \"hello\" then press enter"
|
npx tsx flow.ts --instruction "go to https://example.com then type \"hello\" then press enter"
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "web-automation-scripts",
|
"name": "web-automation-scripts",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Web browsing and scraping scripts using Camoufox",
|
"description": "Web browsing and scraping scripts using CloakBrowser",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"extract": "node extract.js",
|
"extract": "node extract.js",
|
||||||
"browse": "tsx browse.ts",
|
"browse": "tsx browse.ts",
|
||||||
"scrape": "tsx scrape.ts",
|
"scrape": "tsx scrape.ts",
|
||||||
"fetch-browser": "npx camoufox-js fetch"
|
"fetch-browser": "npx cloakbrowser install"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mozilla/readability": "^0.5.0",
|
"@mozilla/readability": "^0.5.0",
|
||||||
"better-sqlite3": "^12.6.2",
|
"better-sqlite3": "^12.6.2",
|
||||||
"camoufox-js": "^0.8.5",
|
"cloakbrowser": "^0.3.14",
|
||||||
"jsdom": "^24.0.0",
|
"jsdom": "^24.0.0",
|
||||||
"minimist": "^1.2.8",
|
"minimist": "^1.2.8",
|
||||||
"playwright": "^1.58.2",
|
|
||||||
"playwright-core": "^1.40.0",
|
"playwright-core": "^1.40.0",
|
||||||
"turndown": "^7.1.2",
|
"turndown": "^7.1.2",
|
||||||
"turndown-plugin-gfm": "^1.0.2"
|
"turndown-plugin-gfm": "^1.0.2"
|
||||||
|
|||||||
480
skills/web-automation/scripts/pnpm-lock.yaml
generated
480
skills/web-automation/scripts/pnpm-lock.yaml
generated
@@ -14,18 +14,15 @@ importers:
|
|||||||
better-sqlite3:
|
better-sqlite3:
|
||||||
specifier: ^12.6.2
|
specifier: ^12.6.2
|
||||||
version: 12.6.2
|
version: 12.6.2
|
||||||
camoufox-js:
|
cloakbrowser:
|
||||||
specifier: ^0.8.5
|
specifier: ^0.3.14
|
||||||
version: 0.8.5(playwright-core@1.57.0)
|
version: 0.3.14(mmdb-lib@3.0.1)(playwright-core@1.57.0)
|
||||||
jsdom:
|
jsdom:
|
||||||
specifier: ^24.0.0
|
specifier: ^24.0.0
|
||||||
version: 24.1.3
|
version: 24.1.3
|
||||||
minimist:
|
minimist:
|
||||||
specifier: ^1.2.8
|
specifier: ^1.2.8
|
||||||
version: 1.2.8
|
version: 1.2.8
|
||||||
playwright:
|
|
||||||
specifier: ^1.58.2
|
|
||||||
version: 1.58.2
|
|
||||||
playwright-core:
|
playwright-core:
|
||||||
specifier: ^1.40.0
|
specifier: ^1.40.0
|
||||||
version: 1.57.0
|
version: 1.57.0
|
||||||
@@ -244,13 +241,9 @@ packages:
|
|||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@isaacs/balanced-match@4.0.1':
|
'@isaacs/fs-minipass@4.0.1':
|
||||||
resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
|
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: '>=18.0.0'}
|
||||||
|
|
||||||
'@isaacs/brace-expansion@5.0.0':
|
|
||||||
resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==}
|
|
||||||
engines: {node: 20 || >=22}
|
|
||||||
|
|
||||||
'@mixmark-io/domino@2.2.0':
|
'@mixmark-io/domino@2.2.0':
|
||||||
resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==}
|
resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==}
|
||||||
@@ -259,10 +252,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-Z+CZ3QaosfFaTqvhQsIktyGrjFjSC0Fa4EMph4mqKnWhmyoGICsV/8QK+8HpXut6zV7zwfWwqDmEjtk1Qf6EgQ==}
|
resolution: {integrity: sha512-Z+CZ3QaosfFaTqvhQsIktyGrjFjSC0Fa4EMph4mqKnWhmyoGICsV/8QK+8HpXut6zV7zwfWwqDmEjtk1Qf6EgQ==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
|
|
||||||
'@sindresorhus/is@4.6.0':
|
|
||||||
resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
|
|
||||||
'@types/jsdom@21.1.7':
|
'@types/jsdom@21.1.7':
|
||||||
resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==}
|
resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==}
|
||||||
|
|
||||||
@@ -278,10 +267,6 @@ packages:
|
|||||||
'@types/turndown@5.0.6':
|
'@types/turndown@5.0.6':
|
||||||
resolution: {integrity: sha512-ru00MoyeeouE5BX4gRL+6m/BsDfbRayOskWqUvh7CLGW+UXxHQItqALa38kKnOiZPqJrtzJUgAC2+F0rL1S4Pg==}
|
resolution: {integrity: sha512-ru00MoyeeouE5BX4gRL+6m/BsDfbRayOskWqUvh7CLGW+UXxHQItqALa38kKnOiZPqJrtzJUgAC2+F0rL1S4Pg==}
|
||||||
|
|
||||||
adm-zip@0.5.16:
|
|
||||||
resolution: {integrity: sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==}
|
|
||||||
engines: {node: '>=12.0'}
|
|
||||||
|
|
||||||
agent-base@7.1.4:
|
agent-base@7.1.4:
|
||||||
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
|
||||||
engines: {node: '>= 14'}
|
engines: {node: '>= 14'}
|
||||||
@@ -292,10 +277,6 @@ packages:
|
|||||||
base64-js@1.5.1:
|
base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
|
|
||||||
baseline-browser-mapping@2.9.14:
|
|
||||||
resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
better-sqlite3@12.6.2:
|
better-sqlite3@12.6.2:
|
||||||
resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==}
|
resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==}
|
||||||
engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x}
|
engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x}
|
||||||
@@ -306,11 +287,6 @@ packages:
|
|||||||
bl@4.1.0:
|
bl@4.1.0:
|
||||||
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
|
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
|
||||||
|
|
||||||
browserslist@4.28.1:
|
|
||||||
resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
|
|
||||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
buffer@5.7.1:
|
buffer@5.7.1:
|
||||||
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
|
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
|
||||||
|
|
||||||
@@ -318,31 +294,33 @@ packages:
|
|||||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
callsites@3.1.0:
|
|
||||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
|
|
||||||
camoufox-js@0.8.5:
|
|
||||||
resolution: {integrity: sha512-20ihPbspAcOVSUTX9Drxxp0C116DON1n8OVA1eUDglWZiHwiHwFVFOMrIEBwAHMZpU11mIEH/kawJtstRIrDPA==}
|
|
||||||
engines: {node: '>= 20'}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
playwright-core: '*'
|
|
||||||
|
|
||||||
caniuse-lite@1.0.30001764:
|
|
||||||
resolution: {integrity: sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==}
|
|
||||||
|
|
||||||
chownr@1.1.4:
|
chownr@1.1.4:
|
||||||
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
|
||||||
|
|
||||||
|
chownr@3.0.0:
|
||||||
|
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
cloakbrowser@0.3.14:
|
||||||
|
resolution: {integrity: sha512-8mcEVxfiNbAMHNa0B2IZKPtMDQ2peZlrScfQDJW+C9tjKG/P5Bg9wCweI0hnbaWR2ulG1MrxiEvTMMjz/SgmLw==}
|
||||||
|
engines: {node: '>=18.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
mmdb-lib: '>=2.0.0'
|
||||||
|
playwright-core: '>=1.40.0'
|
||||||
|
puppeteer-core: '>=21.0.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
mmdb-lib:
|
||||||
|
optional: true
|
||||||
|
playwright-core:
|
||||||
|
optional: true
|
||||||
|
puppeteer-core:
|
||||||
|
optional: true
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
combined-stream@1.0.8:
|
||||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
|
||||||
commander@14.0.2:
|
|
||||||
resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==}
|
|
||||||
engines: {node: '>=20'}
|
|
||||||
|
|
||||||
cssstyle@4.6.0:
|
cssstyle@4.6.0:
|
||||||
resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==}
|
resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -375,24 +353,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
|
|
||||||
detect-europe-js@0.1.2:
|
|
||||||
resolution: {integrity: sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==}
|
|
||||||
|
|
||||||
detect-libc@2.1.2:
|
detect-libc@2.1.2:
|
||||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
dot-prop@6.0.1:
|
|
||||||
resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
|
|
||||||
dunder-proto@1.0.1:
|
dunder-proto@1.0.1:
|
||||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
electron-to-chromium@1.5.267:
|
|
||||||
resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
|
|
||||||
|
|
||||||
end-of-stream@1.4.5:
|
end-of-stream@1.4.5:
|
||||||
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
|
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
|
||||||
|
|
||||||
@@ -421,10 +389,6 @@ packages:
|
|||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
escalade@3.2.0:
|
|
||||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
|
|
||||||
expand-template@2.0.3:
|
expand-template@2.0.3:
|
||||||
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
|
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -432,10 +396,6 @@ packages:
|
|||||||
file-uri-to-path@1.0.0:
|
file-uri-to-path@1.0.0:
|
||||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||||
|
|
||||||
fingerprint-generator@2.1.79:
|
|
||||||
resolution: {integrity: sha512-0dr3kTgvRYHleRPp6OBDcPb8amJmOyFr9aOuwnpN6ooWJ5XyT+/aL/SZ6CU4ZrEtzV26EyJ2Lg7PT32a0NdrRA==}
|
|
||||||
engines: {node: '>=16.0.0'}
|
|
||||||
|
|
||||||
form-data@4.0.5:
|
form-data@4.0.5:
|
||||||
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -443,11 +403,6 @@ packages:
|
|||||||
fs-constants@1.0.0:
|
fs-constants@1.0.0:
|
||||||
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
|
||||||
|
|
||||||
fsevents@2.3.2:
|
|
||||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
fsevents@2.3.3:
|
fsevents@2.3.3:
|
||||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
@@ -456,9 +411,6 @@ packages:
|
|||||||
function-bind@1.1.2:
|
function-bind@1.1.2:
|
||||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||||
|
|
||||||
generative-bayesian-network@2.1.79:
|
|
||||||
resolution: {integrity: sha512-aPH+V2wO+HE0BUX1LbsM8Ak99gmV43lgh+D7GDteM0zgnPqiAwcK9JZPxMPZa3aJUleFtFaL1lAei8g9zNrDIA==}
|
|
||||||
|
|
||||||
get-intrinsic@1.3.0:
|
get-intrinsic@1.3.0:
|
||||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -473,10 +425,6 @@ packages:
|
|||||||
github-from-package@0.0.0:
|
github-from-package@0.0.0:
|
||||||
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
||||||
|
|
||||||
glob@13.0.0:
|
|
||||||
resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==}
|
|
||||||
engines: {node: 20 || >=22}
|
|
||||||
|
|
||||||
gopd@1.2.0:
|
gopd@1.2.0:
|
||||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -493,10 +441,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
header-generator@2.1.79:
|
|
||||||
resolution: {integrity: sha512-YvHx8teq4QmV5mz7wdPMsj9n1OZBPnZxA4QE+EOrtx7xbmGvd1gBvDNKCb5XqS4GR/TL75MU5hqMqqqANdILRg==}
|
|
||||||
engines: {node: '>=16.0.0'}
|
|
||||||
|
|
||||||
html-encoding-sniffer@4.0.0:
|
html-encoding-sniffer@4.0.0:
|
||||||
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
|
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -516,74 +460,15 @@ packages:
|
|||||||
ieee754@1.2.1:
|
ieee754@1.2.1:
|
||||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||||
|
|
||||||
impit-darwin-arm64@0.7.6:
|
|
||||||
resolution: {integrity: sha512-M7NQXkttyzqilWfzVkNCp7hApT69m0etyJkVpHze4bR5z1kJnHhdsb8BSdDv2dzvZL4u1JyqZNxq+qoMn84eUw==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
impit-darwin-x64@0.7.6:
|
|
||||||
resolution: {integrity: sha512-kikTesWirAwJp9JPxzGLoGVc+heBlEabWS5AhTkQedACU153vmuL90OBQikVr3ul2N0LPImvnuB+51wV0zDE6g==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
impit-linux-arm64-gnu@0.7.6:
|
|
||||||
resolution: {integrity: sha512-H6GHjVr/0lG9VEJr6IHF8YLq+YkSIOF4k7Dfue2ygzUAj1+jZ5ZwnouhG/XrZHYW6EWsZmEAjjRfWE56Q0wDRQ==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
impit-linux-arm64-musl@0.7.6:
|
|
||||||
resolution: {integrity: sha512-1sCB/UBVXLZTpGJsXRdNNSvhN9xmmQcYLMWAAB4Itb7w684RHX1pLoCb6ichv7bfAf6tgaupcFIFZNBp3ghmQA==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
impit-linux-x64-gnu@0.7.6:
|
|
||||||
resolution: {integrity: sha512-yYhlRnZ4fhKt8kuGe0JK2WSHc8TkR6BEH0wn+guevmu8EOn9Xu43OuRvkeOyVAkRqvFnlZtMyySUo/GuSLz9Gw==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
impit-linux-x64-musl@0.7.6:
|
|
||||||
resolution: {integrity: sha512-sdGWyu+PCLmaOXy7Mzo4WP61ZLl5qpZ1L+VeXW+Ycazgu0e7ox0NZLdiLRunIrEzD+h0S+e4CyzNwaiP3yIolg==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
impit-win32-arm64-msvc@0.7.6:
|
|
||||||
resolution: {integrity: sha512-sM5deBqo0EuXg5GACBUMKEua9jIau/i34bwNlfrf/Amnw1n0GB4/RkuUh+sKiUcbNAntrRq+YhCq8qDP8IW19w==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
impit-win32-x64-msvc@0.7.6:
|
|
||||||
resolution: {integrity: sha512-ry63ADGLCB/PU/vNB1VioRt2V+klDJ34frJUXUZBEv1kA96HEAg9AxUk+604o+UHS3ttGH2rkLmrbwHOdAct5Q==}
|
|
||||||
engines: {node: '>= 10'}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
impit@0.7.6:
|
|
||||||
resolution: {integrity: sha512-AkS6Gv63+E6GMvBrcRhMmOREKpq5oJ0J5m3xwfkHiEs97UIsbpEqFmW3sFw/sdyOTDGRF5q4EjaLxtb922Ta8g==}
|
|
||||||
engines: {node: '>= 20'}
|
|
||||||
|
|
||||||
inherits@2.0.4:
|
inherits@2.0.4:
|
||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||||
|
|
||||||
ini@1.3.8:
|
ini@1.3.8:
|
||||||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
||||||
|
|
||||||
is-obj@2.0.0:
|
|
||||||
resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
|
|
||||||
is-potential-custom-element-name@1.0.1:
|
is-potential-custom-element-name@1.0.1:
|
||||||
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
|
||||||
|
|
||||||
is-standalone-pwa@0.1.1:
|
|
||||||
resolution: {integrity: sha512-9Cbovsa52vNQCjdXOzeQq5CnCbAcRk05aU62K20WO372NrTv0NxibLFCK6lQ4/iZEFdEA3p3t2VNOn8AJ53F5g==}
|
|
||||||
|
|
||||||
jsdom@24.1.3:
|
jsdom@24.1.3:
|
||||||
resolution: {integrity: sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==}
|
resolution: {integrity: sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -593,32 +478,13 @@ packages:
|
|||||||
canvas:
|
canvas:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
language-subtag-registry@0.3.23:
|
|
||||||
resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==}
|
|
||||||
|
|
||||||
language-tags@2.1.0:
|
|
||||||
resolution: {integrity: sha512-D4CgpyCt+61f6z2jHjJS1OmZPviAWM57iJ9OKdFFWSNgS7Udj9QVWqyGs/cveVNF57XpZmhSvMdVIV5mjLA7Vg==}
|
|
||||||
engines: {node: '>=22'}
|
|
||||||
|
|
||||||
lodash.isequal@4.5.0:
|
|
||||||
resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
|
|
||||||
deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
|
|
||||||
|
|
||||||
lru-cache@10.4.3:
|
lru-cache@10.4.3:
|
||||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||||
|
|
||||||
lru-cache@11.2.4:
|
|
||||||
resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
|
|
||||||
engines: {node: 20 || >=22}
|
|
||||||
|
|
||||||
math-intrinsics@1.1.0:
|
math-intrinsics@1.1.0:
|
||||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
maxmind@5.0.3:
|
|
||||||
resolution: {integrity: sha512-oMtZwLrsp0LcZehfYKIirtwKMBycMMqMA1/Dc9/BlUqIEtXO75mIzMJ3PYCV1Ji+BpoUCk+lTzRfh9c+ptGdyQ==}
|
|
||||||
engines: {node: '>=12', npm: '>=6'}
|
|
||||||
|
|
||||||
mime-db@1.52.0:
|
mime-db@1.52.0:
|
||||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -631,10 +497,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
|
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
minimatch@10.1.1:
|
|
||||||
resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==}
|
|
||||||
engines: {node: 20 || >=22}
|
|
||||||
|
|
||||||
minimist@1.2.8:
|
minimist@1.2.8:
|
||||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||||
|
|
||||||
@@ -642,6 +504,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||||
engines: {node: '>=16 || 14 >=14.17'}
|
engines: {node: '>=16 || 14 >=14.17'}
|
||||||
|
|
||||||
|
minizlib@3.1.0:
|
||||||
|
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
mkdirp-classic@0.5.3:
|
mkdirp-classic@0.5.3:
|
||||||
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||||
|
|
||||||
@@ -659,53 +525,25 @@ packages:
|
|||||||
resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==}
|
resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
node-releases@2.0.27:
|
|
||||||
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
|
|
||||||
|
|
||||||
nwsapi@2.2.23:
|
nwsapi@2.2.23:
|
||||||
resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==}
|
resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==}
|
||||||
|
|
||||||
once@1.4.0:
|
once@1.4.0:
|
||||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||||
|
|
||||||
ow@0.28.2:
|
|
||||||
resolution: {integrity: sha512-dD4UpyBh/9m4X2NVjA+73/ZPBRF+uF4zIMFvvQsabMiEK8x41L3rQ8EENOi35kyyoaJwNxEeJcP6Fj1H4U409Q==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
parse5@7.3.0:
|
parse5@7.3.0:
|
||||||
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
|
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
|
||||||
|
|
||||||
path-scurry@2.0.1:
|
|
||||||
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
|
|
||||||
engines: {node: 20 || >=22}
|
|
||||||
|
|
||||||
picocolors@1.1.1:
|
|
||||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
|
||||||
|
|
||||||
playwright-core@1.57.0:
|
playwright-core@1.57.0:
|
||||||
resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==}
|
resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
playwright-core@1.58.2:
|
|
||||||
resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
playwright@1.58.2:
|
|
||||||
resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
prebuild-install@7.1.3:
|
prebuild-install@7.1.3:
|
||||||
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
|
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
progress@2.0.3:
|
|
||||||
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
|
||||||
engines: {node: '>=0.4.0'}
|
|
||||||
|
|
||||||
psl@1.15.0:
|
psl@1.15.0:
|
||||||
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
|
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
|
||||||
|
|
||||||
@@ -745,10 +583,6 @@ packages:
|
|||||||
safer-buffer@2.1.2:
|
safer-buffer@2.1.2:
|
||||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||||
|
|
||||||
sax@1.4.4:
|
|
||||||
resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==}
|
|
||||||
engines: {node: '>=11.0.0'}
|
|
||||||
|
|
||||||
saxes@6.0.0:
|
saxes@6.0.0:
|
||||||
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
|
||||||
engines: {node: '>=v12.22.7'}
|
engines: {node: '>=v12.22.7'}
|
||||||
@@ -781,9 +615,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
tiny-lru@11.4.5:
|
tar@7.5.11:
|
||||||
resolution: {integrity: sha512-hkcz3FjNJfKXjV4mjQ1OrXSLAehg8Hw+cEZclOVT+5c/cWQWImQ9wolzTjth+dmmDe++p3bme3fTxz6Q4Etsqw==}
|
resolution: {integrity: sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
tough-cookie@4.1.4:
|
tough-cookie@4.1.4:
|
||||||
resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
|
resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
|
||||||
@@ -793,9 +627,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
|
resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
tslib@2.8.1:
|
|
||||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
|
||||||
|
|
||||||
tsx@4.21.0:
|
tsx@4.21.0:
|
||||||
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
|
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
@@ -815,13 +646,6 @@ packages:
|
|||||||
engines: {node: '>=14.17'}
|
engines: {node: '>=14.17'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
ua-is-frozen@0.1.2:
|
|
||||||
resolution: {integrity: sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==}
|
|
||||||
|
|
||||||
ua-parser-js@2.0.7:
|
|
||||||
resolution: {integrity: sha512-CFdHVHr+6YfbktNZegH3qbYvYgC7nRNEUm2tk7nSFXSODUu4tDBpaFpP1jdXBUOKKwapVlWRfTtS8bCPzsQ47w==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
undici-types@7.16.0:
|
undici-types@7.16.0:
|
||||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||||
|
|
||||||
@@ -829,22 +653,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
|
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
|
|
||||||
update-browserslist-db@1.2.3:
|
|
||||||
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
|
|
||||||
hasBin: true
|
|
||||||
peerDependencies:
|
|
||||||
browserslist: '>= 4.21.0'
|
|
||||||
|
|
||||||
url-parse@1.5.10:
|
url-parse@1.5.10:
|
||||||
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
|
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
|
||||||
|
|
||||||
util-deprecate@1.0.2:
|
util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
vali-date@1.0.0:
|
|
||||||
resolution: {integrity: sha512-sgECfZthyaCKW10N0fm27cg8HYTFK5qMWgypqkXMQ4Wbl/zZKx7xZICgcoxIIE+WFAP/MBL2EFwC/YvLxw3Zeg==}
|
|
||||||
engines: {node: '>=0.10.0'}
|
|
||||||
|
|
||||||
w3c-xmlserializer@5.0.0:
|
w3c-xmlserializer@5.0.0:
|
||||||
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -885,17 +699,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
|
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
xml2js@0.6.2:
|
|
||||||
resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==}
|
|
||||||
engines: {node: '>=4.0.0'}
|
|
||||||
|
|
||||||
xmlbuilder@11.0.1:
|
|
||||||
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
|
|
||||||
engines: {node: '>=4.0'}
|
|
||||||
|
|
||||||
xmlchars@2.2.0:
|
xmlchars@2.2.0:
|
||||||
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
|
||||||
|
|
||||||
|
yallist@5.0.0:
|
||||||
|
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@asamuzakjp/css-color@3.2.0':
|
'@asamuzakjp/css-color@3.2.0':
|
||||||
@@ -1004,18 +814,14 @@ snapshots:
|
|||||||
'@esbuild/win32-x64@0.27.0':
|
'@esbuild/win32-x64@0.27.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@isaacs/balanced-match@4.0.1': {}
|
'@isaacs/fs-minipass@4.0.1':
|
||||||
|
|
||||||
'@isaacs/brace-expansion@5.0.0':
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@isaacs/balanced-match': 4.0.1
|
minipass: 7.1.2
|
||||||
|
|
||||||
'@mixmark-io/domino@2.2.0': {}
|
'@mixmark-io/domino@2.2.0': {}
|
||||||
|
|
||||||
'@mozilla/readability@0.5.0': {}
|
'@mozilla/readability@0.5.0': {}
|
||||||
|
|
||||||
'@sindresorhus/is@4.6.0': {}
|
|
||||||
|
|
||||||
'@types/jsdom@21.1.7':
|
'@types/jsdom@21.1.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 25.0.6
|
'@types/node': 25.0.6
|
||||||
@@ -1032,16 +838,12 @@ snapshots:
|
|||||||
|
|
||||||
'@types/turndown@5.0.6': {}
|
'@types/turndown@5.0.6': {}
|
||||||
|
|
||||||
adm-zip@0.5.16: {}
|
|
||||||
|
|
||||||
agent-base@7.1.4: {}
|
agent-base@7.1.4: {}
|
||||||
|
|
||||||
asynckit@0.4.0: {}
|
asynckit@0.4.0: {}
|
||||||
|
|
||||||
base64-js@1.5.1: {}
|
base64-js@1.5.1: {}
|
||||||
|
|
||||||
baseline-browser-mapping@2.9.14: {}
|
|
||||||
|
|
||||||
better-sqlite3@12.6.2:
|
better-sqlite3@12.6.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
bindings: 1.5.0
|
bindings: 1.5.0
|
||||||
@@ -1057,14 +859,6 @@ snapshots:
|
|||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
|
|
||||||
browserslist@4.28.1:
|
|
||||||
dependencies:
|
|
||||||
baseline-browser-mapping: 2.9.14
|
|
||||||
caniuse-lite: 1.0.30001764
|
|
||||||
electron-to-chromium: 1.5.267
|
|
||||||
node-releases: 2.0.27
|
|
||||||
update-browserslist-db: 1.2.3(browserslist@4.28.1)
|
|
||||||
|
|
||||||
buffer@5.7.1:
|
buffer@5.7.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
base64-js: 1.5.1
|
base64-js: 1.5.1
|
||||||
@@ -1075,33 +869,21 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
|
|
||||||
callsites@3.1.0: {}
|
|
||||||
|
|
||||||
camoufox-js@0.8.5(playwright-core@1.57.0):
|
|
||||||
dependencies:
|
|
||||||
adm-zip: 0.5.16
|
|
||||||
better-sqlite3: 12.6.2
|
|
||||||
commander: 14.0.2
|
|
||||||
fingerprint-generator: 2.1.79
|
|
||||||
glob: 13.0.0
|
|
||||||
impit: 0.7.6
|
|
||||||
language-tags: 2.1.0
|
|
||||||
maxmind: 5.0.3
|
|
||||||
playwright-core: 1.57.0
|
|
||||||
progress: 2.0.3
|
|
||||||
ua-parser-js: 2.0.7
|
|
||||||
xml2js: 0.6.2
|
|
||||||
|
|
||||||
caniuse-lite@1.0.30001764: {}
|
|
||||||
|
|
||||||
chownr@1.1.4: {}
|
chownr@1.1.4: {}
|
||||||
|
|
||||||
|
chownr@3.0.0: {}
|
||||||
|
|
||||||
|
cloakbrowser@0.3.14(mmdb-lib@3.0.1)(playwright-core@1.57.0):
|
||||||
|
dependencies:
|
||||||
|
tar: 7.5.11
|
||||||
|
optionalDependencies:
|
||||||
|
mmdb-lib: 3.0.1
|
||||||
|
playwright-core: 1.57.0
|
||||||
|
|
||||||
combined-stream@1.0.8:
|
combined-stream@1.0.8:
|
||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream: 1.0.0
|
delayed-stream: 1.0.0
|
||||||
|
|
||||||
commander@14.0.2: {}
|
|
||||||
|
|
||||||
cssstyle@4.6.0:
|
cssstyle@4.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@asamuzakjp/css-color': 3.2.0
|
'@asamuzakjp/css-color': 3.2.0
|
||||||
@@ -1126,22 +908,14 @@ snapshots:
|
|||||||
|
|
||||||
delayed-stream@1.0.0: {}
|
delayed-stream@1.0.0: {}
|
||||||
|
|
||||||
detect-europe-js@0.1.2: {}
|
|
||||||
|
|
||||||
detect-libc@2.1.2: {}
|
detect-libc@2.1.2: {}
|
||||||
|
|
||||||
dot-prop@6.0.1:
|
|
||||||
dependencies:
|
|
||||||
is-obj: 2.0.0
|
|
||||||
|
|
||||||
dunder-proto@1.0.1:
|
dunder-proto@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers: 1.0.2
|
call-bind-apply-helpers: 1.0.2
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
gopd: 1.2.0
|
gopd: 1.2.0
|
||||||
|
|
||||||
electron-to-chromium@1.5.267: {}
|
|
||||||
|
|
||||||
end-of-stream@1.4.5:
|
end-of-stream@1.4.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
@@ -1192,18 +966,10 @@ snapshots:
|
|||||||
'@esbuild/win32-ia32': 0.27.0
|
'@esbuild/win32-ia32': 0.27.0
|
||||||
'@esbuild/win32-x64': 0.27.0
|
'@esbuild/win32-x64': 0.27.0
|
||||||
|
|
||||||
escalade@3.2.0: {}
|
|
||||||
|
|
||||||
expand-template@2.0.3: {}
|
expand-template@2.0.3: {}
|
||||||
|
|
||||||
file-uri-to-path@1.0.0: {}
|
file-uri-to-path@1.0.0: {}
|
||||||
|
|
||||||
fingerprint-generator@2.1.79:
|
|
||||||
dependencies:
|
|
||||||
generative-bayesian-network: 2.1.79
|
|
||||||
header-generator: 2.1.79
|
|
||||||
tslib: 2.8.1
|
|
||||||
|
|
||||||
form-data@4.0.5:
|
form-data@4.0.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
asynckit: 0.4.0
|
asynckit: 0.4.0
|
||||||
@@ -1214,19 +980,11 @@ snapshots:
|
|||||||
|
|
||||||
fs-constants@1.0.0: {}
|
fs-constants@1.0.0: {}
|
||||||
|
|
||||||
fsevents@2.3.2:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
fsevents@2.3.3:
|
fsevents@2.3.3:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
function-bind@1.1.2: {}
|
function-bind@1.1.2: {}
|
||||||
|
|
||||||
generative-bayesian-network@2.1.79:
|
|
||||||
dependencies:
|
|
||||||
adm-zip: 0.5.16
|
|
||||||
tslib: 2.8.1
|
|
||||||
|
|
||||||
get-intrinsic@1.3.0:
|
get-intrinsic@1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind-apply-helpers: 1.0.2
|
call-bind-apply-helpers: 1.0.2
|
||||||
@@ -1251,12 +1009,6 @@ snapshots:
|
|||||||
|
|
||||||
github-from-package@0.0.0: {}
|
github-from-package@0.0.0: {}
|
||||||
|
|
||||||
glob@13.0.0:
|
|
||||||
dependencies:
|
|
||||||
minimatch: 10.1.1
|
|
||||||
minipass: 7.1.2
|
|
||||||
path-scurry: 2.0.1
|
|
||||||
|
|
||||||
gopd@1.2.0: {}
|
gopd@1.2.0: {}
|
||||||
|
|
||||||
has-symbols@1.1.0: {}
|
has-symbols@1.1.0: {}
|
||||||
@@ -1269,13 +1021,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
|
|
||||||
header-generator@2.1.79:
|
|
||||||
dependencies:
|
|
||||||
browserslist: 4.28.1
|
|
||||||
generative-bayesian-network: 2.1.79
|
|
||||||
ow: 0.28.2
|
|
||||||
tslib: 2.8.1
|
|
||||||
|
|
||||||
html-encoding-sniffer@4.0.0:
|
html-encoding-sniffer@4.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-encoding: 3.1.1
|
whatwg-encoding: 3.1.1
|
||||||
@@ -1300,51 +1045,12 @@ snapshots:
|
|||||||
|
|
||||||
ieee754@1.2.1: {}
|
ieee754@1.2.1: {}
|
||||||
|
|
||||||
impit-darwin-arm64@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-darwin-x64@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-linux-arm64-gnu@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-linux-arm64-musl@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-linux-x64-gnu@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-linux-x64-musl@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-win32-arm64-msvc@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit-win32-x64-msvc@0.7.6:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
impit@0.7.6:
|
|
||||||
optionalDependencies:
|
|
||||||
impit-darwin-arm64: 0.7.6
|
|
||||||
impit-darwin-x64: 0.7.6
|
|
||||||
impit-linux-arm64-gnu: 0.7.6
|
|
||||||
impit-linux-arm64-musl: 0.7.6
|
|
||||||
impit-linux-x64-gnu: 0.7.6
|
|
||||||
impit-linux-x64-musl: 0.7.6
|
|
||||||
impit-win32-arm64-msvc: 0.7.6
|
|
||||||
impit-win32-x64-msvc: 0.7.6
|
|
||||||
|
|
||||||
inherits@2.0.4: {}
|
inherits@2.0.4: {}
|
||||||
|
|
||||||
ini@1.3.8: {}
|
ini@1.3.8: {}
|
||||||
|
|
||||||
is-obj@2.0.0: {}
|
|
||||||
|
|
||||||
is-potential-custom-element-name@1.0.1: {}
|
is-potential-custom-element-name@1.0.1: {}
|
||||||
|
|
||||||
is-standalone-pwa@0.1.1: {}
|
|
||||||
|
|
||||||
jsdom@24.1.3:
|
jsdom@24.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
cssstyle: 4.6.0
|
cssstyle: 4.6.0
|
||||||
@@ -1373,25 +1079,10 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
language-subtag-registry@0.3.23: {}
|
|
||||||
|
|
||||||
language-tags@2.1.0:
|
|
||||||
dependencies:
|
|
||||||
language-subtag-registry: 0.3.23
|
|
||||||
|
|
||||||
lodash.isequal@4.5.0: {}
|
|
||||||
|
|
||||||
lru-cache@10.4.3: {}
|
lru-cache@10.4.3: {}
|
||||||
|
|
||||||
lru-cache@11.2.4: {}
|
|
||||||
|
|
||||||
math-intrinsics@1.1.0: {}
|
math-intrinsics@1.1.0: {}
|
||||||
|
|
||||||
maxmind@5.0.3:
|
|
||||||
dependencies:
|
|
||||||
mmdb-lib: 3.0.1
|
|
||||||
tiny-lru: 11.4.5
|
|
||||||
|
|
||||||
mime-db@1.52.0: {}
|
mime-db@1.52.0: {}
|
||||||
|
|
||||||
mime-types@2.1.35:
|
mime-types@2.1.35:
|
||||||
@@ -1400,17 +1091,18 @@ snapshots:
|
|||||||
|
|
||||||
mimic-response@3.1.0: {}
|
mimic-response@3.1.0: {}
|
||||||
|
|
||||||
minimatch@10.1.1:
|
|
||||||
dependencies:
|
|
||||||
'@isaacs/brace-expansion': 5.0.0
|
|
||||||
|
|
||||||
minimist@1.2.8: {}
|
minimist@1.2.8: {}
|
||||||
|
|
||||||
minipass@7.1.2: {}
|
minipass@7.1.2: {}
|
||||||
|
|
||||||
|
minizlib@3.1.0:
|
||||||
|
dependencies:
|
||||||
|
minipass: 7.1.2
|
||||||
|
|
||||||
mkdirp-classic@0.5.3: {}
|
mkdirp-classic@0.5.3: {}
|
||||||
|
|
||||||
mmdb-lib@3.0.1: {}
|
mmdb-lib@3.0.1:
|
||||||
|
optional: true
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
@@ -1420,43 +1112,18 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
semver: 7.7.3
|
semver: 7.7.3
|
||||||
|
|
||||||
node-releases@2.0.27: {}
|
|
||||||
|
|
||||||
nwsapi@2.2.23: {}
|
nwsapi@2.2.23: {}
|
||||||
|
|
||||||
once@1.4.0:
|
once@1.4.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
wrappy: 1.0.2
|
wrappy: 1.0.2
|
||||||
|
|
||||||
ow@0.28.2:
|
|
||||||
dependencies:
|
|
||||||
'@sindresorhus/is': 4.6.0
|
|
||||||
callsites: 3.1.0
|
|
||||||
dot-prop: 6.0.1
|
|
||||||
lodash.isequal: 4.5.0
|
|
||||||
vali-date: 1.0.0
|
|
||||||
|
|
||||||
parse5@7.3.0:
|
parse5@7.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
entities: 6.0.1
|
entities: 6.0.1
|
||||||
|
|
||||||
path-scurry@2.0.1:
|
|
||||||
dependencies:
|
|
||||||
lru-cache: 11.2.4
|
|
||||||
minipass: 7.1.2
|
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
|
||||||
|
|
||||||
playwright-core@1.57.0: {}
|
playwright-core@1.57.0: {}
|
||||||
|
|
||||||
playwright-core@1.58.2: {}
|
|
||||||
|
|
||||||
playwright@1.58.2:
|
|
||||||
dependencies:
|
|
||||||
playwright-core: 1.58.2
|
|
||||||
optionalDependencies:
|
|
||||||
fsevents: 2.3.2
|
|
||||||
|
|
||||||
prebuild-install@7.1.3:
|
prebuild-install@7.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-libc: 2.1.2
|
detect-libc: 2.1.2
|
||||||
@@ -1472,8 +1139,6 @@ snapshots:
|
|||||||
tar-fs: 2.1.4
|
tar-fs: 2.1.4
|
||||||
tunnel-agent: 0.6.0
|
tunnel-agent: 0.6.0
|
||||||
|
|
||||||
progress@2.0.3: {}
|
|
||||||
|
|
||||||
psl@1.15.0:
|
psl@1.15.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
@@ -1512,8 +1177,6 @@ snapshots:
|
|||||||
|
|
||||||
safer-buffer@2.1.2: {}
|
safer-buffer@2.1.2: {}
|
||||||
|
|
||||||
sax@1.4.4: {}
|
|
||||||
|
|
||||||
saxes@6.0.0:
|
saxes@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
xmlchars: 2.2.0
|
xmlchars: 2.2.0
|
||||||
@@ -1551,7 +1214,13 @@ snapshots:
|
|||||||
inherits: 2.0.4
|
inherits: 2.0.4
|
||||||
readable-stream: 3.6.2
|
readable-stream: 3.6.2
|
||||||
|
|
||||||
tiny-lru@11.4.5: {}
|
tar@7.5.11:
|
||||||
|
dependencies:
|
||||||
|
'@isaacs/fs-minipass': 4.0.1
|
||||||
|
chownr: 3.0.0
|
||||||
|
minipass: 7.1.2
|
||||||
|
minizlib: 3.1.0
|
||||||
|
yallist: 5.0.0
|
||||||
|
|
||||||
tough-cookie@4.1.4:
|
tough-cookie@4.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1564,8 +1233,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
tslib@2.8.1: {}
|
|
||||||
|
|
||||||
tsx@4.21.0:
|
tsx@4.21.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.27.0
|
esbuild: 0.27.0
|
||||||
@@ -1585,24 +1252,10 @@ snapshots:
|
|||||||
|
|
||||||
typescript@5.9.3: {}
|
typescript@5.9.3: {}
|
||||||
|
|
||||||
ua-is-frozen@0.1.2: {}
|
|
||||||
|
|
||||||
ua-parser-js@2.0.7:
|
|
||||||
dependencies:
|
|
||||||
detect-europe-js: 0.1.2
|
|
||||||
is-standalone-pwa: 0.1.1
|
|
||||||
ua-is-frozen: 0.1.2
|
|
||||||
|
|
||||||
undici-types@7.16.0: {}
|
undici-types@7.16.0: {}
|
||||||
|
|
||||||
universalify@0.2.0: {}
|
universalify@0.2.0: {}
|
||||||
|
|
||||||
update-browserslist-db@1.2.3(browserslist@4.28.1):
|
|
||||||
dependencies:
|
|
||||||
browserslist: 4.28.1
|
|
||||||
escalade: 3.2.0
|
|
||||||
picocolors: 1.1.1
|
|
||||||
|
|
||||||
url-parse@1.5.10:
|
url-parse@1.5.10:
|
||||||
dependencies:
|
dependencies:
|
||||||
querystringify: 2.2.0
|
querystringify: 2.2.0
|
||||||
@@ -1610,8 +1263,6 @@ snapshots:
|
|||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
vali-date@1.0.0: {}
|
|
||||||
|
|
||||||
w3c-xmlserializer@5.0.0:
|
w3c-xmlserializer@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
xml-name-validator: 5.0.0
|
xml-name-validator: 5.0.0
|
||||||
@@ -1635,11 +1286,6 @@ snapshots:
|
|||||||
|
|
||||||
xml-name-validator@5.0.0: {}
|
xml-name-validator@5.0.0: {}
|
||||||
|
|
||||||
xml2js@0.6.2:
|
|
||||||
dependencies:
|
|
||||||
sax: 1.4.4
|
|
||||||
xmlbuilder: 11.0.1
|
|
||||||
|
|
||||||
xmlbuilder@11.0.1: {}
|
|
||||||
|
|
||||||
xmlchars@2.2.0: {}
|
xmlchars@2.2.0: {}
|
||||||
|
|
||||||
|
yallist@5.0.0: {}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { getPage } from './browse.js';
|
|||||||
|
|
||||||
const baseUrl = 'http://localhost:3000';
|
const baseUrl = 'http://localhost:3000';
|
||||||
const username = 'analyst@fhb.local';
|
const username = 'analyst@fhb.local';
|
||||||
const password = process.env.CAMOUFOX_PASSWORD ?? '';
|
const password = process.env.CLOAKBROWSER_PASSWORD ?? '';
|
||||||
|
|
||||||
const reportPath = '/Users/stefano.fiorini/Documents/projects/fhb-loan-spreading-pilot-a/docs/plans/2026-01-24-financials-analysis-redesign/web-automation-scan.md';
|
const reportPath = '/Users/stefano.fiorini/Documents/projects/fhb-loan-spreading-pilot-a/docs/plans/2026-01-24-financials-analysis-redesign/web-automation-scan.md';
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
import { Camoufox } from 'camoufox-js';
|
import { launchPersistentContext } from 'cloakbrowser';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { mkdirSync, existsSync } from 'fs';
|
import { mkdirSync, existsSync } from 'fs';
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
const profilePath = join(homedir(), '.camoufox-profile');
|
const profilePath = join(homedir(), '.cloakbrowser-profile');
|
||||||
if (!existsSync(profilePath)) {
|
if (!existsSync(profilePath)) {
|
||||||
mkdirSync(profilePath, { recursive: true });
|
mkdirSync(profilePath, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Profile path:', profilePath);
|
console.log('Profile path:', profilePath);
|
||||||
console.log('Launching with full options...');
|
console.log('Launching CloakBrowser with full options...');
|
||||||
|
|
||||||
const browser = await Camoufox({
|
const browser = await launchPersistentContext({
|
||||||
headless: true,
|
headless: true,
|
||||||
user_data_dir: profilePath,
|
userDataDir: profilePath,
|
||||||
// humanize: 1.5, // Test without this first
|
humanize: true,
|
||||||
// geoip: true, // Test without this first
|
|
||||||
// enable_cache: true,
|
|
||||||
// block_webrtc: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Browser launched');
|
console.log('Browser launched');
|
||||||
const page = await browser.newPage();
|
const page = browser.pages()[0] || await browser.newPage();
|
||||||
console.log('Page created');
|
console.log('Page created');
|
||||||
|
|
||||||
await page.goto('https://github.com', { timeout: 30000 });
|
await page.goto('https://github.com', { timeout: 30000 });
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { Camoufox } from 'camoufox-js';
|
import { launch } from 'cloakbrowser';
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
console.log('Launching Camoufox with minimal config...');
|
console.log('Launching CloakBrowser with minimal config...');
|
||||||
|
|
||||||
const browser = await Camoufox({
|
const browser = await launch({
|
||||||
headless: true,
|
headless: true,
|
||||||
|
humanize: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Browser launched');
|
console.log('Browser launched');
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
import { Camoufox } from 'camoufox-js';
|
import { launchPersistentContext } from 'cloakbrowser';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { mkdirSync, existsSync } from 'fs';
|
import { mkdirSync, existsSync } from 'fs';
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
const profilePath = join(homedir(), '.camoufox-profile');
|
const profilePath = join(homedir(), '.cloakbrowser-profile');
|
||||||
if (!existsSync(profilePath)) {
|
if (!existsSync(profilePath)) {
|
||||||
mkdirSync(profilePath, { recursive: true });
|
mkdirSync(profilePath, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Profile path:', profilePath);
|
console.log('Profile path:', profilePath);
|
||||||
console.log('Launching with user_data_dir...');
|
console.log('Launching with persistent userDataDir...');
|
||||||
|
|
||||||
const browser = await Camoufox({
|
const browser = await launchPersistentContext({
|
||||||
headless: true,
|
headless: true,
|
||||||
user_data_dir: profilePath,
|
userDataDir: profilePath,
|
||||||
|
humanize: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Browser launched');
|
console.log('Browser launched');
|
||||||
const page = await browser.newPage();
|
const page = browser.pages()[0] || await browser.newPage();
|
||||||
console.log('Page created');
|
console.log('Page created');
|
||||||
|
|
||||||
await page.goto('https://example.com', { timeout: 30000 });
|
await page.goto('https://example.com', { timeout: 30000 });
|
||||||
|
|||||||
Reference in New Issue
Block a user