diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 690c1e4..b9cf01b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,13 +57,13 @@ jobs: node-version: '20' - name: Install ai-agent dependencies run: npm ci - working-directory: ai-agent/pardus-browser + working-directory: ai-agent/open-browser - name: Typecheck ai-agent run: npm run lint - working-directory: ai-agent/pardus-browser + working-directory: ai-agent/open-browser - name: Test ai-agent run: npm test - working-directory: ai-agent/pardus-browser + working-directory: ai-agent/open-browser security-audit: name: security audit diff --git a/.gitignore b/.gitignore index adb3732..7a45144 100644 --- a/.gitignore +++ b/.gitignore @@ -5,28 +5,28 @@ **/.DS_Store # Adapter build artifacts -adapters/python/pardus-playwright/*.egg-info/ -adapters/python/pardus-playwright/__pycache__/ -adapters/python/pardus-playwright/build/ -adapters/python/pardus-playwright/dist/ -adapters/node/pardus-puppeteer/node_modules/ -adapters/node/pardus-puppeteer/dist/ -adapters/node/pardus-playwright/node_modules/ -adapters/node/pardus-playwright/dist/ +adapters/python/open-playwright/*.egg-info/ +adapters/python/open-playwright/__pycache__/ +adapters/python/open-playwright/build/ +adapters/python/open-playwright/dist/ +adapters/node/open-puppeteer/node_modules/ +adapters/node/open-puppeteer/dist/ +adapters/node/open-playwright/node_modules/ +adapters/node/open-playwright/dist/ # Tauri frontend -crates/pardus-tauri/node_modules/ -crates/pardus-tauri/frontend/node_modules/ -crates/pardus-tauri/dist/ -crates/pardus-tauri/frontend/dist/ +crates/open-tauri/node_modules/ +crates/open-tauri/frontend/node_modules/ +crates/open-tauri/dist/ +crates/open-tauri/frontend/dist/ # Web dashboard web/node_modules/ web/dist/ # AI agent -ai-agent/pardus-browser/node_modules/ -ai-agent/pardus-browser/dist/ +ai-agent/open-browser/node_modules/ +ai-agent/open-browser/dist/ # Lockfiles (committed for reproducibility) # If you need to regenerate: rm **/package-lock.json && npm install diff --git a/.opencode/plans/pardus-kg-optimization.md b/.opencode/plans/pardus-kg-optimization.md deleted file mode 100644 index c3f0dc0..0000000 --- a/.opencode/plans/pardus-kg-optimization.md +++ /dev/null @@ -1,142 +0,0 @@ -# pardus-kg Optimization Plan - -## Pre-requisite Fix (unrelated pre-existing bug) - -**File:** `crates/pardus-core/src/page.rs:783-791` - -The `snapshot()` method is missing the `redirect_chain` field, causing compilation failure. - -```rust -pub fn snapshot(&self) -> PageSnapshot { - PageSnapshot { - url: self.url.clone(), - status: self.status, - content_type: self.content_type.clone(), - title: self.title(), - html: self.html.html(), - redirect_chain: self.redirect_chain.clone(), - } -} -``` - ---- - -## Phase 1: Bug Fixes (B1-B4) - -### B1. Fix query param sorting in `normalize_url` - -**File:** `crates/pardus-kg/src/crawler.rs:224-234` - -Docstring says "sort query params" but code doesn't sort. Sort query pairs before rebuilding URL string. - -### B2. Fix `Box::leak` memory leak in pagination - -**File:** `crates/pardus-kg/src/discovery.rs:139,146` - -Change `segments` from `Vec<&str>` to `Vec` and use local `String` instead of `Box::leak`. - -### B3. Fix duplicate `navigation_graph()` call - -**File:** `crates/pardus-kg/src/crawler.rs:176-221` - -Pass pre-built `nav_graph` into `discover_transitions_for_page` instead of rebuilding inside. - -### B4. Fix same-origin filtering at frontier insertion - -**File:** `crates/pardus-kg/src/crawler.rs:237-239` - -Replace unused `_root_origin` param with actual same-origin check. Skip cross-origin URLs before enqueueing. - ---- - -## Phase 2: Quick Wins (H4, M1) - -### H4. Incremental blake3 hashing - -**File:** `crates/pardus-kg/src/fingerprint.rs` - -Replace 3 functions (`hash_tree_structure`, `hash_resource_set`, `compute_view_state_id`) to use `blake3::Hasher::new()` + incremental `update()` calls instead of building large intermediate strings. - -### M1. Remove duplicate `role_str` function - -**File:** `crates/pardus-kg/src/fingerprint.rs:88-122` - -Delete the local `role_str()` that allocates `String` per call. Use `node.role.role_str()` which already exists on `SemanticRole` in pardus-core and returns `&str`. - ---- - -## Phase 3: Parallel Fetch (H1) - -**File:** `crates/pardus-kg/src/crawler.rs` - -- Add `concurrency: usize` field to `CrawlConfig` (default: 4) -- Add `tokio/sync` and `tokio/rt` features to `Cargo.toml` -- Replace serial BFS loop with batched parallel fetch using `tokio::task::JoinSet` + `tokio::sync::Semaphore` -- Result processing stays serial to maintain BFS ordering and safe `HashMap` mutation -- Parallelism is I/O-bound fetch only; semantic tree building stays in collection loop - ---- - -## Phase 4: Single-Pass HTML (H3) - -### New unified analysis API - -**New file:** `crates/pardus-core/src/page_analysis.rs` - -Create `PageAnalysis` struct with `build(html, page_url)` that produces both `SemanticTree` and `NavigationGraph` through a single API call. Initially delegates to individual builders; evolved later into true single-pass. - ---- - -## Phase 5: Memory Optimization (M2-M4, L1, L3) - -### M2. Optional tree storage - -- Add `store_full_trees: bool` to `CrawlConfig` -- Make `semantic_tree` and `navigation_graph` `Option` on `ViewState` -- Skip serializing when `None` - -### M3. Type-safe HashMap keys - -**File:** `crates/pardus-kg/src/graph.rs` - -Change `states: HashMap` to `HashMap`. Update `add_state` and `has_state` accordingly. Update all callers. - -### M4. HashSet for resources - -Change `resource_urls: BTreeSet` to `HashSet` across state.rs and fingerprint.rs. Sort only when hashing. - -### L1. Remove dead `verify_transitions` config - -Remove the unused field from `CrawlConfig`. - -### L3. Crawler-level retry - -Add `retries: u8` to `FrontierEntry`. On fetch failure, re-enqueue up to 2 retries. - ---- - -## File Change Summary - -| Order | File | Changes | -|-------|------|---------| -| 0 | `pardus-core/src/page.rs` | Fix missing `redirect_chain` in `snapshot()` | -| 1 | `pardus-kg/src/discovery.rs` | B2: Fix `Box::leak` | -| 1 | `pardus-kg/src/crawler.rs` | B1: query param sort; B3: pass nav_graph; B4: same-origin filter | -| 2 | `pardus-kg/src/fingerprint.rs` | H4: incremental blake3; M1: remove role_str; M4: HashSet | -| 3 | `pardus-kg/src/crawler.rs` | H1: parallel fetch | -| 3 | `pardus-kg/src/config.rs` | Add `concurrency` | -| 3 | `pardus-kg/Cargo.toml` | Add tokio features | -| 4 | `pardus-core/src/page_analysis.rs` | New file: unified PageAnalysis | -| 4 | `pardus-kg/src/crawler.rs` | Use PageAnalysis | -| 5 | `pardus-kg/src/graph.rs` | M3: HashMap key type | -| 5 | `pardus-kg/src/state.rs` | M2: optional trees; M4: HashSet | -| 5 | `pardus-kg/src/config.rs` | L1: remove dead field; add store_full_trees | - -## Verification - -```bash -cargo test -p pardus-kg -cargo test -p pardus-core -cargo clippy -p pardus-kg -- -D warnings -cargo build -p pardus-kg -``` diff --git a/CHANGELOG.md b/CHANGELOG.md index bb039b0..a5e99c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ### v0.4.0 — WebSocket Full Implementation **WebSocket Support:** -- Added `WebSocketConnection` module (`crates/pardus-core/src/websocket/connection.rs`) +- Added `WebSocketConnection` module (`crates/open-core/src/websocket/connection.rs`) - Async connect with configurable timeout - `send_text()`, `send_binary()` for outgoing messages - `recv()` returns `(WebSocketFrame, Vec)` for incoming messages @@ -11,7 +11,7 @@ - Connection statistics tracking (frames sent/received, bytes) - Unique connection ID generation via URL hashing -- Added `WebSocketManager` module (`crates/pardus-core/src/websocket/manager.rs`) +- Added `WebSocketManager` module (`crates/open-core/src/websocket/manager.rs`) - Connection pooling with per-origin limits (`max_per_origin`) - Configurable security policy (`block_private_ips`, `block_loopback`) - CDP event bus integration for real-time notifications @@ -32,7 +32,7 @@ - Blocks cloud metadata: metadata.google.internal, 169.254.169.254, 100.100.100.200 - Blocks localhost hostname -- Added `ResourceType::WebSocket` to `pardus-debug` crate +- Added `ResourceType::WebSocket` to `open-debug` crate - Dependencies added: - `tokio-tungstenite = "0.26"` — Async WebSocket client @@ -149,7 +149,7 @@ **CDP Network (Cookies):** - Implemented `Network.getCookies` / `Network.getAllCookies` — extracts cookies from network log Set-Cookie headers with full attribute parsing (domain, path, httpOnly, secure, sameSite, size) - Implemented `Network.setCookie`, `Network.deleteCookies`, `Network.clearBrowserCookies` -- Added `url` crate dependency to pardus-cdp for URL parsing in cookie operations +- Added `url` crate dependency to open-cdp for URL parsing in cookie operations **Cookie System (SessionStore):** - Fixed cookie parsing bug: removed incorrect `split(';')` on Set-Cookie header values @@ -159,7 +159,7 @@ - Added `session_dir()` public accessor to SessionStore **Performance:** -- Removed unnecessary HTML re-parsing in Pardus domain click handler (reuse `page_data` result) +- Removed unnecessary HTML re-parsing in Open domain click handler (reuse `page_data` result) - Removed dead HTML clone in `RuntimeDomain::evaluate_expression` - Fixed tab loading to use browser's actual `BrowserConfig` instead of hardcoded default - POST form submissions now recorded in NetworkLog diff --git a/Cargo.lock b/Cargo.lock index 05e51fd..a7adabf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4091,7 +4091,7 @@ dependencies = [ ] [[package]] -name = "pardus-cdp" +name = "open-cdp" version = "0.1.0" dependencies = [ "anyhow", @@ -4100,8 +4100,8 @@ dependencies = [ "chrono", "futures-util", "mockito", - "pardus-core", - "pardus-debug", + "open-core", + "open-debug", "parking_lot", "rquest", "scraper", @@ -4116,27 +4116,27 @@ dependencies = [ ] [[package]] -name = "pardus-challenge" +name = "open-challenge" version = "0.1.0" dependencies = [ "async-trait", - "pardus-core", + "open-core", "serde", "tokio", "tracing", ] [[package]] -name = "pardus-cli" +name = "open-cli" version = "0.1.0" dependencies = [ "anyhow", "clap", "dirs", - "pardus-cdp", - "pardus-core", - "pardus-debug", - "pardus-kg", + "open-cdp", + "open-core", + "open-debug", + "open-kg", "rustyline", "serde_json", "shell-words", @@ -4146,7 +4146,7 @@ dependencies = [ ] [[package]] -name = "pardus-core" +name = "open-core" version = "0.1.0" dependencies = [ "anyhow", @@ -4173,7 +4173,7 @@ dependencies = [ "lopdf 0.39.0", "lru 0.12.5", "mime_guess", - "pardus-debug", + "open-debug", "parking_lot", "pdf-extract", "regex", @@ -4197,7 +4197,7 @@ dependencies = [ ] [[package]] -name = "pardus-debug" +name = "open-debug" version = "0.1.0" dependencies = [ "chrono", @@ -4211,15 +4211,15 @@ dependencies = [ ] [[package]] -name = "pardus-kg" +name = "open-kg" version = "0.1.0" dependencies = [ "anyhow", "blake3", "chrono", "futures", - "pardus-core", - "pardus-debug", + "open-core", + "open-debug", "scraper", "serde", "serde_json", @@ -4229,7 +4229,7 @@ dependencies = [ ] [[package]] -name = "pardus-server" +name = "open-server" version = "0.1.0" dependencies = [ "anyhow", @@ -4237,8 +4237,8 @@ dependencies = [ "clap", "futures-util", "include_dir", - "pardus-core", - "pardus-debug", + "open-core", + "open-debug", "serde", "serde_json", "tokio", @@ -4249,16 +4249,16 @@ dependencies = [ ] [[package]] -name = "pardus-tauri" +name = "open-tauri" version = "0.1.0" dependencies = [ "anyhow", "async-trait", "chrono", "futures-util", - "pardus-cdp", - "pardus-challenge", - "pardus-core", + "open-cdp", + "open-challenge", + "open-core", "serde", "serde_json", "tauri", diff --git a/Cargo.toml b/Cargo.toml index 1699549..8bd0dd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [workspace] members = [ - "crates/pardus-core", - "crates/pardus-cdp", - "crates/pardus-challenge", - "crates/pardus-cli", - "crates/pardus-debug", - "crates/pardus-kg", - "crates/pardus-server", - "crates/pardus-tauri/src-tauri", + "crates/open-core", + "crates/open-cdp", + "crates/open-challenge", + "crates/open-cli", + "crates/open-debug", + "crates/open-kg", + "crates/open-server", + "crates/open-tauri/src-tauri", ] resolver = "2" diff --git a/Dockerfile b/Dockerfile index 39c4650..f6e11ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,24 +19,24 @@ WORKDIR /app # Cache dependencies COPY Cargo.toml Cargo.lock* ./ -COPY crates/pardus-core/Cargo.toml crates/pardus-core/Cargo.toml -COPY crates/pardus-cli/Cargo.toml crates/pardus-cli/Cargo.toml -COPY crates/pardus-debug/Cargo.toml crates/pardus-debug/Cargo.toml -COPY crates/pardus-cdp/Cargo.toml crates/pardus-cdp/Cargo.toml -COPY crates/pardus-kg/Cargo.toml crates/pardus-kg/Cargo.toml +COPY crates/open-core/Cargo.toml crates/open-core/Cargo.toml +COPY crates/open-cli/Cargo.toml crates/open-cli/Cargo.toml +COPY crates/open-debug/Cargo.toml crates/open-debug/Cargo.toml +COPY crates/open-cdp/Cargo.toml crates/open-cdp/Cargo.toml +COPY crates/open-kg/Cargo.toml crates/open-kg/Cargo.toml -RUN mkdir -p crates/pardus-core/src && echo "" > crates/pardus-core/src/lib.rs && \ - mkdir -p crates/pardus-cli/src && echo "fn main() {}" > crates/pardus-cli/src/main.rs && \ - mkdir -p crates/pardus-debug/src && echo "" > crates/pardus-debug/src/lib.rs && \ - mkdir -p crates/pardus-cdp/src && echo "" > crates/pardus-cdp/src/lib.rs && \ - mkdir -p crates/pardus-kg/src && echo "" > crates/pardus-kg/src/lib.rs +RUN mkdir -p crates/open-core/src && echo "" > crates/open-core/src/lib.rs && \ + mkdir -p crates/open-cli/src && echo "fn main() {}" > crates/open-cli/src/main.rs && \ + mkdir -p crates/open-debug/src && echo "" > crates/open-debug/src/lib.rs && \ + mkdir -p crates/open-cdp/src && echo "" > crates/open-cdp/src/lib.rs && \ + mkdir -p crates/open-kg/src && echo "" > crates/open-kg/src/lib.rs RUN cargo +nightly build --release 2>/dev/null || true COPY . . -RUN touch crates/pardus-core/src/lib.rs crates/pardus-cli/src/main.rs \ - crates/pardus-debug/src/lib.rs crates/pardus-cdp/src/lib.rs crates/pardus-kg/src/lib.rs -RUN cargo +nightly build --release --bin pardus-browser +RUN touch crates/open-core/src/lib.rs crates/open-cli/src/main.rs \ + crates/open-debug/src/lib.rs crates/open-cdp/src/lib.rs crates/open-kg/src/lib.rs +RUN cargo +nightly build --release --bin open-browser # ── Runtime stage ──────────────────────────────────────────────────────────── FROM debian:bookworm-slim @@ -47,12 +47,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libstdc++6 \ curl \ && rm -rf /var/lib/apt/lists/* \ - && groupadd --gid 1000 pardus \ - && useradd --uid 1000 --gid pardus --create-home pardus + && groupadd --gid 1000 open \ + && useradd --uid 1000 --gid open --create-home open -WORKDIR /home/pardus +WORKDIR /home/open -COPY --from=builder /app/target/release/pardus-browser /usr/local/bin/pardus-browser +COPY --from=builder /app/target/release/open-browser /usr/local/bin/open-browser # CDP server port EXPOSE 9222 @@ -61,8 +61,8 @@ EXPOSE 9222 HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD curl -sf http://127.0.0.1:${PORT:-9222}/json/version || exit 1 -USER pardus +USER open # Default: start CDP server bound to all interfaces. Override with `docker run ... [args]` -ENTRYPOINT ["pardus-browser"] +ENTRYPOINT ["open-browser"] CMD ["serve", "--host", "0.0.0.0"] diff --git a/README.md b/README.md index 9925af9..a8b372c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# pardus-browser +# open-browser A headless browser built for AI agents. No pixels, no screenshots — just structured semantic state. ``` -$ pardus-browser navigate https://example.com +$ open-browser navigate https://example.com -00:00 pardus-browser navigate https://example.com +00:00 open-browser navigate https://example.com 00:05 connected — parsing semantic state… document [role: document] └── region [role: region] @@ -19,7 +19,7 @@ $ pardus-browser navigate https://example.com ## Why -AI agents don't need screenshots. They need to know what's on a page, what they can interact with, and where they can go. `pardus-browser` fetches a URL, parses the HTML, and outputs a clean semantic tree — landmarks, headings, links, buttons, forms, and their actions — in milliseconds, not seconds. +AI agents don't need screenshots. They need to know what's on a page, what they can interact with, and where they can go. `open-browser` fetches a URL, parses the HTML, and outputs a clean semantic tree — landmarks, headings, links, buttons, forms, and their actions — in milliseconds, not seconds. No Chromium binary. No Docker. No GPU. Just HTTP + HTML parsing. @@ -52,16 +52,16 @@ From source (requires Rust nightly): rustup install nightly # Clone and build -git clone https://github.com/user/pardus-browser.git -cd pardus-browser -cargo +nightly install --path crates/pardus-cli --features js +git clone https://github.com/user/open-browser.git +cd open-browser +cargo +nightly install --path crates/open-cli --features js ``` ### Docker ```bash -docker build -t pardus-browser . -docker run --rm pardus-browser navigate https://example.com +docker build -t open-browser . +docker run --rm open-browser navigate https://example.com ``` ## Usage @@ -70,34 +70,34 @@ docker run --rm pardus-browser navigate https://example.com ```bash # Default: Markdown tree -pardus-browser navigate https://example.com +open-browser navigate https://example.com # Raw tree format -pardus-browser navigate https://example.com --format tree +open-browser navigate https://example.com --format tree # JSON with navigation graph -pardus-browser navigate https://example.com --format json --with-nav +open-browser navigate https://example.com --format json --with-nav # Only interactive elements -pardus-browser navigate https://example.com --interactive-only +open-browser navigate https://example.com --interactive-only # Custom headers -pardus-browser navigate https://api.example.com --header "Authorization: Bearer token" +open-browser navigate https://api.example.com --header "Authorization: Bearer token" # Enable JavaScript execution (improved — problematic scripts are now filtered) -pardus-browser navigate https://example.com --js +open-browser navigate https://example.com --js # JS with custom wait time (ms) for async rendering -pardus-browser navigate https://example.com --js --wait-ms 5000 +open-browser navigate https://example.com --js --wait-ms 5000 # Verbose logging -pardus-browser navigate https://example.com -v +open-browser navigate https://example.com -v # Capture and display network request table -pardus-browser navigate https://example.com --network-log +open-browser navigate https://example.com --network-log # Network log with JSON output -pardus-browser navigate https://example.com --format json --network-log +open-browser navigate https://example.com --format json --network-log ``` ### PDF viewing @@ -105,11 +105,11 @@ pardus-browser navigate https://example.com --format json --network-log Navigate to a PDF URL the same way you'd navigate to an HTML page. The browser detects `application/pdf` responses, extracts text per-page, and builds a semantic tree with heading detection. ```bash -pardus-browser navigate https://example.com/report.pdf +open-browser navigate https://example.com/report.pdf ``` ``` -00:00 pardus-browser navigate https://example.com/report.pdf +00:00 open-browser navigate https://example.com/report.pdf 00:01 connected — parsing semantic state… document "Annual Report 2026" [role: document] ├── heading (h1) "Annual Report 2026" @@ -125,10 +125,10 @@ Works with all output formats and subcommands: ```bash # JSON output -pardus-browser navigate https://example.com/report.pdf --format json +open-browser navigate https://example.com/report.pdf --format json # Tree format -pardus-browser navigate https://example.com/report.pdf --format tree +open-browser navigate https://example.com/report.pdf --format tree ``` **How it works:** @@ -167,7 +167,7 @@ Each interactive element has a unique ID in brackets (`[#1]`, `[#2]`, etc.) that **JSON** — structured data with full navigation graph: ```bash -pardus-browser navigate https://example.com --format json --with-nav +open-browser navigate https://example.com --format json --with-nav ``` Returns: @@ -219,11 +219,11 @@ Returns: Capture and display all network requests in a DevTools-style table: ```bash -pardus-browser navigate https://example.com --network-log +open-browser navigate https://example.com --network-log ``` ``` -00:00 pardus-browser navigate https://example.com +00:00 open-browser navigate https://example.com 00:00 connected — parsing semantic state… # Network — 4 requests — 4.6 KB — 312ms total @@ -249,16 +249,16 @@ Start a Chrome DevTools Protocol WebSocket server for automation: ```bash # Start on default host/port -pardus-browser serve +open-browser serve # Custom host and port -pardus-browser serve --host 0.0.0.0 --port 9222 +open-browser serve --host 0.0.0.0 --port 9222 # With inactivity timeout -pardus-browser serve --timeout 60 +open-browser serve --timeout 60 ``` -Implemented CDP domains: Browser, Target, Page, Runtime, DOM, Network, Emulation, Input, CSS, Log, Console, Security, Performance, Pardus (custom extensions) +Implemented CDP domains: Browser, Target, Page, Runtime, DOM, Network, Emulation, Input, CSS, Log, Console, Security, Performance, Open (custom extensions) ### Knowledge Graph (site mapping) @@ -266,19 +266,19 @@ Map a site's functional structure into a deterministic state graph. Nodes are vi ```bash # Map a site (default: depth 3, max 50 pages) -pardus-browser map https://example.com --output kg.json +open-browser map https://example.com --output kg.json # Shallow crawl -pardus-browser map https://example.com --depth 1 --output kg.json +open-browser map https://example.com --depth 1 --output kg.json # Deep crawl with higher page limit -pardus-browser map https://example.com --depth 5 --max-pages 200 --output kg.json +open-browser map https://example.com --depth 5 --max-pages 200 --output kg.json # Skip pagination discovery (only follow links) -pardus-browser map https://example.com --output kg.json --no-pagination +open-browser map https://example.com --output kg.json --no-pagination # Verbose logging -pardus-browser map https://example.com -v --output kg.json +open-browser map https://example.com -v --output kg.json ``` **Output** — JSON with all view-states, transitions, and stats: @@ -347,35 +347,35 @@ pardus-browser map https://example.com -v --output kg.json ```bash # Wipe everything -pardus-browser clean +open-browser clean # Only cookies -pardus-browser clean --cookies-only +open-browser clean --cookies-only # Only cache -pardus-browser clean --cache-only +open-browser clean --cache-only # Custom cache directory -pardus-browser clean --cache-dir /path/to/cache +open-browser clean --cache-dir /path/to/cache ``` ### Tab management ```bash # Open a new tab (fetches page and shows summary) -pardus-browser tab open https://example.com +open-browser tab open https://example.com # Open with JS execution -pardus-browser tab open https://example.com --js +open-browser tab open https://example.com --js # List all open tabs -pardus-browser tab list +open-browser tab list # Show active tab info -pardus-browser tab info +open-browser tab info # Navigate the active tab -pardus-browser tab navigate https://example.com/page2 +open-browser tab navigate https://example.com/page2 ``` **Note:** Tab state does not persist across CLI invocations. For persistent tab sessions, use the REPL or the CDP server. @@ -386,41 +386,41 @@ Start a persistent interactive session where browser state (tabs, pages, cookies ```bash # Start REPL with defaults -pardus-browser repl +open-browser repl # Enable JS execution by default -pardus-browser repl --js +open-browser repl --js # Set default output format and JS wait time -pardus-browser repl --format json --wait-ms 5000 +open-browser repl --format json --wait-ms 5000 ``` Once inside the REPL, the prompt shows the current URL context: ``` -pardus> visit https://example.com +open> visit https://example.com document [role: document] └── region [role: region] ├── heading (h1) "Example Domain" └── link "Learn more" → https://iana.org/domains/example 0 landmarks, 1 links, 1 headings, 1 actions -pardus [https://example.com]> tab open https://httpbin.org +open [https://example.com]> tab open https://httpbin.org Opened tab 2: httpbin.org -pardus [https://httpbin.org]> tab list +open [https://httpbin.org]> tab list Tabs (2 total): * [2] Ready — httpbin.org — https://httpbin.org [1] Ready — Example Domain — https://example.com -pardus [https://httpbin.org]> tab switch 1 +open [https://httpbin.org]> tab switch 1 Switched to tab 1: https://example.com -pardus [https://example.com]> click 'a' +open [https://example.com]> click 'a' Navigated to: https://iana.org/domains/example -pardus [https://iana.org/domains/example]> back -pardus [https://example.com]> exit +open [https://iana.org/domains/example]> back +open [https://example.com]> exit Bye. ``` @@ -450,7 +450,7 @@ Bye. The `Browser` type unifies navigation, interaction, and tab management into a single API: ```rust -use pardus_core::Browser; +use open_core::Browser; let mut browser = Browser::new(BrowserConfig::default()); @@ -489,34 +489,34 @@ Interact with pages using the `interact` subcommand. Works at the HTTP level — ```bash # Click a link — follows href, returns new page -pardus-browser interact https://example.com click 'a' +open-browser interact https://example.com click 'a' # Click by element ID — easier for AI agents -pardus-browser interact https://example.com click-id 1 +open-browser interact https://example.com click-id 1 # Click a submit button — finds enclosing form, submits it -pardus-browser interact https://example.com click 'button[type="submit"]' +open-browser interact https://example.com click 'button[type="submit"]' # Type into a field (returns the field state) -pardus-browser interact https://example.com type 'input[name="q"]' 'search query' +open-browser interact https://example.com type 'input[name="q"]' 'search query' # Type by element ID — easier for AI agents -pardus-browser interact https://example.com type-id 3 'search query' +open-browser interact https://example.com type-id 3 'search query' # Submit a form with field values -pardus-browser interact https://example.com submit 'form' --field 'q=rust+language' +open-browser interact https://example.com submit 'form' --field 'q=rust+language' # Wait for a CSS selector to appear (with timeout) -pardus-browser interact https://example.com wait '.result-list' --timeout-ms 5000 +open-browser interact https://example.com wait '.result-list' --timeout-ms 5000 # Scroll — detects URL pagination (?page=, ?offset=, /page/N) -pardus-browser interact 'https://example.com/news?page=1' scroll --direction down +open-browser interact 'https://example.com/news?page=1' scroll --direction down # JSON output for the result page -pardus-browser interact https://example.com click 'a' --format json +open-browser interact https://example.com click 'a' --format json # Enable JS execution before interaction -pardus-browser interact https://example.com wait '.dynamic-content' --js --wait-ms 3000 +open-browser interact https://example.com wait '.dynamic-content' --js --wait-ms 3000 ``` **How interactions work:** @@ -533,23 +533,23 @@ pardus-browser interact https://example.com wait '.dynamic-content' --js --wait- ## Architecture ``` -pardus-browser -├── crates/pardus-core Core library — Browser type, HTML parsing, semantic tree, navigation graph, interaction, tabs -├── crates/pardus-debug Network debugger — request recording, subresource discovery, table output -├── crates/pardus-cdp CDP WebSocket server — Chrome DevTools Protocol for automation (14 domains) -├── crates/pardus-kg Knowledge Graph — BFS site crawler, state fingerprinting, transition discovery -└── crates/pardus-cli CLI binary +open-browser +├── crates/open-core Core library — Browser type, HTML parsing, semantic tree, navigation graph, interaction, tabs +├── crates/open-debug Network debugger — request recording, subresource discovery, table output +├── crates/open-cdp CDP WebSocket server — Chrome DevTools Protocol for automation (14 domains) +├── crates/open-kg Knowledge Graph — BFS site crawler, state fingerprinting, transition discovery +└── crates/open-cli CLI binary ``` -**pardus-core** — The engine. The `Browser` type is the main entry point — it owns the HTTP client, tab state, and provides navigation + interaction as a single cohesive API. Internally, it fetches pages via `reqwest`, parses HTML with `scraper`, and builds semantic trees mapping ARIA roles and interactive states. PDF URLs are detected by content-type and extracted into semantic trees via `pdf-extract`. Provides page interaction (click, type, submit, wait, scroll) with automatic tab updates on navigation. Includes tab management, history navigation, session persistence (cookies, headers, localStorage), and optional JavaScript execution via deno_core (enabled by default). Outputs Markdown, tree, or JSON. +**open-core** — The engine. The `Browser` type is the main entry point — it owns the HTTP client, tab state, and provides navigation + interaction as a single cohesive API. Internally, it fetches pages via `reqwest`, parses HTML with `scraper`, and builds semantic trees mapping ARIA roles and interactive states. PDF URLs are detected by content-type and extracted into semantic trees via `pdf-extract`. Provides page interaction (click, type, submit, wait, scroll) with automatic tab updates on navigation. Includes tab management, history navigation, session persistence (cookies, headers, localStorage), and optional JavaScript execution via deno_core (enabled by default). Outputs Markdown, tree, or JSON. -**pardus-debug** — Network debugging. Records all HTTP requests to a shared `NetworkLog`, discovers subresources from parsed HTML (stylesheets, scripts, images, fonts, media), fetches them in parallel, and formats DevTools-style request tables. +**open-debug** — Network debugging. Records all HTTP requests to a shared `NetworkLog`, discovers subresources from parsed HTML (stylesheets, scripts, images, fonts, media), fetches them in parallel, and formats DevTools-style request tables. -**pardus-cdp** — Chrome DevTools Protocol server. Exposes a WebSocket endpoint for browser automation with 14 domain handlers (Browser, Target, Page, Runtime, DOM, Network, Emulation, Input, CSS, Log, Console, Security, Performance, Pardus). Includes event bus, target management, message routing, and session lifecycle. +**open-cdp** — Chrome DevTools Protocol server. Exposes a WebSocket endpoint for browser automation with 14 domain handlers (Browser, Target, Page, Runtime, DOM, Network, Emulation, Input, CSS, Log, Console, Security, Performance, Open). Includes event bus, target management, message routing, and session lifecycle. -**pardus-kg** — Knowledge Graph. BFS site crawler that builds a deterministic state map: nodes are view-states identified by composite fingerprints (semantic tree structure hash + resource URL set hash + normalized URL), edges are verified transitions (link clicks, hash navigation, pagination). Produces a JSON graph suitable for AI agent consumption — an agent can query the graph to understand what states exist and how to reach them without trial-and-error navigation. +**open-kg** — Knowledge Graph. BFS site crawler that builds a deterministic state map: nodes are view-states identified by composite fingerprints (semantic tree structure hash + resource URL set hash + normalized URL), edges are verified transitions (link clicks, hash navigation, pagination). Produces a JSON graph suitable for AI agent consumption — an agent can query the graph to understand what states exist and how to reach them without trial-and-error navigation. -**pardus-cli** — The `pardus-browser` command-line tool. Provides `navigate`, `interact`, `map`, `tab`, `serve`, `repl`, and `clean` subcommands. All commands use the unified `Browser` type. +**open-cli** — The `open-browser` command-line tool. Provides `navigate`, `interact`, `map`, `tab`, `serve`, `repl`, and `clean` subcommands. All commands use the unified `Browser` type. ## Semantic roles detected diff --git a/ROADMAP.md b/ROADMAP.md index b1bc7db..b086bf4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,4 +1,4 @@ -# Pardus Browser Roadmap +# Open Browser Roadmap **Version:** 0.4.0-dev | **Branch:** dev/roadmap | **Updated:** April 4, 2026 @@ -20,7 +20,7 @@ Core engine, CLI, and all major subsystems are stable. Summary of shipped featur | **Network** | DevTools-style request table, parallel subresource fetch, full request/response logging, HAR 1.2 export, CSS/JS coverage reporting | | **SSE** | Streaming parser (HTML Living Standard), async client with auto-reconnect, thread-safe manager, JS EventSource API, 4 deno_core ops, SSRF validation | | **WebSocket** | WS/WSS via tokio-tungstenite, connection pooling, per-origin limits, CDP events | -| **CDP Server** | WebSocket endpoint on ws://127.0.0.1:9222, 14 domain handlers (Browser, Target, Page, DOM, Network, Runtime, Input, CSS, Console, Log, Security, Emulation, Performance, Pardus), event bus, node mapping | +| **CDP Server** | WebSocket endpoint on ws://127.0.0.1:9222, 14 domain handlers (Browser, Target, Page, DOM, Network, Runtime, Input, CSS, Console, Log, Security, Emulation, Performance, Open), event bus, node mapping | | **Knowledge Graph** | BFS crawler, blake3 fingerprinting, transition discovery (links/hash/pagination), JSON graph output | | **Frames** | Recursive iframe/frame parsing with depth limits, sandbox token awareness, iframe-aware semantic tree | | **Shadow DOM** | Shadow boundary piercing (query_selector_deep, query_selector_all_deep) | @@ -48,7 +48,7 @@ Core engine, CLI, and all major subsystems are stable. Summary of shipped featur - [x] Cross-platform — dashboard is pure HTML/CSS (no OS webview dependency for primary view); CAPTCHA popup uses OS webview only when needed **Phase 1.5 — Webview ↔ Headless Browser Sync (current)** -- [x] Click interceptor — JS injected into OS webview captures clicks on links, buttons, inputs and forwards to Pardus headless browser via Tauri events +- [x] Click interceptor — JS injected into OS webview captures clicks on links, buttons, inputs and forwards to Open headless browser via Tauri events - [x] CSS selector generator — produces unique selectors for any clicked DOM element (ID, name, type, nth-of-type) - [x] Form input sync — debounced `input` event tracking syncs typed values to headless browser form state - [x] Select/checkbox/radio change tracking — `change` events forwarded as `select`/`toggle` CDP actions @@ -56,7 +56,7 @@ Core engine, CLI, and all major subsystems are stable. Summary of shipped featur - [x] Navigation sync — when headless browser navigates after a forwarded action, OS webview is updated to the new URL - [x] Href fallback — when CSS selector doesn't match in headless browser, falls back to direct URL navigation - [x] Action log events — `webview-action-log` Tauri events emitted for frontend action log integration -- [x] Pardus UI guard — toolbar and challenge banner clicks are not intercepted +- [x] Open UI guard — toolbar and challenge banner clicks are not intercepted **Phase 2 — Multi-Agent Dashboard (current)** - [x] Multiple concurrent agent instances — spawn/manage N agents in one window @@ -73,7 +73,7 @@ Core engine, CLI, and all major subsystems are stable. Summary of shipped featur **Phase 3 — Rendered View (Optional)** - [ ] Rendered page tab — OS webview shows actual page pixels (WKWebView on macOS, WebKitGTK on Linux, WebView2 on Windows) - [ ] Split view — semantic tree on left, rendered pixels on right -- [ ] Screenshot capture — use pardus-core screenshot feature (chromiumoxide) for pixel-perfect captures +- [ ] Screenshot capture — use open-core screenshot feature (chromiumoxide) for pixel-perfect captures **Architecture:** ``` @@ -132,9 +132,9 @@ Core engine, CLI, and all major subsystems are stable. Summary of shipped featur - [ ] **Shadow DOM in JS runtime** — Wire shadow boundary piercing into deno_core ops; currently only works in Rust-side parsing - [ ] **External script execution** — Fetch and execute `"#; // ==================== execute_js Integration ==================== // NOTE: V8-based integration tests run individually but crash when batched // due to deno_core's V8 platform not being safe for multi-init in a - // single test process. Run these with: cargo test -p pardus-core --features js -- + // single test process. Run these with: cargo test -p open-core --features js -- } diff --git a/crates/pardus-core/src/js/snapshot.rs b/crates/open-core/src/js/snapshot.rs similarity index 95% rename from crates/pardus-core/src/js/snapshot.rs rename to crates/open-core/src/js/snapshot.rs index 78a1e9d..4490cd7 100644 --- a/crates/pardus-core/src/js/snapshot.rs +++ b/crates/open-core/src/js/snapshot.rs @@ -8,12 +8,12 @@ use std::sync::OnceLock; use deno_core::RuntimeOptions; -use super::extension::pardus_dom; +use super::extension::open_dom; use crate::sandbox::JsSandboxMode; fn create_bootstrap_snapshot(bootstrap_code: &'static str) -> &'static [u8] { let mut runtime = deno_core::JsRuntimeForSnapshot::new(RuntimeOptions { - extensions: vec![pardus_dom::init()], + extensions: vec![open_dom::init()], ..Default::default() }); if let Err(e) = runtime.execute_script("bootstrap.js", bootstrap_code) { diff --git a/crates/pardus-core/src/js/sse.rs b/crates/open-core/src/js/sse.rs similarity index 100% rename from crates/pardus-core/src/js/sse.rs rename to crates/open-core/src/js/sse.rs diff --git a/crates/pardus-core/src/js/timer.rs b/crates/open-core/src/js/timer.rs similarity index 100% rename from crates/pardus-core/src/js/timer.rs rename to crates/open-core/src/js/timer.rs diff --git a/crates/pardus-core/src/js/v8/isolate_pool.rs b/crates/open-core/src/js/v8/isolate_pool.rs similarity index 100% rename from crates/pardus-core/src/js/v8/isolate_pool.rs rename to crates/open-core/src/js/v8/isolate_pool.rs diff --git a/crates/pardus-core/src/js/v8/mod.rs b/crates/open-core/src/js/v8/mod.rs similarity index 100% rename from crates/pardus-core/src/js/v8/mod.rs rename to crates/open-core/src/js/v8/mod.rs diff --git a/crates/pardus-core/src/js/v8/module_cache.rs b/crates/open-core/src/js/v8/module_cache.rs similarity index 100% rename from crates/pardus-core/src/js/v8/module_cache.rs rename to crates/open-core/src/js/v8/module_cache.rs diff --git a/crates/pardus-core/src/js/v8/snapshot.rs b/crates/open-core/src/js/v8/snapshot.rs similarity index 100% rename from crates/pardus-core/src/js/v8/snapshot.rs rename to crates/open-core/src/js/v8/snapshot.rs diff --git a/crates/pardus-core/src/lib.rs b/crates/open-core/src/lib.rs similarity index 100% rename from crates/pardus-core/src/lib.rs rename to crates/open-core/src/lib.rs diff --git a/crates/pardus-core/src/navigation/graph.rs b/crates/open-core/src/navigation/graph.rs similarity index 100% rename from crates/pardus-core/src/navigation/graph.rs rename to crates/open-core/src/navigation/graph.rs diff --git a/crates/pardus-core/src/navigation/mod.rs b/crates/open-core/src/navigation/mod.rs similarity index 100% rename from crates/pardus-core/src/navigation/mod.rs rename to crates/open-core/src/navigation/mod.rs diff --git a/crates/pardus-core/src/oauth/flow.rs b/crates/open-core/src/oauth/flow.rs similarity index 100% rename from crates/pardus-core/src/oauth/flow.rs rename to crates/open-core/src/oauth/flow.rs diff --git a/crates/pardus-core/src/oauth/mod.rs b/crates/open-core/src/oauth/mod.rs similarity index 91% rename from crates/pardus-core/src/oauth/mod.rs rename to crates/open-core/src/oauth/mod.rs index 31b169a..e5b13fa 100644 --- a/crates/pardus-core/src/oauth/mod.rs +++ b/crates/open-core/src/oauth/mod.rs @@ -1,4 +1,4 @@ -//! OAuth 2.0 / OIDC support for Pardus browser. +//! OAuth 2.0 / OIDC support for Open browser. //! //! Implements authorization code flow with PKCE, token management, //! OIDC discovery, and automatic Authorization header injection. diff --git a/crates/pardus-core/src/oauth/oidc.rs b/crates/open-core/src/oauth/oidc.rs similarity index 100% rename from crates/pardus-core/src/oauth/oidc.rs rename to crates/open-core/src/oauth/oidc.rs diff --git a/crates/pardus-core/src/oauth/pkce.rs b/crates/open-core/src/oauth/pkce.rs similarity index 100% rename from crates/pardus-core/src/oauth/pkce.rs rename to crates/open-core/src/oauth/pkce.rs diff --git a/crates/pardus-core/src/oauth/store.rs b/crates/open-core/src/oauth/store.rs similarity index 100% rename from crates/pardus-core/src/oauth/store.rs rename to crates/open-core/src/oauth/store.rs diff --git a/crates/pardus-core/src/oauth/token.rs b/crates/open-core/src/oauth/token.rs similarity index 100% rename from crates/pardus-core/src/oauth/token.rs rename to crates/open-core/src/oauth/token.rs diff --git a/crates/pardus-core/src/output/json_formatter.rs b/crates/open-core/src/output/json_formatter.rs similarity index 88% rename from crates/pardus-core/src/output/json_formatter.rs rename to crates/open-core/src/output/json_formatter.rs index 04e78f2..8e6ded5 100644 --- a/crates/pardus-core/src/output/json_formatter.rs +++ b/crates/open-core/src/output/json_formatter.rs @@ -12,7 +12,7 @@ pub struct JsonResult<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub navigation_graph: Option<&'a NavigationGraph>, #[serde(skip_serializing_if = "Option::is_none")] - pub network_log: Option<&'a pardus_debug::formatter::NetworkLogJson>, + pub network_log: Option<&'a open_debug::formatter::NetworkLogJson>, #[serde(skip_serializing_if = "Option::is_none")] pub redirect_chain: Option<&'a RedirectChain>, } @@ -23,7 +23,7 @@ pub fn format_json( title: Option, tree: &SemanticTree, nav_graph: Option<&NavigationGraph>, - network_log: Option<&pardus_debug::formatter::NetworkLogJson>, + network_log: Option<&open_debug::formatter::NetworkLogJson>, redirect_chain: Option<&RedirectChain>, ) -> anyhow::Result { let result = JsonResult { diff --git a/crates/pardus-core/src/output/llm_formatter.rs b/crates/open-core/src/output/llm_formatter.rs similarity index 100% rename from crates/pardus-core/src/output/llm_formatter.rs rename to crates/open-core/src/output/llm_formatter.rs diff --git a/crates/pardus-core/src/output/md_formatter.rs b/crates/open-core/src/output/md_formatter.rs similarity index 100% rename from crates/pardus-core/src/output/md_formatter.rs rename to crates/open-core/src/output/md_formatter.rs diff --git a/crates/pardus-core/src/output/mod.rs b/crates/open-core/src/output/mod.rs similarity index 100% rename from crates/pardus-core/src/output/mod.rs rename to crates/open-core/src/output/mod.rs diff --git a/crates/pardus-core/src/output/tree_formatter.rs b/crates/open-core/src/output/tree_formatter.rs similarity index 100% rename from crates/pardus-core/src/output/tree_formatter.rs rename to crates/open-core/src/output/tree_formatter.rs diff --git a/crates/pardus-core/src/page.rs b/crates/open-core/src/page.rs similarity index 98% rename from crates/pardus-core/src/page.rs rename to crates/open-core/src/page.rs index dec4655..79ad8df 100644 --- a/crates/pardus-core/src/page.rs +++ b/crates/open-core/src/page.rs @@ -1,6 +1,6 @@ use std::{cell::OnceCell, sync::Arc, time::Instant}; -use pardus_debug::{Initiator, NetworkRecord, ResourceType}; +use open_debug::{Initiator, NetworkRecord, ResourceType}; use scraper::{ElementRef, Html, Selector}; use serde::Serialize; use url::Url; @@ -845,14 +845,14 @@ impl Page { NavigationGraph::build(&self.html, &self.url) } - pub fn discover_subresources(&self, log: &Arc>) { + pub fn discover_subresources(&self, log: &Arc>) { let start_id = { let log = log.lock().unwrap(); log.next_id() }; let subresources = - pardus_debug::discover::discover_subresources(&self.html, &self.base_url, start_id); + open_debug::discover::discover_subresources(&self.html, &self.base_url, start_id); let mut log = log.lock().unwrap(); for record in subresources { @@ -862,7 +862,7 @@ impl Page { pub async fn fetch_subresources( client: &rquest::Client, - log: &Arc>, + log: &Arc>, ) { // 1. Extract unfetched records with their types and IDs let entries: Vec<(usize, String, ResourceType)> = { @@ -1076,15 +1076,15 @@ impl Page { base_url.join(url).ok().map(|u| u.to_string()) } - /// Parse the `data-pardus-navigation-href` attribute from HTML returned + /// Parse the `data-open-navigation-href` attribute from HTML returned /// by JS execution to detect `location.href`, `location.assign()`, or /// `location.replace()` redirects. #[cfg(feature = "js")] fn parse_js_navigation_href(html_str: &str) -> Option { let doc = Html::parse_document(html_str); - let selector = Selector::parse("html[data-pardus-navigation-href]").ok()?; + let selector = Selector::parse("html[data-open-navigation-href]").ok()?; doc.select(&selector).next().and_then(|el| { - let href = el.value().attr("data-pardus-navigation-href")?; + let href = el.value().attr("data-open-navigation-href")?; let trimmed = href.trim(); if trimmed.is_empty() || trimmed.starts_with('#') || trimmed.starts_with("javascript:") { @@ -1527,7 +1527,7 @@ mod tests { #[cfg(feature = "js")] #[test] fn test_parse_js_nav_href_present() { - let html = r#""#; + let html = r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, Some("https://other.com".to_string())); } @@ -1535,7 +1535,7 @@ mod tests { #[cfg(feature = "js")] #[test] fn test_parse_js_nav_href_empty() { - let html = r#""#; + let html = r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, None); } @@ -1544,7 +1544,7 @@ mod tests { #[test] fn test_parse_js_nav_href_hash() { let html = - r##""##; + r##""##; let result = Page::parse_js_navigation_href(html); assert_eq!(result, None); } @@ -1552,7 +1552,7 @@ mod tests { #[cfg(feature = "js")] #[test] fn test_parse_js_nav_href_javascript() { - let html = r#""#; + let html = r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, None); } @@ -1569,7 +1569,7 @@ mod tests { #[test] fn test_parse_js_nav_href_relative() { let html = - r#""#; + r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, Some("/new-page".to_string())); } @@ -1578,7 +1578,7 @@ mod tests { #[test] fn test_parse_js_nav_href_whitespace_trimmed() { let html = - r#""#; + r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, Some("/trimmed".to_string())); } @@ -1586,7 +1586,7 @@ mod tests { #[cfg(feature = "js")] #[test] fn test_parse_js_nav_href_data_uri_skipped() { - let html = r#""#; + let html = r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, Some("data:text/html,test".to_string())); } @@ -1594,7 +1594,7 @@ mod tests { #[cfg(feature = "js")] #[test] fn test_parse_js_nav_href_javascript_with_spaces() { - let html = r#""#; + let html = r#""#; let result = Page::parse_js_navigation_href(html); assert_eq!(result, None); } diff --git a/crates/pardus-core/src/page_analysis.rs b/crates/open-core/src/page_analysis.rs similarity index 100% rename from crates/pardus-core/src/page_analysis.rs rename to crates/open-core/src/page_analysis.rs diff --git a/crates/pardus-core/src/parser/arena_dom.rs b/crates/open-core/src/parser/arena_dom.rs similarity index 100% rename from crates/pardus-core/src/parser/arena_dom.rs rename to crates/open-core/src/parser/arena_dom.rs diff --git a/crates/pardus-core/src/parser/fast_scanner.rs b/crates/open-core/src/parser/fast_scanner.rs similarity index 100% rename from crates/pardus-core/src/parser/fast_scanner.rs rename to crates/open-core/src/parser/fast_scanner.rs diff --git a/crates/pardus-core/src/parser/lazy.rs b/crates/open-core/src/parser/lazy.rs similarity index 100% rename from crates/pardus-core/src/parser/lazy.rs rename to crates/open-core/src/parser/lazy.rs diff --git a/crates/pardus-core/src/parser/mod.rs b/crates/open-core/src/parser/mod.rs similarity index 100% rename from crates/pardus-core/src/parser/mod.rs rename to crates/open-core/src/parser/mod.rs diff --git a/crates/pardus-core/src/parser/node_pool.rs b/crates/open-core/src/parser/node_pool.rs similarity index 100% rename from crates/pardus-core/src/parser/node_pool.rs rename to crates/open-core/src/parser/node_pool.rs diff --git a/crates/pardus-core/src/parser/preload_scanner.rs b/crates/open-core/src/parser/preload_scanner.rs similarity index 100% rename from crates/pardus-core/src/parser/preload_scanner.rs rename to crates/open-core/src/parser/preload_scanner.rs diff --git a/crates/pardus-core/src/parser/selective.rs b/crates/open-core/src/parser/selective.rs similarity index 100% rename from crates/pardus-core/src/parser/selective.rs rename to crates/open-core/src/parser/selective.rs diff --git a/crates/pardus-core/src/parser/streaming.rs b/crates/open-core/src/parser/streaming.rs similarity index 100% rename from crates/pardus-core/src/parser/streaming.rs rename to crates/open-core/src/parser/streaming.rs diff --git a/crates/pardus-core/src/parser/streaming_semantic.rs b/crates/open-core/src/parser/streaming_semantic.rs similarity index 100% rename from crates/pardus-core/src/parser/streaming_semantic.rs rename to crates/open-core/src/parser/streaming_semantic.rs diff --git a/crates/pardus-core/src/pdf.rs b/crates/open-core/src/pdf.rs similarity index 100% rename from crates/pardus-core/src/pdf.rs rename to crates/open-core/src/pdf.rs diff --git a/crates/pardus-core/src/prefetch/mod.rs b/crates/open-core/src/prefetch/mod.rs similarity index 100% rename from crates/pardus-core/src/prefetch/mod.rs rename to crates/open-core/src/prefetch/mod.rs diff --git a/crates/pardus-core/src/prefetch/predictor.rs b/crates/open-core/src/prefetch/predictor.rs similarity index 100% rename from crates/pardus-core/src/prefetch/predictor.rs rename to crates/open-core/src/prefetch/predictor.rs diff --git a/crates/pardus-core/src/prefetch/prefetcher.rs b/crates/open-core/src/prefetch/prefetcher.rs similarity index 100% rename from crates/pardus-core/src/prefetch/prefetcher.rs rename to crates/open-core/src/prefetch/prefetcher.rs diff --git a/crates/pardus-core/src/push/early_scanner.rs b/crates/open-core/src/push/early_scanner.rs similarity index 100% rename from crates/pardus-core/src/push/early_scanner.rs rename to crates/open-core/src/push/early_scanner.rs diff --git a/crates/pardus-core/src/push/h2_push.rs b/crates/open-core/src/push/h2_push.rs similarity index 100% rename from crates/pardus-core/src/push/h2_push.rs rename to crates/open-core/src/push/h2_push.rs diff --git a/crates/pardus-core/src/push/mod.rs b/crates/open-core/src/push/mod.rs similarity index 100% rename from crates/pardus-core/src/push/mod.rs rename to crates/open-core/src/push/mod.rs diff --git a/crates/pardus-core/src/push/push_cache.rs b/crates/open-core/src/push/push_cache.rs similarity index 100% rename from crates/pardus-core/src/push/push_cache.rs rename to crates/open-core/src/push/push_cache.rs diff --git a/crates/pardus-core/src/resource/fetcher.rs b/crates/open-core/src/resource/fetcher.rs similarity index 100% rename from crates/pardus-core/src/resource/fetcher.rs rename to crates/open-core/src/resource/fetcher.rs diff --git a/crates/pardus-core/src/resource/mod.rs b/crates/open-core/src/resource/mod.rs similarity index 100% rename from crates/pardus-core/src/resource/mod.rs rename to crates/open-core/src/resource/mod.rs diff --git a/crates/pardus-core/src/resource/pool.rs b/crates/open-core/src/resource/pool.rs similarity index 100% rename from crates/pardus-core/src/resource/pool.rs rename to crates/open-core/src/resource/pool.rs diff --git a/crates/pardus-core/src/resource/priority.rs b/crates/open-core/src/resource/priority.rs similarity index 100% rename from crates/pardus-core/src/resource/priority.rs rename to crates/open-core/src/resource/priority.rs diff --git a/crates/pardus-core/src/resource/scheduler.rs b/crates/open-core/src/resource/scheduler.rs similarity index 100% rename from crates/pardus-core/src/resource/scheduler.rs rename to crates/open-core/src/resource/scheduler.rs diff --git a/crates/pardus-core/src/sandbox/mod.rs b/crates/open-core/src/sandbox/mod.rs similarity index 100% rename from crates/pardus-core/src/sandbox/mod.rs rename to crates/open-core/src/sandbox/mod.rs diff --git a/crates/pardus-core/src/screenshot/capture.rs b/crates/open-core/src/screenshot/capture.rs similarity index 100% rename from crates/pardus-core/src/screenshot/capture.rs rename to crates/open-core/src/screenshot/capture.rs diff --git a/crates/pardus-core/src/screenshot/chrome.rs b/crates/open-core/src/screenshot/chrome.rs similarity index 100% rename from crates/pardus-core/src/screenshot/chrome.rs rename to crates/open-core/src/screenshot/chrome.rs diff --git a/crates/pardus-core/src/screenshot/mod.rs b/crates/open-core/src/screenshot/mod.rs similarity index 100% rename from crates/pardus-core/src/screenshot/mod.rs rename to crates/open-core/src/screenshot/mod.rs diff --git a/crates/pardus-core/src/semantic/extract.rs b/crates/open-core/src/semantic/extract.rs similarity index 100% rename from crates/pardus-core/src/semantic/extract.rs rename to crates/open-core/src/semantic/extract.rs diff --git a/crates/pardus-core/src/semantic/mod.rs b/crates/open-core/src/semantic/mod.rs similarity index 100% rename from crates/pardus-core/src/semantic/mod.rs rename to crates/open-core/src/semantic/mod.rs diff --git a/crates/pardus-core/src/semantic/selector.rs b/crates/open-core/src/semantic/selector.rs similarity index 100% rename from crates/pardus-core/src/semantic/selector.rs rename to crates/open-core/src/semantic/selector.rs diff --git a/crates/pardus-core/src/semantic/tree.rs b/crates/open-core/src/semantic/tree.rs similarity index 100% rename from crates/pardus-core/src/semantic/tree.rs rename to crates/open-core/src/semantic/tree.rs diff --git a/crates/pardus-core/src/session.rs b/crates/open-core/src/session.rs similarity index 100% rename from crates/pardus-core/src/session.rs rename to crates/open-core/src/session.rs diff --git a/crates/pardus-core/src/sse/client.rs b/crates/open-core/src/sse/client.rs similarity index 100% rename from crates/pardus-core/src/sse/client.rs rename to crates/open-core/src/sse/client.rs diff --git a/crates/pardus-core/src/sse/manager.rs b/crates/open-core/src/sse/manager.rs similarity index 100% rename from crates/pardus-core/src/sse/manager.rs rename to crates/open-core/src/sse/manager.rs diff --git a/crates/pardus-core/src/sse/mod.rs b/crates/open-core/src/sse/mod.rs similarity index 100% rename from crates/pardus-core/src/sse/mod.rs rename to crates/open-core/src/sse/mod.rs diff --git a/crates/pardus-core/src/sse/parser.rs b/crates/open-core/src/sse/parser.rs similarity index 99% rename from crates/pardus-core/src/sse/parser.rs rename to crates/open-core/src/sse/parser.rs index 5d849f6..b808409 100644 --- a/crates/pardus-core/src/sse/parser.rs +++ b/crates/open-core/src/sse/parser.rs @@ -23,7 +23,7 @@ pub struct SseEvent { /// Streaming SSE parser that handles partial input across chunks. /// /// ```rust -/// # use pardus_core::sse::parser::{SseParser, SseEvent}; +/// # use open_core::sse::parser::{SseParser, SseEvent}; /// let mut p = SseParser::new(); /// let events = p.feed("data: hello\n\n"); /// assert_eq!(events[0].data, "hello"); diff --git a/crates/pardus-core/src/tab/manager.rs b/crates/open-core/src/tab/manager.rs similarity index 100% rename from crates/pardus-core/src/tab/manager.rs rename to crates/open-core/src/tab/manager.rs diff --git a/crates/pardus-core/src/tab/mod.rs b/crates/open-core/src/tab/mod.rs similarity index 96% rename from crates/pardus-core/src/tab/mod.rs rename to crates/open-core/src/tab/mod.rs index 0d0d3b3..0364cfb 100644 --- a/crates/pardus-core/src/tab/mod.rs +++ b/crates/open-core/src/tab/mod.rs @@ -1,4 +1,4 @@ -//! Tab management module for pardus-core +//! Tab management module for open-core //! //! Provides orthogonal tab functionality that wraps existing Page/App //! without modifying them. Tabs share App resources but maintain diff --git a/crates/pardus-core/src/tab/state.rs b/crates/open-core/src/tab/state.rs similarity index 100% rename from crates/pardus-core/src/tab/state.rs rename to crates/open-core/src/tab/state.rs diff --git a/crates/pardus-core/src/tab/tab.rs b/crates/open-core/src/tab/tab.rs similarity index 98% rename from crates/pardus-core/src/tab/tab.rs rename to crates/open-core/src/tab/tab.rs index 288041c..827946b 100644 --- a/crates/pardus-core/src/tab/tab.rs +++ b/crates/open-core/src/tab/tab.rs @@ -204,7 +204,7 @@ impl Tab { pub async fn load_with_client( &mut self, client: &rquest::Client, - network_log: &Arc>, + network_log: &Arc>, config: &BrowserConfig, js_enabled: bool, wait_ms: u32, @@ -245,7 +245,7 @@ impl Tab { pub async fn navigate_with_client( &mut self, client: &rquest::Client, - network_log: &Arc>, + network_log: &Arc>, config: &BrowserConfig, url: &str, js_enabled: bool, @@ -262,7 +262,7 @@ impl Tab { pub async fn reload_with_client( &mut self, client: &rquest::Client, - network_log: &Arc>, + network_log: &Arc>, config: &BrowserConfig, ) -> anyhow::Result<&Page> { self.state = TabState::Loading; diff --git a/crates/pardus-core/src/tls/mod.rs b/crates/open-core/src/tls/mod.rs similarity index 100% rename from crates/pardus-core/src/tls/mod.rs rename to crates/open-core/src/tls/mod.rs diff --git a/crates/pardus-core/src/tls/pinning.rs b/crates/open-core/src/tls/pinning.rs similarity index 100% rename from crates/pardus-core/src/tls/pinning.rs rename to crates/open-core/src/tls/pinning.rs diff --git a/crates/pardus-core/src/url_policy.rs b/crates/open-core/src/url_policy.rs similarity index 100% rename from crates/pardus-core/src/url_policy.rs rename to crates/open-core/src/url_policy.rs diff --git a/crates/pardus-core/src/websocket/connection.rs b/crates/open-core/src/websocket/connection.rs similarity index 100% rename from crates/pardus-core/src/websocket/connection.rs rename to crates/open-core/src/websocket/connection.rs diff --git a/crates/pardus-core/src/websocket/manager.rs b/crates/open-core/src/websocket/manager.rs similarity index 100% rename from crates/pardus-core/src/websocket/manager.rs rename to crates/open-core/src/websocket/manager.rs diff --git a/crates/pardus-core/src/websocket/mod.rs b/crates/open-core/src/websocket/mod.rs similarity index 89% rename from crates/pardus-core/src/websocket/mod.rs rename to crates/open-core/src/websocket/mod.rs index c15e2c6..e32fc4c 100644 --- a/crates/pardus-core/src/websocket/mod.rs +++ b/crates/open-core/src/websocket/mod.rs @@ -1,4 +1,4 @@ -//! WebSocket support for PardusBrowser. +//! WebSocket support for OpenBrowser. //! //! Provides native WS/WSS protocol handling with: //! - Connection management via `WebSocketManager` diff --git a/crates/pardus-core/tests/config_test.rs b/crates/open-core/tests/config_test.rs similarity index 99% rename from crates/pardus-core/tests/config_test.rs rename to crates/open-core/tests/config_test.rs index 4bcc594..15d65b6 100644 --- a/crates/pardus-core/tests/config_test.rs +++ b/crates/open-core/tests/config_test.rs @@ -3,7 +3,7 @@ //! Verifies that all configuration structs produce sensible defaults //! and that builder methods chain correctly. -use pardus_core::BrowserConfig; +use open_core::BrowserConfig; // --------------------------------------------------------------------------- // BrowserConfig defaults diff --git a/crates/pardus-core/tests/csp_test.rs b/crates/open-core/tests/csp_test.rs similarity index 99% rename from crates/pardus-core/tests/csp_test.rs rename to crates/open-core/tests/csp_test.rs index e0e114e..904a0a0 100644 --- a/crates/pardus-core/tests/csp_test.rs +++ b/crates/open-core/tests/csp_test.rs @@ -1,6 +1,6 @@ //! Tests for Content Security Policy parsing and evaluation. -use pardus_core::csp::{ +use open_core::csp::{ CspPolicySet, CspDirectiveKind, CspSource, parser::CspPolicy, source::{SourceMatchContext, compute_hash}, diff --git a/crates/pardus-core/tests/dedup_extended_test.rs b/crates/open-core/tests/dedup_extended_test.rs similarity index 98% rename from crates/pardus-core/tests/dedup_extended_test.rs rename to crates/open-core/tests/dedup_extended_test.rs index 5f09ec8..5e79622 100644 --- a/crates/pardus-core/tests/dedup_extended_test.rs +++ b/crates/open-core/tests/dedup_extended_test.rs @@ -1,7 +1,7 @@ //! Extended tests for request deduplication edge cases. use std::sync::Arc; -use pardus_core::dedup::{RequestDedup, DedupEntry, DedupResult, dedup_key}; +use open_core::dedup::{RequestDedup, DedupEntry, DedupResult, dedup_key}; // --------------------------------------------------------------------------- // dedup_key normalization diff --git a/crates/pardus-core/tests/element_id_test.rs b/crates/open-core/tests/element_id_test.rs similarity index 90% rename from crates/pardus-core/tests/element_id_test.rs rename to crates/open-core/tests/element_id_test.rs index ea602b5..7ce3db5 100644 --- a/crates/pardus-core/tests/element_id_test.rs +++ b/crates/open-core/tests/element_id_test.rs @@ -3,8 +3,8 @@ //! Tests that interactive elements get unique IDs assigned during semantic tree building, //! and that these IDs can be used to find and interact with elements. -use pardus_core::semantic::tree::{SemanticTree, SemanticNode, SemanticRole}; -use pardus_core::page::Page; +use open_core::semantic::tree::{SemanticTree, SemanticNode, SemanticRole}; +use open_core::page::Page; // --------------------------------------------------------------------------- // Element ID Assignment Tests @@ -16,8 +16,8 @@ fn test_link_gets_element_id() { let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); // Find the link node - fn find_link(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Link) { + fn find_link(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Link) { return Some(node); } for child in &node.children { @@ -38,8 +38,8 @@ fn test_button_gets_element_id() { let html = r#""#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_button(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Button) { + fn find_button(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Button) { return Some(node); } for child in &node.children { @@ -68,7 +68,7 @@ fn test_multiple_interactive_elements_get_sequential_ids() { "#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn collect_interactive_ids(node: &pardus_core::semantic::tree::SemanticNode, ids: &mut Vec) { + fn collect_interactive_ids(node: &open_core::semantic::tree::SemanticNode, ids: &mut Vec) { if let Some(id) = node.element_id { ids.push(id); } @@ -96,8 +96,8 @@ fn test_textbox_gets_element_id() { let html = r#""#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_textbox(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::TextBox) { + fn find_textbox(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::TextBox) { return Some(node); } for child in &node.children { @@ -117,8 +117,8 @@ fn test_checkbox_gets_element_id() { let html = r#""#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_checkbox(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Checkbox) { + fn find_checkbox(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Checkbox) { return Some(node); } for child in &node.children { @@ -138,8 +138,8 @@ fn test_radio_gets_element_id() { let html = r#""#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_radio(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Radio) { + fn find_radio(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Radio) { return Some(node); } for child in &node.children { @@ -159,8 +159,8 @@ fn test_combobox_gets_element_id() { let html = r#""#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_combobox(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Combobox) { + fn find_combobox(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Combobox) { return Some(node); } for child in &node.children { @@ -184,8 +184,8 @@ fn test_disabled_button_has_no_element_id() { let html = r#""#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_button(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Button) { + fn find_button(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Button) { return Some(node); } for child in &node.children { @@ -211,8 +211,8 @@ fn test_disabled_elements_dont_consume_ids() { "#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn collect_button_ids(node: &pardus_core::semantic::tree::SemanticNode, ids: &mut Vec) { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Button) { + fn collect_button_ids(node: &open_core::semantic::tree::SemanticNode, ids: &mut Vec) { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Button) { if let Some(id) = node.element_id { ids.push(id); } @@ -238,8 +238,8 @@ fn test_heading_has_no_element_id() { let html = r#"

Title

"#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_heading(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Heading { .. }) { + fn find_heading(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Heading { .. }) { return Some(node); } for child in &node.children { @@ -259,8 +259,8 @@ fn test_generic_element_has_no_element_id() { let html = r#"
Some content
"#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_generic(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Generic) { + fn find_generic(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Generic) { return Some(node); } for child in &node.children { @@ -305,8 +305,8 @@ fn test_link_without_href_has_no_element_id() { let html = r#"Anchor Only"#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn find_link(node: &pardus_core::semantic::tree::SemanticNode) -> Option<&pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Link) { + fn find_link(node: &open_core::semantic::tree::SemanticNode) -> Option<&open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Link) { return Some(node); } for child in &node.children { @@ -343,7 +343,7 @@ fn test_interactive_elements_have_selectors() { "#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://example.com"); - fn collect_selectors(node: &pardus_core::semantic::tree::SemanticNode, selectors: &mut Vec) { + fn collect_selectors(node: &open_core::semantic::tree::SemanticNode, selectors: &mut Vec) { if let Some(sel) = &node.selector { selectors.push(sel.clone()); } @@ -372,8 +372,8 @@ fn test_multiple_links_have_unique_selectors() { "#; let tree = SemanticTree::build(&scraper::Html::parse_document(html), "https://google.com"); - fn find_link_by_text<'a>(node: &'a pardus_core::semantic::tree::SemanticNode, text: &str) -> Option<&'a pardus_core::semantic::tree::SemanticNode> { - if matches!(node.role, pardus_core::semantic::tree::SemanticRole::Link) { + fn find_link_by_text<'a>(node: &'a open_core::semantic::tree::SemanticNode, text: &str) -> Option<&'a open_core::semantic::tree::SemanticNode> { + if matches!(node.role, open_core::semantic::tree::SemanticRole::Link) { if node.name.as_deref() == Some(text) { return Some(node); } diff --git a/crates/pardus-core/tests/feed_test.rs b/crates/open-core/tests/feed_test.rs similarity index 98% rename from crates/pardus-core/tests/feed_test.rs rename to crates/open-core/tests/feed_test.rs index f1d57b9..7b5c11b 100644 --- a/crates/pardus-core/tests/feed_test.rs +++ b/crates/open-core/tests/feed_test.rs @@ -1,6 +1,6 @@ //! Tests for RSS/Atom feed detection and semantic tree extraction. -use pardus_core::feed::is_feed_content; +use open_core::feed::is_feed_content; // --------------------------------------------------------------------------- // is_feed_content — content-type detection diff --git a/crates/pardus-core/tests/frame_tree_test.rs b/crates/open-core/tests/frame_tree_test.rs similarity index 99% rename from crates/pardus-core/tests/frame_tree_test.rs rename to crates/open-core/tests/frame_tree_test.rs index 12607f4..371513d 100644 --- a/crates/pardus-core/tests/frame_tree_test.rs +++ b/crates/open-core/tests/frame_tree_test.rs @@ -1,5 +1,5 @@ -use pardus_core::frame::{FrameData, FrameId, FrameTree}; -use pardus_core::Page; +use open_core::frame::{FrameData, FrameId, FrameTree}; +use open_core::Page; use scraper::Html; fn sample_html_with_iframe() -> &'static str { diff --git a/crates/pardus-core/tests/meta_refresh_test.rs b/crates/open-core/tests/meta_refresh_test.rs similarity index 99% rename from crates/pardus-core/tests/meta_refresh_test.rs rename to crates/open-core/tests/meta_refresh_test.rs index 83bc070..e86dd98 100644 --- a/crates/pardus-core/tests/meta_refresh_test.rs +++ b/crates/open-core/tests/meta_refresh_test.rs @@ -3,7 +3,7 @@ //! Tests the public `Page::from_html` API combined with the internal //! `parse_meta_refresh` and `meta_refresh_url` behavior. -use pardus_core::page::Page; +use open_core::page::Page; use scraper::{Html, Selector}; // --------------------------------------------------------------------------- diff --git a/crates/pardus-core/tests/output_formatter_test.rs b/crates/open-core/tests/output_formatter_test.rs similarity index 84% rename from crates/pardus-core/tests/output_formatter_test.rs rename to crates/open-core/tests/output_formatter_test.rs index 16778d9..2c327bd 100644 --- a/crates/pardus-core/tests/output_formatter_test.rs +++ b/crates/open-core/tests/output_formatter_test.rs @@ -1,6 +1,6 @@ //! Tests for output formatters: format_tree, format_md, format_llm, format_json. -use pardus_core::{RedirectChain, SemanticNode, SemanticRole, SemanticTree, TreeStats}; +use open_core::{RedirectChain, SemanticNode, SemanticRole, SemanticTree, TreeStats}; use scraper::Html; fn tree_from(html: &str) -> SemanticTree { @@ -29,14 +29,14 @@ fn simple_tree() -> SemanticTree { #[test] fn test_format_tree_produces_output() { let tree = simple_tree(); - let output = pardus_core::format_tree(&tree); + let output = open_core::format_tree(&tree); assert!(!output.is_empty()); } #[test] fn test_format_tree_has_tree_chars() { let tree = simple_tree(); - let output = pardus_core::format_tree(&tree); + let output = open_core::format_tree(&tree); assert!( output.contains("├") || output.contains("└"), "tree output should contain tree branch characters" @@ -46,7 +46,7 @@ fn test_format_tree_has_tree_chars() { #[test] fn test_format_tree_shows_roles() { let tree = tree_from(""); - let output = pardus_core::format_tree(&tree); + let output = open_core::format_tree(&tree); assert!( output.contains("navigation") || output.contains("nav"), "tree output should mention navigation role" @@ -60,14 +60,14 @@ fn test_format_tree_shows_roles() { #[test] fn test_format_md_produces_output() { let tree = simple_tree(); - let output = pardus_core::output::md_formatter::format_md(&tree); + let output = open_core::output::md_formatter::format_md(&tree); assert!(!output.is_empty()); } #[test] fn test_format_md_starts_with_document() { let tree = simple_tree(); - let output = pardus_core::output::md_formatter::format_md(&tree); + let output = open_core::output::md_formatter::format_md(&tree); assert!( output.starts_with("document"), "MD output should start with 'document'" @@ -77,7 +77,7 @@ fn test_format_md_starts_with_document() { #[test] fn test_format_md_shows_links() { let tree = tree_from(r#"Link"#); - let output = pardus_core::output::md_formatter::format_md(&tree); + let output = open_core::output::md_formatter::format_md(&tree); assert!( output.contains("link") || output.contains("/page"), "MD output should contain link info" @@ -91,7 +91,7 @@ fn test_format_md_shows_links() { #[test] fn test_format_llm_produces_output() { let tree = simple_tree(); - let output = pardus_core::format_llm(&tree); + let output = open_core::format_llm(&tree); assert!(!output.is_empty()); } @@ -101,7 +101,7 @@ fn test_format_llm_compact_format() { Link A "#); - let output = pardus_core::format_llm(&tree); + let output = open_core::format_llm(&tree); // LLM format uses single-char tags and compact notation assert!(output.len() > 0); } @@ -112,7 +112,7 @@ fn test_format_llm_lists_actions() { Go "#); - let output = pardus_core::format_llm(&tree); + let output = open_core::format_llm(&tree); assert!(!output.is_empty()); } @@ -123,7 +123,7 @@ fn test_format_llm_lists_actions() { #[test] fn test_format_json_produces_valid_json() { let tree = simple_tree(); - let output = pardus_core::output::json_formatter::format_json( + let output = open_core::output::json_formatter::format_json( "https://example.com", Some("Test Page".to_string()), &tree, @@ -140,7 +140,7 @@ fn test_format_json_produces_valid_json() { #[test] fn test_format_json_includes_url() { let tree = simple_tree(); - let output = pardus_core::output::json_formatter::format_json( + let output = open_core::output::json_formatter::format_json( "https://example.com/page", None, &tree, @@ -156,7 +156,7 @@ fn test_format_json_includes_url() { #[test] fn test_format_json_includes_stats() { let tree = simple_tree(); - let output = pardus_core::output::json_formatter::format_json( + let output = open_core::output::json_formatter::format_json( "https://example.com", None, &tree, @@ -207,17 +207,17 @@ fn test_format_empty_tree() { stats: TreeStats::default(), }; - let tree_out = pardus_core::format_tree(&tree); + let tree_out = open_core::format_tree(&tree); assert!(!tree_out.is_empty()); - let md_out = pardus_core::output::md_formatter::format_md(&tree); + let md_out = open_core::output::md_formatter::format_md(&tree); assert!(!md_out.is_empty()); - let llm_out = pardus_core::format_llm(&tree); + let llm_out = open_core::format_llm(&tree); // LLM format might be empty for an empty tree, that's OK assert!(llm_out.len() >= 0); - let json_out = pardus_core::output::json_formatter::format_json( + let json_out = open_core::output::json_formatter::format_json( "https://example.com", None, &tree, diff --git a/crates/pardus-core/tests/redirect_chain_test.rs b/crates/open-core/tests/redirect_chain_test.rs similarity index 98% rename from crates/pardus-core/tests/redirect_chain_test.rs rename to crates/open-core/tests/redirect_chain_test.rs index 57e5478..8bf08f8 100644 --- a/crates/pardus-core/tests/redirect_chain_test.rs +++ b/crates/open-core/tests/redirect_chain_test.rs @@ -1,6 +1,6 @@ //! Tests for RedirectChain, RedirectHop, and PageSnapshot. -use pardus_core::{RedirectChain, RedirectHop}; +use open_core::{RedirectChain, RedirectHop}; // --------------------------------------------------------------------------- // RedirectHop diff --git a/crates/pardus-core/tests/semantic_extract_test.rs b/crates/open-core/tests/semantic_extract_test.rs similarity index 99% rename from crates/pardus-core/tests/semantic_extract_test.rs rename to crates/open-core/tests/semantic_extract_test.rs index c57b648..ee7e4aa 100644 --- a/crates/pardus-core/tests/semantic_extract_test.rs +++ b/crates/open-core/tests/semantic_extract_test.rs @@ -3,11 +3,11 @@ //! Exercises the shared `compute_role`, `check_interactive`, `compute_action`, //! and `compute_name_from_attrs` functions from `semantic::extract`. -use pardus_core::semantic::extract::{ +use open_core::semantic::extract::{ compute_action, compute_name_from_attrs, compute_role, check_interactive, AttrMap, }; -use pardus_core::semantic::tree::SemanticRole; +use open_core::semantic::tree::SemanticRole; // --------------------------------------------------------------------------- // Helpers diff --git a/crates/pardus-core/tests/session_store_test.rs b/crates/open-core/tests/session_store_test.rs similarity index 98% rename from crates/pardus-core/tests/session_store_test.rs rename to crates/open-core/tests/session_store_test.rs index 679301c..727d99b 100644 --- a/crates/pardus-core/tests/session_store_test.rs +++ b/crates/open-core/tests/session_store_test.rs @@ -4,7 +4,7 @@ //! and that header parsing produces expected values. use base64::Engine; -use pardus_core::SessionStore; +use open_core::SessionStore; use std::path::PathBuf; fn tmp_dir() -> PathBuf { @@ -12,7 +12,7 @@ fn tmp_dir() -> PathBuf { .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_millis(); - std::env::temp_dir().join(format!("pardus-test-session-{}", ms)) + std::env::temp_dir().join(format!("open-test-session-{}", ms)) } // --------------------------------------------------------------------------- diff --git a/crates/pardus-core/tests/shadow_dom_piercing_test.rs b/crates/open-core/tests/shadow_dom_piercing_test.rs similarity index 86% rename from crates/pardus-core/tests/shadow_dom_piercing_test.rs rename to crates/open-core/tests/shadow_dom_piercing_test.rs index 0675501..c15c452 100644 --- a/crates/pardus-core/tests/shadow_dom_piercing_test.rs +++ b/crates/open-core/tests/shadow_dom_piercing_test.rs @@ -7,7 +7,7 @@ fn test_basic() { #[test] fn test_get_shadow_root_returns_none() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "
"; let doc = DomDocument::from_html(html); let regular = doc.get_element_by_id("regular").unwrap(); @@ -16,7 +16,7 @@ fn test_get_shadow_root_returns_none() { #[test] fn test_is_shadow_host_returns_false() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "
"; let doc = DomDocument::from_html(html); let regular = doc.get_element_by_id("regular").unwrap(); @@ -25,7 +25,7 @@ fn test_is_shadow_host_returns_false() { #[test] fn test_collect_all_elements_deep() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "
"; let doc = DomDocument::from_html(html); let body = doc.body(); @@ -35,7 +35,7 @@ fn test_collect_all_elements_deep() { #[test] fn test_query_selector_deep() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "
"; let doc = DomDocument::from_html(html); let found = doc.query_selector_deep(0, "#target"); @@ -44,7 +44,7 @@ fn test_query_selector_deep() { #[test] fn test_query_selector_all_deep() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); let found = doc.query_selector_all_deep(0, "button"); @@ -53,7 +53,7 @@ fn test_query_selector_all_deep() { #[test] fn test_empty_document() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); let body = doc.body(); diff --git a/crates/pardus-core/tests/shadow_root_test.rs b/crates/open-core/tests/shadow_root_test.rs similarity index 91% rename from crates/pardus-core/tests/shadow_root_test.rs rename to crates/open-core/tests/shadow_root_test.rs index 7a2102d..8d4536a 100644 --- a/crates/pardus-core/tests/shadow_root_test.rs +++ b/crates/open-core/tests/shadow_root_test.rs @@ -11,7 +11,7 @@ #[test] fn test_element_node_type_is_1() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "
"; let doc = DomDocument::from_html(html); let div = doc.get_element_by_id("test").unwrap(); @@ -20,7 +20,7 @@ fn test_element_node_type_is_1() { #[test] fn test_text_node_type_is_3() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "text content"; let doc = DomDocument::from_html(html); // Body contains a text node child @@ -39,7 +39,7 @@ fn test_text_node_type_is_3() { #[test] fn test_comment_node_type_is_8() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); // Body contains a comment node @@ -56,7 +56,7 @@ fn test_comment_node_type_is_8() { #[test] fn test_document_element_is_found() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); @@ -68,7 +68,7 @@ fn test_document_element_is_found() { #[test] fn test_document_fragment_node_type_is_11() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let mut doc = DomDocument::from_html(html); @@ -84,7 +84,7 @@ fn test_document_fragment_node_type_is_11() { #[test] fn test_element_node_name_is_uppercase_tag() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "
"; let doc = DomDocument::from_html(html); let div = doc.get_element_by_id("test").unwrap(); @@ -93,7 +93,7 @@ fn test_element_node_name_is_uppercase_tag() { #[test] fn test_text_node_name_is_text() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = "text"; let doc = DomDocument::from_html(html); let body = doc.body(); @@ -109,7 +109,7 @@ fn test_text_node_name_is_text() { #[test] fn test_comment_node_name_is_comment() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); let body = doc.body(); @@ -127,7 +127,7 @@ fn test_comment_node_name_is_comment() { #[test] fn test_document_element_node_name_is_html() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); @@ -139,7 +139,7 @@ fn test_document_element_node_name_is_html() { #[test] fn test_document_fragment_node_name() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let mut doc = DomDocument::from_html(html); @@ -153,7 +153,7 @@ fn test_document_fragment_node_name() { #[test] fn test_create_document_fragment() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let mut doc = DomDocument::from_html(html); @@ -165,7 +165,7 @@ fn test_create_document_fragment() { #[test] fn test_document_fragment_can_have_children() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let mut doc = DomDocument::from_html(""); let fragment = doc.create_document_fragment(); @@ -186,7 +186,7 @@ fn test_document_fragment_can_have_children() { #[test] fn test_document_fragment_children_move_on_insert() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let mut doc = DomDocument::from_html("
"); let fragment = doc.create_document_fragment(); @@ -212,7 +212,7 @@ fn test_document_fragment_children_move_on_insert() { #[test] fn test_shadow_root_mode_variants() { - use pardus_core::js::dom::ShadowRootMode; + use open_core::js::dom::ShadowRootMode; // Test that the enum exists and has the expected variants let open = ShadowRootMode::Open; @@ -230,7 +230,7 @@ fn test_shadow_root_mode_variants() { #[test] fn test_nonexistent_node_type_is_0() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); @@ -240,7 +240,7 @@ fn test_nonexistent_node_type_is_0() { #[test] fn test_nonexistent_node_name_is_empty() { - use pardus_core::js::dom::DomDocument; + use open_core::js::dom::DomDocument; let html = ""; let doc = DomDocument::from_html(html); diff --git a/crates/pardus-core/tests/user_agent_test.rs b/crates/open-core/tests/user_agent_test.rs similarity index 94% rename from crates/pardus-core/tests/user_agent_test.rs rename to crates/open-core/tests/user_agent_test.rs index 10efb59..df94517 100644 --- a/crates/pardus-core/tests/user_agent_test.rs +++ b/crates/open-core/tests/user_agent_test.rs @@ -5,7 +5,7 @@ //! headers), the User-Agent was silently lost. The fix reorders the calls so //! `.user_agent()` is applied last. -use pardus_core::BrowserConfig; +use open_core::BrowserConfig; /// The default User-Agent string set in BrowserConfig. const EXPECTED_UA: &str = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) \ @@ -54,7 +54,7 @@ fn test_config_custom_user_agent_is_preserved() { #[tokio::test] async fn test_http_client_sends_user_agent() { let config = BrowserConfig::default(); - let client = pardus_core::app::build_http_client(&config) + let client = open_core::app::build_http_client(&config) .expect("build_http_client should succeed"); let resp = client @@ -90,11 +90,11 @@ async fn test_http_client_sends_user_agent() { /// Verify that a custom user-agent is sent when configured. #[tokio::test] async fn test_http_client_sends_custom_user_agent() { - let custom_ua = "PardusTestBot/2.0 (Integration Test)"; + let custom_ua = "OpenTestBot/2.0 (Integration Test)"; let mut config = BrowserConfig::default(); config.user_agent = custom_ua.to_string(); - let client = pardus_core::app::build_http_client(&config) + let client = open_core::app::build_http_client(&config) .expect("build_http_client should succeed"); let resp = client @@ -125,7 +125,7 @@ async fn test_http_client_sends_custom_user_agent() { #[tokio::test] async fn test_http_client_sends_sec_ch_ua_headers() { let config = BrowserConfig::default(); - let client = pardus_core::app::build_http_client(&config) + let client = open_core::app::build_http_client(&config) .expect("build_http_client should succeed"); let resp = client diff --git a/crates/pardus-core/tests/websocket_test.rs b/crates/open-core/tests/websocket_test.rs similarity index 99% rename from crates/pardus-core/tests/websocket_test.rs rename to crates/open-core/tests/websocket_test.rs index f506d09..c3a556c 100644 --- a/crates/pardus-core/tests/websocket_test.rs +++ b/crates/open-core/tests/websocket_test.rs @@ -2,7 +2,7 @@ //! //! Tests the WebSocket connection and manager functionality. -use pardus_core::websocket::{WebSocketConfig, WebSocketManager}; +use open_core::websocket::{WebSocketConfig, WebSocketManager}; // --------------------------------------------------------------------------- // Config Tests diff --git a/crates/pardus-debug/Cargo.toml b/crates/open-debug/Cargo.toml similarity index 94% rename from crates/pardus-debug/Cargo.toml rename to crates/open-debug/Cargo.toml index 594d323..4afdd86 100644 --- a/crates/pardus-debug/Cargo.toml +++ b/crates/open-debug/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "pardus-debug" +name = "open-debug" version.workspace = true edition.workspace = true diff --git a/crates/pardus-debug/src/coverage.rs b/crates/open-debug/src/coverage.rs similarity index 100% rename from crates/pardus-debug/src/coverage.rs rename to crates/open-debug/src/coverage.rs diff --git a/crates/pardus-debug/src/discover.rs b/crates/open-debug/src/discover.rs similarity index 100% rename from crates/pardus-debug/src/discover.rs rename to crates/open-debug/src/discover.rs diff --git a/crates/pardus-debug/src/fetch.rs b/crates/open-debug/src/fetch.rs similarity index 100% rename from crates/pardus-debug/src/fetch.rs rename to crates/open-debug/src/fetch.rs diff --git a/crates/pardus-debug/src/formatter.rs b/crates/open-debug/src/formatter.rs similarity index 100% rename from crates/pardus-debug/src/formatter.rs rename to crates/open-debug/src/formatter.rs diff --git a/crates/pardus-debug/src/har.rs b/crates/open-debug/src/har.rs similarity index 98% rename from crates/pardus-debug/src/har.rs rename to crates/open-debug/src/har.rs index 6896372..543f4b0 100644 --- a/crates/pardus-debug/src/har.rs +++ b/crates/open-debug/src/har.rs @@ -182,7 +182,7 @@ impl HarFile { log: HarLog { version: "1.2".to_string(), creator: HarCreator { - name: "PardusBrowser".to_string(), + name: "OpenBrowser".to_string(), version: creator_version, }, pages: vec![], @@ -241,7 +241,7 @@ mod tests { let har = HarFile::from_network_log(&log); assert!(har.log.entries.is_empty()); assert_eq!(har.log.version, "1.2"); - assert_eq!(har.log.creator.name, "PardusBrowser"); + assert_eq!(har.log.creator.name, "OpenBrowser"); } #[test] @@ -406,7 +406,7 @@ mod tests { ); r.status = Some(200); r.request_headers.push(("accept".into(), "text/html".into())); - r.request_headers.push(("user-agent".into(), "PardusBrowser/1.0".into())); + r.request_headers.push(("user-agent".into(), "OpenBrowser/1.0".into())); r.response_headers.push(("content-type".into(), "text/html".into())); r.response_headers.push(("server".into(), "nginx".into())); log.push(r); @@ -418,7 +418,7 @@ mod tests { assert_eq!(entry.request.headers[0].name, "accept"); assert_eq!(entry.request.headers[0].value, "text/html"); assert_eq!(entry.request.headers[1].name, "user-agent"); - assert_eq!(entry.request.headers[1].value, "PardusBrowser/1.0"); + assert_eq!(entry.request.headers[1].value, "OpenBrowser/1.0"); assert_eq!(entry.response.headers.len(), 2); assert_eq!(entry.response.headers[0].name, "content-type"); diff --git a/crates/pardus-debug/src/lib.rs b/crates/open-debug/src/lib.rs similarity index 100% rename from crates/pardus-debug/src/lib.rs rename to crates/open-debug/src/lib.rs diff --git a/crates/pardus-debug/src/record.rs b/crates/open-debug/src/record.rs similarity index 100% rename from crates/pardus-debug/src/record.rs rename to crates/open-debug/src/record.rs diff --git a/crates/pardus-kg/Cargo.toml b/crates/open-kg/Cargo.toml similarity index 78% rename from crates/pardus-kg/Cargo.toml rename to crates/open-kg/Cargo.toml index 1281027..e423ad2 100644 --- a/crates/pardus-kg/Cargo.toml +++ b/crates/open-kg/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "pardus-kg" +name = "open-kg" version.workspace = true edition.workspace = true [dependencies] -pardus-core = { path = "../pardus-core" } -pardus-debug = { path = "../pardus-debug" } +open-core = { path = "../open-core" } +open-debug = { path = "../open-debug" } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } tokio = { workspace = true } diff --git a/crates/pardus-kg/src/config.rs b/crates/open-kg/src/config.rs similarity index 97% rename from crates/pardus-kg/src/config.rs rename to crates/open-kg/src/config.rs index 639e6a3..113d766 100644 --- a/crates/pardus-kg/src/config.rs +++ b/crates/open-kg/src/config.rs @@ -1,4 +1,4 @@ -use pardus_core::ProxyConfig; +use open_core::ProxyConfig; use serde::{Deserialize, Serialize}; /// Configuration for a KG crawl. diff --git a/crates/pardus-kg/src/crawler.rs b/crates/open-kg/src/crawler.rs similarity index 99% rename from crates/pardus-kg/src/crawler.rs rename to crates/open-kg/src/crawler.rs index 863cf45..fedb428 100644 --- a/crates/pardus-kg/src/crawler.rs +++ b/crates/open-kg/src/crawler.rs @@ -6,7 +6,7 @@ use std::{ use anyhow::Result; use futures::stream::{FuturesUnordered, StreamExt}; -use pardus_core::{ +use open_core::{ app::App, config::BrowserConfig, navigation::graph::NavigationGraph, page::Page, page_analysis::PageAnalysis, }; diff --git a/crates/pardus-kg/src/discovery.rs b/crates/open-kg/src/discovery.rs similarity index 98% rename from crates/pardus-kg/src/discovery.rs rename to crates/open-kg/src/discovery.rs index 11a6db7..7e4bf67 100644 --- a/crates/pardus-kg/src/discovery.rs +++ b/crates/open-kg/src/discovery.rs @@ -1,7 +1,7 @@ use scraper::{Html, Selector}; use std::sync::LazyLock as Lazy; -use pardus_core::NavigationGraph; +use open_core::NavigationGraph; use crate::state::ViewStateId; use crate::transition::Trigger; @@ -77,7 +77,7 @@ pub fn discover_hash_transitions(html: &Html, page_url: &str) -> Vec Vec { let mut results = Vec::new(); diff --git a/crates/pardus-kg/src/fingerprint.rs b/crates/open-kg/src/fingerprint.rs similarity index 97% rename from crates/pardus-kg/src/fingerprint.rs rename to crates/open-kg/src/fingerprint.rs index 059ea94..470c92b 100644 --- a/crates/pardus-kg/src/fingerprint.rs +++ b/crates/open-kg/src/fingerprint.rs @@ -1,6 +1,6 @@ use std::collections::{BTreeMap, HashSet}; -use pardus_core::{SemanticNode, SemanticTree}; +use open_core::{SemanticNode, SemanticTree}; use scraper::Html; use url::Url; @@ -40,7 +40,7 @@ pub fn compute_fingerprint( /// Discover subresource URLs from HTML. pub fn discover_resources(html: &Html, base_url: &str) -> HashSet { - let records = pardus_debug::discover::discover_subresources(html, base_url, 0); + let records = open_debug::discover::discover_subresources(html, base_url, 0); records.into_iter().map(|r| r.url).collect() } diff --git a/crates/pardus-kg/src/graph.rs b/crates/open-kg/src/graph.rs similarity index 100% rename from crates/pardus-kg/src/graph.rs rename to crates/open-kg/src/graph.rs diff --git a/crates/pardus-kg/src/lib.rs b/crates/open-kg/src/lib.rs similarity index 100% rename from crates/pardus-kg/src/lib.rs rename to crates/open-kg/src/lib.rs diff --git a/crates/pardus-kg/src/output.rs b/crates/open-kg/src/output.rs similarity index 100% rename from crates/pardus-kg/src/output.rs rename to crates/open-kg/src/output.rs diff --git a/crates/pardus-kg/src/state.rs b/crates/open-kg/src/state.rs similarity index 87% rename from crates/pardus-kg/src/state.rs rename to crates/open-kg/src/state.rs index 5449b49..7f75e17 100644 --- a/crates/pardus-kg/src/state.rs +++ b/crates/open-kg/src/state.rs @@ -1,8 +1,8 @@ use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashSet}; -use pardus_core::NavigationGraph; -use pardus_core::SemanticTree; +use open_core::NavigationGraph; +use open_core::SemanticTree; /// Unique fingerprint identifying a distinct page state. #[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] @@ -33,10 +33,10 @@ pub struct ViewState { pub fragment: Option, /// Fingerprint components. pub fingerprint: Fingerprint, - /// Semantic tree from pardus-core (only when `store_full_trees` is enabled). + /// Semantic tree from open-core (only when `store_full_trees` is enabled). #[serde(skip_serializing_if = "Option::is_none")] pub semantic_tree: Option, - /// Navigation graph from pardus-core (only when `store_full_trees` is enabled). + /// Navigation graph from open-core (only when `store_full_trees` is enabled). #[serde(skip_serializing_if = "Option::is_none")] pub navigation_graph: Option, /// The set of subresource URLs loaded by this state. diff --git a/crates/pardus-kg/src/transition.rs b/crates/open-kg/src/transition.rs similarity index 100% rename from crates/pardus-kg/src/transition.rs rename to crates/open-kg/src/transition.rs diff --git a/crates/pardus-server/Cargo.toml b/crates/open-server/Cargo.toml similarity index 77% rename from crates/pardus-server/Cargo.toml rename to crates/open-server/Cargo.toml index a22d722..759e9e9 100644 --- a/crates/pardus-server/Cargo.toml +++ b/crates/open-server/Cargo.toml @@ -1,16 +1,16 @@ [package] -name = "pardus-server" +name = "open-server" version.workspace = true edition.workspace = true license.workspace = true [[bin]] -name = "pardus-server" +name = "open-server" path = "src/main.rs" [dependencies] -pardus-core = { path = "../pardus-core", default-features = false, features = [] } -pardus-debug = { path = "../pardus-debug" } +open-core = { path = "../open-core", default-features = false, features = [] } +open-debug = { path = "../open-debug" } axum = { version = "0.8", features = ["ws"] } tokio = { workspace = true } serde = { workspace = true } diff --git a/crates/pardus-server/src/events.rs b/crates/open-server/src/events.rs similarity index 100% rename from crates/pardus-server/src/events.rs rename to crates/open-server/src/events.rs diff --git a/crates/pardus-server/src/handlers.rs b/crates/open-server/src/handlers.rs similarity index 100% rename from crates/pardus-server/src/handlers.rs rename to crates/open-server/src/handlers.rs diff --git a/crates/pardus-server/src/main.rs b/crates/open-server/src/main.rs similarity index 78% rename from crates/pardus-server/src/main.rs rename to crates/open-server/src/main.rs index 89de246..bc84429 100644 --- a/crates/pardus-server/src/main.rs +++ b/crates/open-server/src/main.rs @@ -8,7 +8,7 @@ mod ws; use clap::Parser; #[derive(Parser, Debug)] -#[command(name = "pardus-server", about = "Pardus browser HTTP/WebSocket server with web UI")] +#[command(name = "open-server", about = "Open browser HTTP/WebSocket server with web UI")] struct Args { /// Host to bind to #[arg(long, default_value = "127.0.0.1")] @@ -26,7 +26,7 @@ struct Args { #[tokio::main] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt() - .with_env_filter("pardus_server=info,tower_http=info") + .with_env_filter("open_server=info,tower_http=info") .init(); let args = Args::parse(); @@ -36,7 +36,7 @@ async fn main() -> anyhow::Result<()> { let app = router::build_router(server_state, args.dev); let listener = tokio::net::TcpListener::bind(&addr).await?; - tracing::info!("Pardus server listening on http://{}", addr); + tracing::info!("Open server listening on http://{}", addr); axum::serve(listener, app).await?; diff --git a/crates/pardus-server/src/router.rs b/crates/open-server/src/router.rs similarity index 100% rename from crates/pardus-server/src/router.rs rename to crates/open-server/src/router.rs diff --git a/crates/pardus-server/src/state.rs b/crates/open-server/src/state.rs similarity index 97% rename from crates/pardus-server/src/state.rs rename to crates/open-server/src/state.rs index a66d03c..e88576b 100644 --- a/crates/pardus-server/src/state.rs +++ b/crates/open-server/src/state.rs @@ -1,10 +1,10 @@ use std::{collections::HashMap, sync::Arc}; use anyhow::Result; -use pardus_core::{ +use open_core::{ Browser, BrowserConfig, CookieEntry, ElementHandle, FormState, PageSnapshot, ScrollDirection, }; -use pardus_debug::NetworkRecord; +use open_debug::NetworkRecord; use tokio::sync::{broadcast, mpsc, oneshot}; use crate::events::ServerEvent; @@ -255,13 +255,13 @@ async fn handle_cmd( } }, BrowserCmd::CloseTab { id, reply } => { - let tab_id = pardus_core::TabId::from_u64(id); + let tab_id = open_core::TabId::from_u64(id); browser.close_tab(tab_id); let _ = event_tx.send(ServerEvent::TabClosed { id }); let _ = reply.send(Ok(BrowserResponse::Ok { ok: true })); } BrowserCmd::ActivateTab { id, reply } => { - let tab_id = pardus_core::TabId::from_u64(id); + let tab_id = open_core::TabId::from_u64(id); match browser.switch_to(tab_id).await { Ok(tab) => { let _ = event_tx.send(ServerEvent::TabActivated { id }); @@ -392,7 +392,7 @@ async fn handle_cmd( } BrowserCmd::NetworkHar { reply } => { let log = browser.network_log().lock().unwrap(); - let har = pardus_debug::har::HarFile::from_network_log(&log); + let har = open_debug::har::HarFile::from_network_log(&log); let val = serde_json::to_value(&har).unwrap_or_default(); let _ = reply.send(Ok(BrowserResponse::Har(val))); } @@ -422,7 +422,7 @@ async fn handle_cmd( } /// Collect all interactive nodes as flat JSON values. -fn collect_interactive_flat(node: &pardus_core::SemanticNode) -> Vec { +fn collect_interactive_flat(node: &open_core::SemanticNode) -> Vec { let mut result = Vec::new(); if node.is_interactive { result.push(serde_json::to_value(node).unwrap_or_default()); @@ -435,9 +435,9 @@ fn collect_interactive_flat(node: &pardus_core::SemanticNode) -> Vec( - node: &'a pardus_core::SemanticNode, + node: &'a open_core::SemanticNode, id: usize, -) -> Option<&'a pardus_core::SemanticNode> { +) -> Option<&'a open_core::SemanticNode> { if node.element_id == Some(id) { return Some(node); } diff --git a/crates/pardus-server/src/static_files.rs b/crates/open-server/src/static_files.rs similarity index 100% rename from crates/pardus-server/src/static_files.rs rename to crates/open-server/src/static_files.rs diff --git a/crates/pardus-server/src/ws.rs b/crates/open-server/src/ws.rs similarity index 100% rename from crates/pardus-server/src/ws.rs rename to crates/open-server/src/ws.rs diff --git a/crates/pardus-tauri/frontend/index.html b/crates/open-tauri/frontend/index.html similarity index 89% rename from crates/pardus-tauri/frontend/index.html rename to crates/open-tauri/frontend/index.html index 2fe6772..f58ea88 100644 --- a/crates/pardus-tauri/frontend/index.html +++ b/crates/open-tauri/frontend/index.html @@ -3,7 +3,7 @@ - Pardus Mission Control + Open Mission Control diff --git a/crates/pardus-tauri/frontend/package-lock.json b/crates/open-tauri/frontend/package-lock.json similarity index 99% rename from crates/pardus-tauri/frontend/package-lock.json rename to crates/open-tauri/frontend/package-lock.json index 7d4b873..1744b91 100644 --- a/crates/pardus-tauri/frontend/package-lock.json +++ b/crates/open-tauri/frontend/package-lock.json @@ -1,11 +1,11 @@ { - "name": "pardus-mission-control", + "name": "open-mission-control", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "pardus-mission-control", + "name": "open-mission-control", "version": "0.1.0", "dependencies": { "@tauri-apps/api": "^2.0.0", diff --git a/crates/pardus-tauri/frontend/package.json b/crates/open-tauri/frontend/package.json similarity index 94% rename from crates/pardus-tauri/frontend/package.json rename to crates/open-tauri/frontend/package.json index dd92c0c..5a47100 100644 --- a/crates/pardus-tauri/frontend/package.json +++ b/crates/open-tauri/frontend/package.json @@ -1,5 +1,5 @@ { - "name": "pardus-mission-control", + "name": "open-mission-control", "private": true, "version": "0.1.0", "type": "module", diff --git a/crates/pardus-tauri/frontend/src/App.tsx b/crates/open-tauri/frontend/src/App.tsx similarity index 96% rename from crates/pardus-tauri/frontend/src/App.tsx rename to crates/open-tauri/frontend/src/App.tsx index af27144..16a2aa5 100644 --- a/crates/pardus-tauri/frontend/src/App.tsx +++ b/crates/open-tauri/frontend/src/App.tsx @@ -24,13 +24,13 @@ type Theme = "dark" | "light"; function useTheme(): [Theme, () => void] { const [theme, setTheme] = useState(() => { - const saved = localStorage.getItem("pardus-theme") as Theme | null; + const saved = localStorage.getItem("open-theme") as Theme | null; return saved ?? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"); }); useEffect(() => { document.documentElement.setAttribute("data-theme", theme); - localStorage.setItem("pardus-theme", theme); + localStorage.setItem("open-theme", theme); }, [theme]); return [theme, () => setTheme((t) => (t === "dark" ? "light" : "dark"))]; @@ -114,7 +114,7 @@ function WelcomeState() {
{"\u{1F578}"}
- Pardus Mission Control + Open Mission Control
Headless browser for AI agents. Spawn an instance, navigate to a page, diff --git a/crates/pardus-tauri/frontend/src/api/tauri.ts b/crates/open-tauri/frontend/src/api/tauri.ts similarity index 100% rename from crates/pardus-tauri/frontend/src/api/tauri.ts rename to crates/open-tauri/frontend/src/api/tauri.ts diff --git a/crates/pardus-tauri/frontend/src/components/ActionLog.tsx b/crates/open-tauri/frontend/src/components/ActionLog.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/ActionLog.tsx rename to crates/open-tauri/frontend/src/components/ActionLog.tsx diff --git a/crates/pardus-tauri/frontend/src/components/AgentCard.tsx b/crates/open-tauri/frontend/src/components/AgentCard.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/AgentCard.tsx rename to crates/open-tauri/frontend/src/components/AgentCard.tsx diff --git a/crates/pardus-tauri/frontend/src/components/AgentGrid.tsx b/crates/open-tauri/frontend/src/components/AgentGrid.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/AgentGrid.tsx rename to crates/open-tauri/frontend/src/components/AgentGrid.tsx diff --git a/crates/pardus-tauri/frontend/src/components/AgentSidebar.tsx b/crates/open-tauri/frontend/src/components/AgentSidebar.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/AgentSidebar.tsx rename to crates/open-tauri/frontend/src/components/AgentSidebar.tsx diff --git a/crates/pardus-tauri/frontend/src/components/ChallengePanel.tsx b/crates/open-tauri/frontend/src/components/ChallengePanel.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/ChallengePanel.tsx rename to crates/open-tauri/frontend/src/components/ChallengePanel.tsx diff --git a/crates/pardus-tauri/frontend/src/components/ChatPanel.tsx b/crates/open-tauri/frontend/src/components/ChatPanel.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/ChatPanel.tsx rename to crates/open-tauri/frontend/src/components/ChatPanel.tsx diff --git a/crates/pardus-tauri/frontend/src/components/GlobalActionStream.tsx b/crates/open-tauri/frontend/src/components/GlobalActionStream.tsx similarity index 100% rename from crates/pardus-tauri/frontend/src/components/GlobalActionStream.tsx rename to crates/open-tauri/frontend/src/components/GlobalActionStream.tsx diff --git a/crates/pardus-tauri/frontend/src/components/InstanceHeader.tsx b/crates/open-tauri/frontend/src/components/InstanceHeader.tsx similarity index 95% rename from crates/pardus-tauri/frontend/src/components/InstanceHeader.tsx rename to crates/open-tauri/frontend/src/components/InstanceHeader.tsx index 03a4bc9..c32b19a 100644 --- a/crates/pardus-tauri/frontend/src/components/InstanceHeader.tsx +++ b/crates/open-tauri/frontend/src/components/InstanceHeader.tsx @@ -20,7 +20,7 @@ export function InstanceHeader({ const [url, setUrl] = useState(""); const [navigating, setNavigating] = useState(false); const [theme, setTheme] = useState<"dark" | "light">(() => - (localStorage.getItem("pardus-theme") as "dark" | "light") ?? + (localStorage.getItem("open-theme") as "dark" | "light") ?? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark"), ); @@ -34,7 +34,7 @@ export function InstanceHeader({ setTheme((t) => { const next = t === "dark" ? "light" : "dark"; document.documentElement.setAttribute("data-theme", next); - localStorage.setItem("pardus-theme", next); + localStorage.setItem("open-theme", next); return next; }); }, []); @@ -63,7 +63,7 @@ export function InstanceHeader({ return (
- Pardus + Open Mission Control