From 8674b60b4e99fd50324c370388702a8d83a6ce06 Mon Sep 17 00:00:00 2001 From: Jacob Magar Date: Sat, 11 Apr 2026 00:10:38 -0400 Subject: [PATCH] chore: rebrand webclaw to noxa --- .github/banner.png | Bin 44694 -> 0 bytes .github/workflows/deps.yml | 10 +- .github/workflows/release.yml | 68 +- CHANGELOG.md | 24 +- CLAUDE.md | 76 +- CODE_OF_CONDUCT.md | 38 - CONTRIBUTING.md | 118 ---- Cargo.lock | 206 +++--- Cargo.toml | 11 +- Dockerfile | 34 +- Dockerfile.ci | 6 +- LICENSE | 661 ------------------ README.md | 144 ++-- SKILL.md | 96 +-- assets/demo.gif | Bin 535924 -> 0 bytes assets/demo.mp4 | Bin 177411 -> 0 bytes benchmarks/README.md | 38 +- crates/{webclaw-cli => noxa-cli}/Cargo.toml | 12 +- crates/{webclaw-cli => noxa-cli}/src/cloud.rs | 16 +- crates/{webclaw-cli => noxa-cli}/src/main.rs | 84 +-- crates/{webclaw-core => noxa-core}/Cargo.toml | 2 +- .../{webclaw-core => noxa-core}/src/brand.rs | 0 .../src/data_island.rs | 0 .../{webclaw-core => noxa-core}/src/diff.rs | 0 .../{webclaw-core => noxa-core}/src/domain.rs | 0 .../{webclaw-core => noxa-core}/src/error.rs | 0 .../src/extractor.rs | 0 .../src/js_eval.rs | 0 crates/{webclaw-core => noxa-core}/src/lib.rs | 2 +- .../src/llm/body.rs | 0 .../src/llm/cleanup.rs | 0 .../src/llm/images.rs | 0 .../src/llm/links.rs | 0 .../src/llm/metadata.rs | 0 .../src/llm/mod.rs | 0 .../src/markdown.rs | 0 .../src/metadata.rs | 0 .../{webclaw-core => noxa-core}/src/noise.rs | 0 .../src/structured_data.rs | 0 .../{webclaw-core => noxa-core}/src/types.rs | 0 .../src/youtube.rs | 0 .../testdata/express_test.html | 0 .../{webclaw-fetch => noxa-fetch}/Cargo.toml | 6 +- .../src/browser.rs | 4 +- .../src/client.rs | 42 +- .../src/crawler.rs | 2 +- .../src/document.rs | 8 +- .../src/error.rs | 4 +- .../{webclaw-fetch => noxa-fetch}/src/lib.rs | 6 +- .../src/linkedin.rs | 2 +- .../src/proxy.rs | 0 .../src/reddit.rs | 2 +- .../src/sitemap.rs | 0 .../{webclaw-fetch => noxa-fetch}/src/tls.rs | 2 +- crates/{webclaw-llm => noxa-llm}/Cargo.toml | 4 +- crates/{webclaw-llm => noxa-llm}/src/chain.rs | 0 crates/{webclaw-llm => noxa-llm}/src/clean.rs | 0 crates/{webclaw-llm => noxa-llm}/src/error.rs | 0 .../{webclaw-llm => noxa-llm}/src/extract.rs | 0 crates/{webclaw-llm => noxa-llm}/src/lib.rs | 4 +- .../{webclaw-llm => noxa-llm}/src/provider.rs | 0 .../src/providers/anthropic.rs | 2 +- .../src/providers/mod.rs | 2 +- .../src/providers/ollama.rs | 2 +- .../src/providers/openai.rs | 2 +- .../src/summarize.rs | 0 .../{webclaw-llm => noxa-llm}/src/testing.rs | 2 +- crates/{webclaw-mcp => noxa-mcp}/Cargo.toml | 14 +- crates/{webclaw-mcp => noxa-mcp}/src/cloud.rs | 25 +- crates/{webclaw-mcp => noxa-mcp}/src/main.rs | 6 +- .../{webclaw-mcp => noxa-mcp}/src/server.rs | 124 ++-- crates/{webclaw-mcp => noxa-mcp}/src/tools.rs | 0 crates/{webclaw-pdf => noxa-pdf}/Cargo.toml | 4 +- crates/{webclaw-pdf => noxa-pdf}/src/error.rs | 0 crates/{webclaw-pdf => noxa-pdf}/src/lib.rs | 2 +- deploy/hetzner.sh | 513 -------------- docker-compose.yml | 6 +- env.example | 28 +- examples/README.md | 152 ++-- glama.json | 6 - .../{create-webclaw => create-noxa}/README.md | 42 +- .../{create-webclaw => create-noxa}/index.mjs | 68 +- .../package.json | 16 +- proxies.example.txt | 4 +- setup.sh | 54 +- skill/SKILL.md | 96 +-- 86 files changed, 781 insertions(+), 2121 deletions(-) delete mode 100644 .github/banner.png delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 CONTRIBUTING.md delete mode 100644 LICENSE delete mode 100644 assets/demo.gif delete mode 100644 assets/demo.mp4 rename crates/{webclaw-cli => noxa-cli}/Cargo.toml (74%) rename crates/{webclaw-cli => noxa-cli}/src/cloud.rs (81%) rename crates/{webclaw-cli => noxa-cli}/src/main.rs (96%) rename crates/{webclaw-core => noxa-core}/Cargo.toml (96%) rename crates/{webclaw-core => noxa-core}/src/brand.rs (100%) rename crates/{webclaw-core => noxa-core}/src/data_island.rs (100%) rename crates/{webclaw-core => noxa-core}/src/diff.rs (100%) rename crates/{webclaw-core => noxa-core}/src/domain.rs (100%) rename crates/{webclaw-core => noxa-core}/src/error.rs (100%) rename crates/{webclaw-core => noxa-core}/src/extractor.rs (100%) rename crates/{webclaw-core => noxa-core}/src/js_eval.rs (100%) rename crates/{webclaw-core => noxa-core}/src/lib.rs (99%) rename crates/{webclaw-core => noxa-core}/src/llm/body.rs (100%) rename crates/{webclaw-core => noxa-core}/src/llm/cleanup.rs (100%) rename crates/{webclaw-core => noxa-core}/src/llm/images.rs (100%) rename crates/{webclaw-core => noxa-core}/src/llm/links.rs (100%) rename crates/{webclaw-core => noxa-core}/src/llm/metadata.rs (100%) rename crates/{webclaw-core => noxa-core}/src/llm/mod.rs (100%) rename crates/{webclaw-core => noxa-core}/src/markdown.rs (100%) rename crates/{webclaw-core => noxa-core}/src/metadata.rs (100%) rename crates/{webclaw-core => noxa-core}/src/noise.rs (100%) rename crates/{webclaw-core => noxa-core}/src/structured_data.rs (100%) rename crates/{webclaw-core => noxa-core}/src/types.rs (100%) rename crates/{webclaw-core => noxa-core}/src/youtube.rs (100%) rename crates/{webclaw-core => noxa-core}/testdata/express_test.html (100%) rename crates/{webclaw-fetch => noxa-fetch}/Cargo.toml (85%) rename crates/{webclaw-fetch => noxa-fetch}/src/browser.rs (89%) rename crates/{webclaw-fetch => noxa-fetch}/src/client.rs (95%) rename crates/{webclaw-fetch => noxa-fetch}/src/crawler.rs (99%) rename crates/{webclaw-fetch => noxa-fetch}/src/document.rs (99%) rename crates/{webclaw-fetch => noxa-fetch}/src/error.rs (85%) rename crates/{webclaw-fetch => noxa-fetch}/src/lib.rs (75%) rename crates/{webclaw-fetch => noxa-fetch}/src/linkedin.rs (99%) rename crates/{webclaw-fetch => noxa-fetch}/src/proxy.rs (100%) rename crates/{webclaw-fetch => noxa-fetch}/src/reddit.rs (98%) rename crates/{webclaw-fetch => noxa-fetch}/src/sitemap.rs (100%) rename crates/{webclaw-fetch => noxa-fetch}/src/tls.rs (99%) rename crates/{webclaw-llm => noxa-llm}/Cargo.toml (73%) rename crates/{webclaw-llm => noxa-llm}/src/chain.rs (100%) rename crates/{webclaw-llm => noxa-llm}/src/clean.rs (100%) rename crates/{webclaw-llm => noxa-llm}/src/error.rs (100%) rename crates/{webclaw-llm => noxa-llm}/src/extract.rs (100%) rename crates/{webclaw-llm => noxa-llm}/src/lib.rs (80%) rename crates/{webclaw-llm => noxa-llm}/src/provider.rs (100%) rename crates/{webclaw-llm => noxa-llm}/src/providers/anthropic.rs (98%) rename crates/{webclaw-llm => noxa-llm}/src/providers/mod.rs (92%) rename crates/{webclaw-llm => noxa-llm}/src/providers/ollama.rs (98%) rename crates/{webclaw-llm => noxa-llm}/src/providers/openai.rs (98%) rename crates/{webclaw-llm => noxa-llm}/src/summarize.rs (100%) rename crates/{webclaw-llm => noxa-llm}/src/testing.rs (96%) rename crates/{webclaw-mcp => noxa-mcp}/Cargo.toml (68%) rename crates/{webclaw-mcp => noxa-mcp}/src/cloud.rs (92%) rename crates/{webclaw-mcp => noxa-mcp}/src/main.rs (79%) rename crates/{webclaw-mcp => noxa-mcp}/src/server.rs (85%) rename crates/{webclaw-mcp => noxa-mcp}/src/tools.rs (100%) rename crates/{webclaw-pdf => noxa-pdf}/Cargo.toml (72%) rename crates/{webclaw-pdf => noxa-pdf}/src/error.rs (100%) rename crates/{webclaw-pdf => noxa-pdf}/src/lib.rs (99%) delete mode 100755 deploy/hetzner.sh delete mode 100644 glama.json rename packages/{create-webclaw => create-noxa}/README.md (68%) rename packages/{create-webclaw => create-noxa}/index.mjs (88%) rename packages/{create-webclaw => create-noxa}/package.json (58%) diff --git a/.github/banner.png b/.github/banner.png deleted file mode 100644 index 07a6673f88d442b0014f618bb61516787a99b059..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44694 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�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 diff --git a/.github/workflows/deps.yml b/.github/workflows/deps.yml index 29e851b..352ca3e 100644 --- a/.github/workflows/deps.yml +++ b/.github/workflows/deps.yml @@ -11,7 +11,7 @@ env: jobs: sync-tls: - name: Update webclaw-tls dependencies + name: Update noxa-tls dependencies runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -20,9 +20,9 @@ jobs: - uses: dtolnay/rust-toolchain@stable - - name: Update webclaw-tls crates + - name: Update noxa-tls crates run: | - cargo update -p webclaw-http -p rustls -p 'h2@0.4' -p 'hyper@1' -p 'hyper-util@0.1' -p 'reqwest@0.13' 2>&1 + cargo update -p noxa-http -p rustls -p 'h2@0.4' -p 'hyper@1' -p 'hyper-util@0.1' -p 'reqwest@0.13' 2>&1 - name: Check for changes id: diff @@ -39,13 +39,13 @@ jobs: git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add Cargo.lock - git commit -m "chore: update webclaw-tls dependencies" + git commit -m "chore: update noxa-tls dependencies" git push - name: Trigger server update if: steps.diff.outputs.changed == 'true' run: | - gh api repos/0xMassi/webclaw-server/dispatches \ + gh api repos/0xMassi/noxa-server/dispatches \ -f event_type=core-updated \ -f client_payload[sha]=${{ github.sha }} env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 95be38f..abadb4b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,10 +64,10 @@ jobs: shell: bash run: | tag="${GITHUB_REF#refs/tags/}" - staging="webclaw-${tag}-${{ matrix.target }}" + staging="noxa-${tag}-${{ matrix.target }}" mkdir "$staging" - cp target/${{ matrix.target }}/release/webclaw "$staging/" 2>/dev/null || true - cp target/${{ matrix.target }}/release/webclaw-mcp "$staging/" 2>/dev/null || true + cp target/${{ matrix.target }}/release/noxa "$staging/" 2>/dev/null || true + cp target/${{ matrix.target }}/release/noxa-mcp "$staging/" 2>/dev/null || true cp README.md LICENSE "$staging/" tar czf "$staging.tar.gz" "$staging" echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV @@ -128,12 +128,12 @@ jobs: run: | tag="${GITHUB_REF#refs/tags/}" for target in x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do - dir="webclaw-${tag}-${target}" - curl -sSL "https://github.com/0xMassi/webclaw/releases/download/${tag}/${dir}.tar.gz" -o "${target}.tar.gz" + dir="noxa-${tag}-${target}" + curl -sSL "https://github.com/0xMassi/noxa/releases/download/${tag}/${dir}.tar.gz" -o "${target}.tar.gz" tar xzf "${target}.tar.gz" mkdir -p "binaries-${target}" - cp "${dir}/webclaw" "binaries-${target}/webclaw" - cp "${dir}/webclaw-mcp" "binaries-${target}/webclaw-mcp" + cp "${dir}/noxa" "binaries-${target}/noxa" + cp "${dir}/noxa-mcp" "binaries-${target}/noxa-mcp" chmod +x "binaries-${target}"/* done ls -laR binaries-*/ @@ -145,22 +145,22 @@ jobs: # amd64 docker build -f Dockerfile.ci --build-arg BINARY_DIR=binaries-x86_64-unknown-linux-gnu \ - --platform linux/amd64 -t ghcr.io/0xmassi/webclaw:${tag}-amd64 --push . + --platform linux/amd64 -t ghcr.io/0xmassi/noxa:${tag}-amd64 --push . # arm64 docker build -f Dockerfile.ci --build-arg BINARY_DIR=binaries-aarch64-unknown-linux-gnu \ - --platform linux/arm64 -t ghcr.io/0xmassi/webclaw:${tag}-arm64 --push . + --platform linux/arm64 -t ghcr.io/0xmassi/noxa:${tag}-arm64 --push . # Multi-arch manifest - docker manifest create ghcr.io/0xmassi/webclaw:${tag} \ - ghcr.io/0xmassi/webclaw:${tag}-amd64 \ - ghcr.io/0xmassi/webclaw:${tag}-arm64 - docker manifest push ghcr.io/0xmassi/webclaw:${tag} + docker manifest create ghcr.io/0xmassi/noxa:${tag} \ + ghcr.io/0xmassi/noxa:${tag}-amd64 \ + ghcr.io/0xmassi/noxa:${tag}-arm64 + docker manifest push ghcr.io/0xmassi/noxa:${tag} - docker manifest create ghcr.io/0xmassi/webclaw:latest \ - ghcr.io/0xmassi/webclaw:${tag}-amd64 \ - ghcr.io/0xmassi/webclaw:${tag}-arm64 - docker manifest push ghcr.io/0xmassi/webclaw:latest + docker manifest create ghcr.io/0xmassi/noxa:latest \ + ghcr.io/0xmassi/noxa:${tag}-amd64 \ + ghcr.io/0xmassi/noxa:${tag}-arm64 + docker manifest push ghcr.io/0xmassi/noxa:latest homebrew: name: Update Homebrew @@ -172,11 +172,11 @@ jobs: COMMITTER_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} run: | tag="${GITHUB_REF#refs/tags/}" - base="https://github.com/0xMassi/webclaw/releases/download/${tag}" + base="https://github.com/0xMassi/noxa/releases/download/${tag}" # Download all 4 tarballs and compute SHAs for target in aarch64-apple-darwin x86_64-apple-darwin aarch64-unknown-linux-gnu x86_64-unknown-linux-gnu; do - curl -sSL "${base}/webclaw-${tag}-${target}.tar.gz" -o "${target}.tar.gz" + curl -sSL "${base}/noxa-${tag}-${target}.tar.gz" -o "${target}.tar.gz" done SHA_MAC_ARM=$(sha256sum aarch64-apple-darwin.tar.gz | cut -d' ' -f1) @@ -190,53 +190,53 @@ jobs: echo "Linux x86_64: $SHA_LINUX_X86" # Generate formula - cat > webclaw.rb << FORMULA - class Webclaw < Formula + cat > noxa.rb << FORMULA + class Noxa < Formula desc "The fastest web scraper for AI agents. 67% fewer tokens. Sub-ms extraction." - homepage "https://webclaw.io" + homepage "https://noxa.io" license "AGPL-3.0" version "${tag#v}" on_macos do if Hardware::CPU.arm? - url "${base}/webclaw-${tag}-aarch64-apple-darwin.tar.gz" + url "${base}/noxa-${tag}-aarch64-apple-darwin.tar.gz" sha256 "${SHA_MAC_ARM}" else - url "${base}/webclaw-${tag}-x86_64-apple-darwin.tar.gz" + url "${base}/noxa-${tag}-x86_64-apple-darwin.tar.gz" sha256 "${SHA_MAC_X86}" end end on_linux do if Hardware::CPU.arm? - url "${base}/webclaw-${tag}-aarch64-unknown-linux-gnu.tar.gz" + url "${base}/noxa-${tag}-aarch64-unknown-linux-gnu.tar.gz" sha256 "${SHA_LINUX_ARM}" else - url "${base}/webclaw-${tag}-x86_64-unknown-linux-gnu.tar.gz" + url "${base}/noxa-${tag}-x86_64-unknown-linux-gnu.tar.gz" sha256 "${SHA_LINUX_X86}" end end def install - bin.install "webclaw" - bin.install "webclaw-mcp" + bin.install "noxa" + bin.install "noxa-mcp" end test do - assert_match "webclaw", shell_output("#{bin}/webclaw --version") + assert_match "noxa", shell_output("#{bin}/noxa --version") end end FORMULA # Remove leading whitespace from heredoc - sed -i 's/^ //' webclaw.rb + sed -i 's/^ //' noxa.rb # Push to homebrew tap - git clone "https://x-access-token:${COMMITTER_TOKEN}@github.com/0xMassi/homebrew-webclaw.git" tap - cp webclaw.rb tap/Formula/webclaw.rb + git clone "https://x-access-token:${COMMITTER_TOKEN}@github.com/0xMassi/homebrew-noxa.git" tap + cp noxa.rb tap/Formula/noxa.rb cd tap git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add Formula/webclaw.rb - git diff --cached --quiet || git commit -m "Update webclaw to ${tag}" + git add Formula/noxa.rb + git diff --cached --quiet || git commit -m "Update noxa to ${tag}" git push diff --git a/CHANGELOG.md b/CHANGELOG.md index cbe6897..c65ca0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to webclaw are documented here. +All notable changes to noxa are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/). ## [0.3.11] — 2026-04-10 @@ -33,19 +33,19 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). ## [0.3.8] — 2026-04-03 ### Fixed -- **MCP research token overflow**: research results are now saved to `~/.webclaw/research/` and the MCP tool returns file paths + findings instead of the full report. Prevents "exceeds maximum allowed tokens" errors in Claude/Cursor. +- **MCP research token overflow**: research results are now saved to `~/.noxa/research/` and the MCP tool returns file paths + findings instead of the full report. Prevents "exceeds maximum allowed tokens" errors in Claude/Cursor. - **Research caching**: same query returns cached result instantly without spending credits. - **Anthropic rate limit throttling**: 60s delay between LLM calls in research to stay under Tier 1 limits (50K input tokens/min). ### Added -- **`dirs` dependency** for `~/.webclaw/research/` path resolution. +- **`dirs` dependency** for `~/.noxa/research/` path resolution. --- ## [0.3.7] — 2026-04-03 ### Added - **`--research` CLI flag**: run deep research via the cloud API. Prints report to stdout and saves full result (report + sources + findings) to a JSON file. Supports `--deep` for longer reports. -- **MCP extract/summarize cloud fallback**: when no local LLM is available, these tools now fall back to the cloud API instead of erroring. Set `WEBCLAW_API_KEY` for automatic fallback. +- **MCP extract/summarize cloud fallback**: when no local LLM is available, these tools now fall back to the cloud API instead of erroring. Set `NOXA_API_KEY` for automatic fallback. - **MCP research structured output**: the research tool now returns structured JSON (report + sources + findings + metadata) instead of raw text, so agents can reference individual findings and source URLs. --- @@ -80,13 +80,13 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). ## [0.3.3] — 2026-04-01 ### Changed -- **Replaced custom TLS stack with wreq**: migrated from webclaw-tls (patched rustls/h2/hyper/reqwest) to [wreq](https://github.com/0x676e67/wreq) by [@0x676e67](https://github.com/0x676e67). wreq uses BoringSSL for TLS and the [http2](https://github.com/0x676e67/http2) crate for HTTP/2 fingerprinting — both battle-tested with 60+ browser profiles. -- **Removed all `[patch.crates-io]` entries**: consumers no longer need to patch rustls, h2, hyper, hyper-util, or reqwest. Just depend on webclaw normally. +- **Replaced custom TLS stack with wreq**: migrated from noxa-tls (patched rustls/h2/hyper/reqwest) to [wreq](https://github.com/0x676e67/wreq) by [@0x676e67](https://github.com/0x676e67). wreq uses BoringSSL for TLS and the [http2](https://github.com/0x676e67/http2) crate for HTTP/2 fingerprinting — both battle-tested with 60+ browser profiles. +- **Removed all `[patch.crates-io]` entries**: consumers no longer need to patch rustls, h2, hyper, hyper-util, or reqwest. Just depend on noxa normally. - **Browser profiles rebuilt on wreq's Emulation API**: Chrome 145, Firefox 135, Safari 18, Edge 145 with correct TLS options (cipher suites, curves, GREASE, ECH, PSK session resumption), HTTP/2 SETTINGS ordering, pseudo-header order, and header wire order. - **Better TLS compatibility**: BoringSSL handles more server configurations than patched rustls (e.g. servers that previously returned IllegalParameter alerts). ### Removed -- webclaw-tls dependency and all 5 forked crates (webclaw-rustls, webclaw-h2, webclaw-hyper, webclaw-hyper-util, webclaw-reqwest). +- noxa-tls dependency and all 5 forked crates (noxa-rustls, noxa-h2, noxa-hyper, noxa-hyper-util, noxa-reqwest). ### Acknowledgments - TLS and HTTP/2 fingerprinting powered by [wreq](https://github.com/0x676e67/wreq) and [http2](https://github.com/0x676e67/http2) by [@0x676e67](https://github.com/0x676e67), who pioneered browser-grade HTTP/2 fingerprinting in Rust. @@ -114,7 +114,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). ## [0.3.0] — 2026-03-29 ### Changed -- **Replaced primp with webclaw-tls**: switched to custom TLS fingerprinting stack. +- **Replaced primp with noxa-tls**: switched to custom TLS fingerprinting stack. - **Browser profiles**: Chrome 146 (Win/Mac), Firefox 135+, Safari 18, Edge 146 — captured from real browsers. - **HTTP/2 fingerprinting**: SETTINGS frame ordering and pseudo-header ordering based on concepts pioneered by [@0x676e67](https://github.com/0x676e67). @@ -141,7 +141,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/). ## [0.2.1] — 2026-03-27 ### Added -- **Docker image on GHCR**: `docker run ghcr.io/0xmassi/webclaw` — auto-built on every release +- **Docker image on GHCR**: `docker run ghcr.io/0xmassi/noxa` — auto-built on every release - **QuickJS data island extraction**: inline `