Compare commits

...
Author SHA1 Message Date
ArchiveBox Release Bot 736a93cb92 Bump release version to 0.9.35rc517 2026-09-18 22:05:27 +00:00
Nick Sweeting 5c99cdf7c9 Clarify public and private data separation copy 2026-09-18 15:04:59 -07:00
Nick Sweeting 8da338a887 Update homepage archive file access description 2026-09-18 15:03:45 -07:00
ArchiveBox Release Bot 155097ce6f Bump release version to 0.9.35rc516 2026-09-18 22:01:57 +00:00
Nick Sweeting eb9bb069d6 Start macOS quickstart with ArchiveBox app setup wizard 2026-09-18 15:00:08 -07:00
ArchiveBox Release Bot 53523a6a1e Bump release version to 0.9.35rc515 2026-09-18 21:59:37 +00:00
Nick Sweeting ffdc16fc22 Add download icon to macOS quickstart button 2026-09-18 14:58:07 -07:00
ArchiveBox Release Bot 8d14775759 Bump release version to 0.9.35rc514 2026-09-18 21:57:17 +00:00
Nick Sweeting cd5f96c26a Make macOS server download a prominent quickstart button 2026-09-18 14:56:25 -07:00
ArchiveBox Release Bot 877e5f3104 Bump release version to 0.9.35rc513 2026-09-18 21:54:57 +00:00
Nick Sweeting d91ea053a2 Add integration logo stack and TLSNotary authenticity feature 2026-09-18 14:54:41 -07:00
ArchiveBox Release Bot f326097d33 Bump release version to 0.9.35rc512 2026-09-18 21:41:51 +00:00
ArchiveBox Release Bot efa29074f8 Bump for abx-dl 1.12.315 2026-09-18 21:41:30 +00:00
ArchiveBox Release Bot 99fcb02963 Bump release version to 0.9.35rc511 2026-09-18 21:41:16 +00:00
Nick Sweeting e4981957d4 Simplify homepage configuration copy 2026-09-18 14:40:54 -07:00
ArchiveBox Release Bot 8c83947331 Bump release version to 0.9.35rc510 2026-09-18 21:40:50 +00:00
Nick Sweeting 13f9564fa4 Show featured plugin icons beside configuration heading 2026-09-18 14:39:09 -07:00
ArchiveBox Release Bot 4d8b162099 Bump release version to 0.9.35rc509 2026-09-18 21:37:19 +00:00
Nick Sweeting b8d7669c6c Link macOS quickstart artwork to latest Server app download 2026-09-18 14:36:47 -07:00
ArchiveBox Release Bot d08b483c3b Bump release version to 0.9.35rc508 2026-09-18 21:28:21 +00:00
Nick Sweeting f3f7d564e3 Use plus signs in Docker quickstart graphics 2026-09-18 14:27:11 -07:00
Nick Sweeting 38b65fee63 Clarify homepage workflows and link wiki configuration guides 2026-09-18 14:26:44 -07:00
ArchiveBox Release Bot 6580ed01f3 Bump release version to 0.9.35rc507 2026-09-18 21:23:22 +00:00
Nick Sweeting 8cc3d78b3d Illustrate quickstart tabs and add browser extension setup 2026-09-18 14:22:11 -07:00
ArchiveBox Release Bot 1dd74f3ec8 Bump release version to 0.9.35rc506 2026-09-18 21:21:28 +00:00
Nick Sweeting bacd3d053e Link homepage integration items to usage and export guides 2026-09-18 14:20:21 -07:00
ArchiveBox Release Bot 287e792d29 Bump release version to 0.9.35rc505 2026-09-18 21:13:00 +00:00
Nick Sweeting 383adc4e35 Show TLSNotary and crawl options in audience cards 2026-09-18 14:11:21 -07:00
ArchiveBox Release Bot ba740b4568 Bump release version to 0.9.35rc504 2026-09-18 21:09:51 +00:00
Nick Sweeting e7c419ce78 Refine homepage feature headings and card order 2026-09-18 14:08:49 -07:00
Nick Sweeting 363b79e13f Verify OpenCode Home toggles between mounted chats and overview 2026-09-18 14:01:43 -07:00
ArchiveBox Release Bot 05b1c8b829 Bump release version to 0.9.35rc503 2026-09-18 21:00:45 +00:00
ArchiveBox Release Bot cf03d6c8b3 Bump for abx-dl 1.12.314 2026-09-18 20:55:40 +00:00
ArchiveBox Release Bot 6cfdbbd68b Bump release version to 0.9.35rc502 2026-09-18 20:54:41 +00:00
Nick Sweeting 2c0d5584e2 Add compact screenshot thumbnails to homepage cards 2026-09-18 13:54:21 -07:00
ArchiveBox Release Bot 288af543a6 Bump release version to 0.9.35rc501 2026-09-18 20:19:03 +00:00
ArchiveBox Release Bot afeb937db7 Bump for abx-dl 1.12.313 2026-09-18 20:18:01 +00:00
ArchiveBox Release Bot c8a699da0b Bump release version to 0.9.35rc500 2026-09-18 20:08:14 +00:00
Nick Sweeting 6e49cf279f Check OpenCode shutdown releases OAuth and API listeners 2026-09-18 13:07:33 -07:00
ArchiveBox Release Bot 631378a80d Bump release version to 0.9.35rc499 2026-09-18 20:05:50 +00:00
Nick Sweeting 1ef37a02dd Refresh cached homepage styles after mobile layout fix 2026-09-18 13:04:49 -07:00
ArchiveBox Release Bot b618e20fbf Bump release version to 0.9.35rc498 2026-09-18 20:03:23 +00:00
Nick Sweeting 6be2bd85e5 Verify fresh OpenCode drafts promote through real shell submission 2026-09-18 13:02:54 -07:00
Nick Sweeting 8149cc0320 Fix mobile homepage alignment and image overflow 2026-09-18 13:00:44 -07:00
ArchiveBox Release Bot 72b5439137 Bump release version to 0.9.35rc497 2026-09-18 19:45:10 +00:00
Nick Sweeting 8f87aa9e43 Refresh public homepage copy, visuals, and install tabs 2026-09-18 12:44:35 -07:00
ArchiveBox Release Bot e83f2c1808 Bump release version to 0.9.35rc496 2026-09-18 19:30:33 +00:00
ArchiveBox Release Bot a6d56657b2 Bump for abx-dl 1.12.312 2026-09-18 19:30:14 +00:00
ArchiveBox Release Bot 67af2f3a95 Bump release version to 0.9.35rc495 2026-09-18 19:09:45 +00:00
Nick Sweeting b47fc056e3 Install OpenCode only in ArchiveBox application image layers 2026-09-18 12:08:40 -07:00
ArchiveBox Release Bot 007ecaea80 Bump release version to 0.9.35rc494 2026-09-18 19:05:17 +00:00
Nick Sweeting d2eea2e0f1 Allow 900 MiB ArchiveBox images with bundled OpenCode 2026-09-18 12:04:25 -07:00
ArchiveBox Release Bot a88fa72b16 Bump release version to 0.9.35rc493 2026-09-18 19:01:26 +00:00
Nick Sweeting fead132b5c Verify OpenCode provider flows and proxy transports across domain modes 2026-09-18 12:01:10 -07:00
ArchiveBox Release Bot bfef7285f6 Bump release version to 0.9.35rc492 2026-09-18 18:34:44 +00:00
Nick Sweeting 35efcea657 Gate releases on bundled OpenCode and mounted browser tests 2026-09-18 11:34:26 -07:00
ArchiveBox Release Bot 9b58aa30e5 Bump release version to 0.9.35rc491 2026-09-18 18:28:14 +00:00
Nick Sweeting 38dce9b358 Wait for OpenCode draft navigation before checking session links 2026-09-18 11:27:57 -07:00
ArchiveBox Release Bot bc8daf18c0 Bump release version to 0.9.35rc490 2026-09-18 17:52:44 +00:00
ArchiveBox Release Bot 4cd5d170ea Bump for abx-dl 1.12.306 2026-09-18 17:52:28 +00:00
ArchiveBox Release Bot 4ec52a646b Bump release version to 0.9.35rc489 2026-09-18 10:55:18 +00:00
ArchiveBox Release Bot ee78c2c58b Bump for abx-dl 1.12.305 2026-09-18 10:55:03 +00:00
ArchiveBox Release Bot bdfa7f45fc Bump release version to 0.9.35rc488 2026-09-18 10:35:07 +00:00
ArchiveBox Release Bot 1ec5582527 Bump for abx-dl 1.12.304 2026-09-18 10:34:53 +00:00
ArchiveBox Release Bot 75697e4ebf Bump release version to 0.9.35rc487 2026-09-18 10:07:57 +00:00
ArchiveBox Release Bot 7a19792be8 Bump for abx-dl 1.12.302 2026-09-18 10:07:36 +00:00
ArchiveBox Release Bot 601b2db35b Bump release version to 0.9.35rc486 2026-09-18 09:30:14 +00:00
Nick Sweeting 16506ed55a Respect automatic server setup and import private host personas 2026-09-18 02:29:56 -07:00
ArchiveBox Release Bot cc218245c3 Bump release version to 0.9.35rc485 2026-09-18 09:02:15 +00:00
ArchiveBox Release Bot b625cf4958 Bump for abx-dl 1.12.301 2026-09-18 09:01:50 +00:00
ArchiveBox Release Bot 92c0f52324 Bump release version to 0.9.35rc484 2026-09-18 08:43:52 +00:00
Nick Sweeting 880ab87da2 Improve persona import layout and support Chrome Beta profiles 2026-09-18 01:43:19 -07:00
ArchiveBox Release Bot 7e34e43cf5 Bump release version to 0.9.35rc483 2026-09-18 08:31:33 +00:00
Nick Sweeting 4a1e06fda7 Prepare XDG config directory for mounted browser profiles 2026-09-18 01:31:14 -07:00
ArchiveBox Release Bot e1647d8f93 Bump release version to 0.9.35rc482 2026-09-18 08:22:03 +00:00
ArchiveBox Release Bot 0badc70c4d Bump for abx-dl 1.12.300 2026-09-18 08:21:44 +00:00
ArchiveBox Release Bot 9fbddc5b99 Bump release version to 0.9.35rc481 2026-09-18 08:02:08 +00:00
ArchiveBox Release Bot eb7e6f2ba2 Bump for abx-dl 1.12.299 2026-09-18 08:01:47 +00:00
ArchiveBox Release Bot a7eb82ffda Bump release version to 0.9.35rc480 2026-09-18 07:48:43 +00:00
ArchiveBox Release Bot d3f2509c30 Bump for abx-dl 1.12.298 2026-09-18 07:48:16 +00:00
ArchiveBox Release Bot 3e1a31755c Bump release version to 0.9.35rc479 2026-09-18 07:30:56 +00:00
ArchiveBox Release Bot 70bce92bf3 Bump for abx-dl 1.12.297 2026-09-18 07:29:28 +00:00
ArchiveBox Release Bot 80e4a1c4f8 Bump release version to 0.9.35rc478 2026-09-18 06:40:57 +00:00
Nick Sweeting ceb3c04aff Fix explicit DISPLAY handling for Docker noVNC persona setup (#1882)
An explicit `DISPLAY=novnc:0.0` was silently removed by the Docker
entrypoint whenever `xdpyinfo` failed. In the reported `0.9.35rc381`
image, `xdpyinfo` is missing, so `docker compose run --rm` clears the
display even with a healthy noVNC server and Chromium exits with
“Missing X server or $DISPLAY”.

Preserve explicitly supplied `DISPLAY`, including an empty value to opt
out. Probe only the implicit `novnc:0.0` default, retaining automatic
headless fallback when no display was configured. Current dev already
includes `x11-utils`; this change prevents probe failure from overriding
user configuration.

Document the one-off `persona create` / `persona open` Compose flow.
`persona open` resolves Chromium automatically, avoiding the obsolete
`/data/lib/env/bin/chromium` and architecture/version-specific
Playwright paths.

Validation:
- Reproduced persona creation followed by the exact Chromium X11 failure
on the published `0.9.35rc381` image with real, healthy `theasp/novnc`.
- Mounted only the patched entrypoint into that affected image: explicit
DISPLAY survived despite the missing `xdpyinfo`, and the same Chromium
command opened a window visible through noVNC.
- Built the complete branch Docker image using the Dockerfile's default
abx-dl base. Real `docker compose run --rm archivebox persona create
personal` and `persona open personal` succeeded; viewed and controlled
Chromium through noVNC, closed it normally, and reopened in another
one-off container. A bookmark created in the UI persisted across both
runs.
- Added `IMAGE=<built-image> ./bin/validate_docker_display.sh`: six real
Compose checks cover working implicit/explicit displays, unavailable
explicit display, explicit empty opt-out, and implicit/explicit behavior
with noVNC stopped. Passed on the rebuilt image; failed on the unpatched
image at the explicit unavailable-display assertion.
- `bash -n`, `git diff --check`, and pre-commit hooks passed. No mocks
or fake binaries.

Fixes #1872.


<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes the Docker entrypoint silently dropping an explicit `DISPLAY` when
`xdpyinfo` fails, so Chromium can connect to a healthy noVNC server in
images like `0.9.35rc381` where `xdpyinfo` is missing. The entrypoint
previously unset the display on probe failure, causing Chromium to exit
with "Missing X server or $DISPLAY"; now only the implicit `novnc:0.0`
default is probed, an explicit value (including empty to opt out) is
preserved, and headless fallback still applies when no display was
configured. Fixes #1872.

**Validation**
- Adds `bin/validate_docker_display.sh` with six real Compose checks
covering implicit/explicit displays, unavailable display, empty opt-out,
and noVNC stopped behavior.
- Documents the one-off `persona create` / `persona open` Compose flow
and that `persona open` resolves the Chromium binary automatically.

<sup>Written for commit 953f29b65e.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/ArchiveBox/ArchiveBox/pull/1882?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->
2026-09-18 02:39:44 -04:00
Nick Sweeting 953f29b65e Preserve explicit Docker DISPLAY for noVNC persona setup 2026-09-17 23:36:08 -07:00
ArchiveBox Release Bot 404f2efc04 Bump release version to 0.9.35rc477 2026-09-18 06:32:59 +00:00
Nick Sweeting c23389c0a8 Prioritize ArchiveBox projects and TLSNotary in shared footers 2026-09-17 23:27:22 -07:00
ArchiveBox Release Bot 7837373d81 Bump release version to 0.9.35rc476 2026-09-18 06:18:47 +00:00
Nick Sweeting 3600ac54ea docs: remove unnecessary app launch command 2026-09-17 23:17:24 -07:00
ArchiveBox Release Bot ec47877277 Bump release version to 0.9.35rc475 2026-09-18 06:14:01 +00:00
Nick Sweeting 9a33749eca docs: add native app setup and client usage to README 2026-09-17 23:12:38 -07:00
Nick Sweeting c104931341 Align Apps menu inline code and add breathing room 2026-09-17 23:12:09 -07:00
ArchiveBox Release Bot 6a245d70d9 Bump release version to 0.9.35rc474 2026-09-18 06:11:08 +00:00
Nick Sweeting 4ca3b180a8 Preserve inline spacing around abx-dl in the Apps menu 2026-09-17 23:10:11 -07:00
55 changed files with 1711 additions and 277 deletions

No files matched your search

+23 -3
View File
@@ -246,6 +246,26 @@ jobs:
if: inputs.push_digests
run: echo ${{ steps.docker_build.outputs.digest }}
- name: Verify OpenCode install with a read-only browser profile
shell: bash
env:
IMAGE: ${{ inputs.push_digests && format('{0}@{1}', env.DOCKERHUB_IMAGE, steps.docker_build.outputs.digest) || matrix.local_tag }}
run: |
set -Eeuo pipefail
PROFILE_DIR="$(mktemp -d)"
"$DOCKER_BINARY" run --rm --platform '${{ matrix.platform }}' \
--volume "$PROFILE_DIR:/home/archivebox/.config/chromium:ro" \
"$IMAGE" bash -c '
set -Eeuo pipefail
test -w "$XDG_CONFIG_HOME"
test ! -w "$XDG_CONFIG_HOME/chromium"
# Check the shipped executable before the installer can repair
# an image that accidentally omitted this opt-in dependency.
"$ABXPKG_LIB_DIR/pnpm/packages/opencode/node_modules/.bin/opencode" --version
archivebox install opencode
"$ABXPKG_LIB_DIR/pnpm/packages/opencode/node_modules/.bin/opencode" --version
'
- name: Validate exact built image version and commit
if: ${{ !inputs.push_digests }}
shell: bash
@@ -296,8 +316,8 @@ jobs:
MANIFEST="$("$DOCKER_BINARY" buildx imagetools inspect --raw "${DOCKERHUB_IMAGE}@${IMAGE_DIGEST}")"
fi
COMPRESSED_SIZE="$(MANIFEST="$MANIFEST" "$UV_BINARY" run --no-cache --no-project python -c 'import json, os; manifest = json.loads(os.environ["MANIFEST"]); print(manifest["config"]["size"] + sum(layer["size"] for layer in manifest["layers"]))')"
LIMIT=$((750 * 1024 * 1024))
echo "${DIGEST} compressed_size=$((COMPRESSED_SIZE / 1024 / 1024)) MiB limit=750 MiB"
LIMIT=$((900 * 1024 * 1024))
echo "${DIGEST} compressed_size=$((COMPRESSED_SIZE / 1024 / 1024)) MiB limit=900 MiB"
(( COMPRESSED_SIZE < LIMIT ))
- name: Resolve real Docker CLI test dependencies through abxpkg
@@ -423,7 +443,7 @@ jobs:
'${{ runner.temp }}/archivebox-image.tar' \
'${{ steps.docker_build_pr.outputs.digest }}' \
"$LOCAL_IMAGE_ID" \
"$((750 * 1024 * 1024))" <<'PY'
"$((900 * 1024 * 1024))" <<'PY'
from hashlib import sha256
import json
import os
+14
View File
@@ -49,3 +49,17 @@ jobs:
push_digests: true
full_tests: false
secrets: inherit
opencode:
needs: prepare
if: needs.prepare.outputs.action == 'ready' || needs.prepare.outputs.action == 'reserved'
strategy:
fail-fast: false
matrix:
test_file:
- archivebox/tests/test_opencode_agent.py
- archivebox/tests/test_opencode_browser.py
uses: ./.github/workflows/test-parallel.yml
with:
test_file: ${{ matrix.test_file }}
secrets: inherit
+11
View File
@@ -2,6 +2,12 @@ name: Parallel Tests
on:
workflow_call:
inputs:
test_file:
description: Run one discovered test file; empty runs the complete matrix
required: false
default: ""
type: string
env:
PYTHONIOENCODING: utf-8
@@ -58,10 +64,15 @@ jobs:
- name: Discover every test exactly once
id: discover
env:
TEST_FILE: ${{ inputs.test_file }}
run: |
set -Eeuo pipefail
mapfile -t output < <("$PYTHON_BINARY" .github/scripts/discover_test_matrix.py)
test "${#output[@]}" -eq 2
if [[ -n "$TEST_FILE" ]]; then
output[1]="$("$JQ_BINARY" -ce '[.[] | select(.paths == [env.TEST_FILE])] | select(length == 1)' <<< "${output[1]}")"
fi
echo "tests=${output[1]}" >> "$GITHUB_OUTPUT"
echo "${output[0]}"
"$JQ_BINARY" -e 'length > 0 and length <= 256 and ([.[].paths[]] | length == (unique | length))' <<< "${output[1]}"
+17 -4
View File
@@ -1,8 +1,10 @@
# syntax=docker/dockerfile:1.7
# Multistage ArchiveBox Dockerfile that consumes the abx-dl runtime image.
# abx-dl owns Python, Node, Chromium, and downloader plugin runtimes.
# ArchiveBox owns sonic, supervisor, Django, and the app runtime.
# WHY: abx-dl owns Python, Node, Chromium, and extraction dependencies so the
# standalone downloader stays independent of ArchiveBox's server features.
# ArchiveBox-only dependencies (Sonic, OpenCode, supervisor, Django) belong in
# the layers added by this Dockerfile, never in the shared abx-dl base image.
# Build abx-dl first, then point this file at it:
# docker buildx build ../abx-dl -f ../abx-dl/Dockerfile \
# --build-context abxbus=../abxbus \
@@ -10,10 +12,10 @@
# --build-context abx-plugins=../abx-plugins \
# -t archivebox/abx-dl:dev
# docker buildx build . -f Dockerfile \
# --build-arg ABX_DL_IMAGE=archivebox/abx-dl:1.12.289 \
# --build-arg ABX_DL_IMAGE=archivebox/abx-dl:1.12.315 \
# -t archivebox:multistage
ARG ABX_DL_IMAGE=archivebox/abx-dl:1.12.289
ARG ABX_DL_IMAGE=archivebox/abx-dl:1.12.315
FROM archivebox/sonic:1.4.9 AS sonic
FROM ${ABX_DL_IMAGE} AS archivebox-runtime-base
@@ -250,6 +252,17 @@ RUN --mount=type=cache,target=/opt/archivebox/lib/cache,sharing=locked,mode=1777
&& echo -e "\nARCHIVEBOX_USER=$ARCHIVEBOX_USER ARCHIVEBOX_UID=$(id -u "$ARCHIVEBOX_USER") ARCHIVEBOX_GID=$(id -g "$ARCHIVEBOX_USER")" | tee -a /VERSION.txt \
&& echo -e "TMP_DIR=$TMP_DIR\nABXPKG_LIB_DIR=$ABXPKG_LIB_DIR\nPLAYWRIGHT_BROWSERS_PATH=$PLAYWRIGHT_BROWSERS_PATH\nMACHINE_ID=$(cat /etc/machine-id)\n" | tee -a /VERSION.txt
# The optional AI service belongs to ArchiveBox, not the downloader base image.
# Always bundle its executable while leaving OPENCODE_ENABLED opt-in.
RUN --mount=type=cache,target=/var/tmp/abxpkg-cache,sharing=locked,mode=1777,id=archivebox-opencode-$TARGETARCH \
env ABXPKG_TMP_CACHE_DIR=/var/tmp/abxpkg-cache XDG_CACHE_HOME=/var/tmp/abxpkg-cache \
setpriv --reuid="$ARCHIVEBOX_USER" --regid="$ARCHIVEBOX_USER" --init-groups abx-dl install opencode \
# pnpm includes musl variants that Debian's glibc runtime cannot use.
&& find "$ABXPKG_LIB_DIR/pnpm/packages/opencode/node_modules" -type l -name 'opencode-linux-*-musl' -delete \
&& find "$ABXPKG_LIB_DIR/pnpm/packages/opencode/node_modules/.pnpm" -maxdepth 1 -type d -name 'opencode-linux-*-musl@*' -exec rm -rf {} +
RUN --network=none setpriv --reuid="$ARCHIVEBOX_USER" --regid="$ARCHIVEBOX_USER" --init-groups \
bash -c '"$ABXPKG_LIB_DIR/pnpm/packages/opencode/node_modules/.bin/opencode" --version && abx-dl install opencode'
WORKDIR "$DATA_DIR"
RUN echo "[+] Initializing image collection..." \
&& find "$DATA_DIR" -mindepth 1 -maxdepth 1 -exec rm -rf {} + \
+29 -1
View File
@@ -151,6 +151,17 @@ curl -fsSL 'https://get.archivebox.io' | bash
#### ✳️&nbsp; Easy Setup
<details>
<summary><b><img src="https://archivebox.github.io/ios-archivebox/docs/icons/apple.svg" alt="Apple" height="28px" align="top"/> <code>ArchiveBox Server.app</code></b> (macOS)</summary>
<br/>
<ol>
<li><a href="https://github.com/ArchiveBox/ios-archivebox/releases">Download <code>ArchiveBox Server.app</code></a>, move it to Applications, and open it.</li>
<li>Set up an admin account and generate an API Key.</li>
<li>Use the Web UI or <a href="https://archivebox.github.io/ios-archivebox/"><code>ArchiveBox.app</code></a>, and optionally connect REST API clients, the <a href="https://archivebox.github.io/ios-archivebox/">mobile app</a>, the <a href="https://archivebox.github.io/archivebox-browser-extension/">browser extension</a>, and other integrations to your server using your API Key.</li>
</ol>
<br/>
</details>
<details>
<summary><b><img src="https://user-images.githubusercontent.com/511499/117447182-29758200-af0b-11eb-97bd-58723fee62ab.png" alt="Docker" height="28px" align="top"/> <code>docker-compose</code></b> (macOS/Linux) &nbsp; <b>👈&nbsp; recommended</b> &nbsp; <i>(click to expand)</i></summary>
<br/>
@@ -561,6 +572,20 @@ docker compose run --rm archivebox config --set PERMISSIONS=public
</code></pre>
</details>
<br/>
<details>
<summary><b><img src="https://archivebox.github.io/ios-archivebox/docs/icons/apple.svg" alt="Apple" height="22px" align="top"/> <img src="https://cdn.jsdelivr.net/gh/devicons/devicon@v2.17.0/icons/windows11/windows11-original.svg" alt="Windows" height="22px" align="top"/> 🐧&nbsp; Desktop / Mobile / Extension Usage</b></summary>
<br/>
- 📱 [<code>ArchiveBox</code> iOS Mobile App](https://archivebox.github.io/ios-archivebox/)
- 🖥️ [<code>ArchiveBox.app</code> macOS Desktop App](https://archivebox.github.io/ios-archivebox/)
- 🧩 [ArchiveBox Browser Extension](https://archivebox.github.io/archivebox-browser-extension/)
- 💻 [Linux/Windows Desktop App (Requires Docker Desktop)](https://github.com/ArchiveBox/electron-archivebox)
<br/>
</details>
<br/>
<br/>
@@ -614,7 +639,10 @@ docker run -it -v $PWD:/data archivebox/archivebox:dev add --depth=1 'https://ex
- <img src="https://github.com/ArchiveBox/ArchiveBox/assets/511499/ff20d251-5347-4b85-ae9b-83037d0ac01e" height="28px"/> <b>From the official <a href="https://github.com/ArchiveBox/archivebox-extension">ArchiveBox Browser Extension</a></b>
<i>Provides realtime archiving of browsing history or selected pages from Chrome/Chromium/Firefox browsers.</i>
<i>Provides realtime archiving of browsing history or selected pages from Chrome/Chromium/Firefox/Safari browsers.</i>
- <img src="https://archivebox.github.io/ios-archivebox/App/AppIcon.icon/Assets/ArchiveBox.png" alt="ArchiveBox app icon" height="28px"/> <b>From the official <a href="https://archivebox.github.io/ios-archivebox/">ArchiveBox macOS Desktop App or iOS Mobile App</a></b><br/>
<i>Save directly from the Share menu or Siri/Shortcuts to your server.</i>
- <img src="https://github.com/ArchiveBox/ArchiveBox/assets/511499/64078483-21d7-4eb1-aa6e-9ad55afe45b8" height="22px"/> From manual imports of URLs from RSS, JSON, CSV, TXT, SQL, HTML, Markdown, etc. files
<i>ArchiveBox supports injesting URLs in [any text-based format](https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#Import-a-list-of-URLs-from-a-text-file).</i>
+33 -4
View File
@@ -109,6 +109,7 @@ def create_personas(
profile: str | None = None,
source: str | None = None,
browser_binary: str | None = None,
permissions: str | None = None,
) -> int:
"""
Create Personas from names.
@@ -162,7 +163,10 @@ def create_personas(
rprint(f'[red]Invalid persona name "{name}": {error_msg}[/red]', file=sys.stderr)
continue
persona, created = Persona.objects.get_or_create(name=name)
persona, created = Persona.objects.get_or_create(
name=name,
defaults={"config": {"PERMISSIONS": permissions}} if permissions else {},
)
if created:
persona.ensure_dirs()
@@ -441,7 +445,11 @@ def main():
@main.command("create")
@click.argument("names", nargs=-1)
@click.option("--import", "import_from", help="Import from chrome, chromium, brave, edge, a persona directory, or a live CDP URL")
@click.option(
"--import",
"import_from",
help="Import from chrome, chrome-beta, chromium, brave, edge, a persona directory, or a live CDP URL",
)
@click.option("--source", help="Source browser user-data directory or exact profile path (including Docker mounts)")
@click.option(
"--browser-binary",
@@ -449,9 +457,30 @@ def main():
help="Source Chromium browser executable; required for other Chromium-based browsers",
)
@click.option("--profile", help="Profile directory name under the user data dir (e.g. Default, Profile 1)")
def create_cmd(names: tuple, import_from: str | None, profile: str | None, source: str | None, browser_binary: str | None):
@click.option(
"--permissions",
type=click.Choice(["public", "unlisted", "private"]),
help="Visibility for a newly created persona (existing personas are unchanged)",
)
def create_cmd(
names: tuple,
import_from: str | None,
profile: str | None,
source: str | None,
browser_binary: str | None,
permissions: str | None,
):
"""Create Personas, optionally importing from a browser profile."""
sys.exit(create_personas(names, import_from=import_from, profile=profile, source=source, browser_binary=browser_binary))
sys.exit(
create_personas(
names,
import_from=import_from,
profile=profile,
source=source,
browser_binary=browser_binary,
permissions=permissions,
),
)
@main.command("list")
+4 -4
View File
@@ -460,9 +460,9 @@ def system_warnings_banner(context):
"""Render the top-of-page warning banner for one of the conditions below,
in priority order (highest first):
1. ``mode="unconfigured"``— ``BASE_URL`` is empty. Security/correctness
issue: until it's pinned, generated URLs can echo any Host the client
sends, and admin/web/api routing has no canonical anchor.
1. ``mode="unconfigured"``— ``BASE_URL`` is empty and the operator has
not selected safe single-domain routing. That mode intentionally uses
each device's connection address, including LAN and Tailscale IPs.
2. ``mode="base_url_mismatch"`` — the browser reached ArchiveBox through
an origin that differs from the configured canonical ``BASE_URL``.
3. ``mode="unsafe"`` — ``SERVER_SECURITY_MODE`` explicitly enables
@@ -489,7 +489,7 @@ def system_warnings_banner(context):
config = get_config(resolve_plugins=False)
if not config.BASE_URL:
if not config.BASE_URL and config.SERVER_SECURITY_MODE != "safe-onedomain-nojsreplay":
return get_setup_wizard_context(context.get("request"), config)
mismatch = get_base_url_mismatch_context(context.get("request"), config)
if mismatch and not _is_web_subdomain_alias(mismatch["browser_url"], mismatch["configured_base_url"]):
+2 -2
View File
@@ -27,7 +27,7 @@ class PersonaAdmin(ConfigEditorMixin, BaseModelAdmin):
"Persona",
{
"fields": ("name", "created_by", "permissions"),
"classes": ("card", "persona-card-primary"),
"classes": ("card", "wide", "persona-card-primary"),
},
),
(
@@ -42,7 +42,7 @@ class PersonaAdmin(ConfigEditorMixin, BaseModelAdmin):
"import_extract_cookies",
"import_capture_storage",
),
"classes": ("card", "wide"),
"classes": ("card", "wide", "persona-card-import"),
},
),
(
+1 -1
View File
@@ -55,7 +55,7 @@ class PersonaAdminForm(PluginConfigFormMixin, forms.ModelForm):
label="Autodiscovered profiles",
widget=forms.RadioSelect,
choices=(),
help_text="Detected from local Chrome, Chromium, Brave, and Edge profile roots.",
help_text="Detected from local Chrome, Chrome Beta, Chromium, Brave, and Edge profile roots.",
)
import_source = forms.CharField(
required=False,
+28 -7
View File
@@ -18,6 +18,7 @@ import subprocess
import sys
import tempfile
from dataclasses import dataclass, field
from functools import partial
from pathlib import Path
from typing import TYPE_CHECKING
from urllib.parse import urlparse
@@ -31,6 +32,7 @@ if TYPE_CHECKING:
BROWSER_LABELS = {
"chrome": "Google Chrome",
"chrome-beta": "Google Chrome Beta",
"chromium": "Chromium",
"brave": "Brave",
"edge": "Microsoft Edge",
@@ -216,24 +218,29 @@ class PersonaImportResult:
return self.profile_copied or self.cookies_imported or self.storage_captured or self.user_agent_imported
def get_chrome_user_data_dir() -> Path | None:
def get_chrome_user_data_dir(*, beta: bool = False) -> Path | None:
"""Get the default Chrome user data directory for the current platform."""
system = platform.system()
home = Path.home()
app_name = "Chrome Beta" if beta else "Chrome"
if system == "Darwin":
candidates = [
home / "Library" / "Application Support" / "Google" / "Chrome",
home / "Library" / "Application Support" / "Google" / app_name,
]
elif system == "Linux":
candidates = [
home / ".config" / "google-chrome",
home / ".config" / "chrome",
]
candidates = (
[home / ".config" / "google-chrome-beta"]
if beta
else [
home / ".config" / "google-chrome",
home / ".config" / "chrome",
]
)
elif system == "Windows":
local_app_data = Path(os.environ.get("LOCALAPPDATA", home / "AppData" / "Local"))
candidates = [
local_app_data / "Google" / "Chrome" / "User Data",
local_app_data / "Google" / app_name / "User Data",
]
else:
candidates = []
@@ -320,6 +327,7 @@ def get_edge_user_data_dir() -> Path | None:
BROWSER_PROFILE_FINDERS = {
"chrome": get_chrome_user_data_dir,
"chrome-beta": partial(get_chrome_user_data_dir, beta=True),
"chromium": get_chromium_user_data_dir,
"brave": get_brave_user_data_dir,
"edge": get_edge_user_data_dir,
@@ -354,6 +362,12 @@ def validate_persona_name(name: str) -> tuple[bool, str]:
def discover_local_browser_profiles() -> list[PersonaImportSource]:
# The macOS companion exports with the host Keychain before creating personas.
# Raw mounts alone cannot decrypt macOS cookies in the Linux container.
if host_profiles := os.environ.get("ARCHIVEBOX_HOST_BROWSER_PROFILES"):
host_templates = discover_persona_template_profiles(Path(host_profiles))
host_names = {source.source_name for source in host_templates}
return host_templates + [source for source in discover_persona_template_profiles() if source.source_name not in host_names]
discovered: list[PersonaImportSource] = []
for browser, finder in BROWSER_PROFILE_FINDERS.items():
@@ -430,6 +444,11 @@ def discover_persona_template_profiles(personas_dir: Path | None = None) -> list
def resolve_browser_import_source(browser: str, profile_dir: str | None = None) -> PersonaImportSource:
browser = browser.lower().strip()
if host_profiles := os.environ.get("ARCHIVEBOX_HOST_BROWSER_PROFILES"):
label = BROWSER_LABELS.get(browser, browser)
exported = Path(host_profiles) / f"{label} - {profile_dir or 'Default'}"
if exported.is_dir():
return resolve_custom_import_source(str(exported))
if browser not in BROWSER_PROFILE_FINDERS:
supported = ", ".join(BROWSER_PROFILE_FINDERS)
raise ValueError(f"Unknown browser: {browser}. Supported browsers: {supported}")
@@ -547,6 +566,7 @@ def resolve_source_browser_binary(source: PersonaImportSource) -> str:
return str(Path(source.browser_binary).expanduser().resolve())
names = {
"chrome": ("Google Chrome", "google-chrome"),
"chrome-beta": ("Google Chrome Beta", "google-chrome-beta"),
"chromium": ("Chromium", "chromium"),
"brave": ("Brave Browser", "brave-browser"),
"edge": ("Microsoft Edge", "microsoft-edge"),
@@ -561,6 +581,7 @@ def resolve_source_browser_binary(source: PersonaImportSource) -> str:
elif platform.system() == "Windows":
relative = {
"chrome": "Google/Chrome/Application/chrome.exe",
"chrome-beta": "Google/Chrome Beta/Application/chrome.exe",
"edge": "Microsoft/Edge/Application/msedge.exe",
"brave": "BraveSoftware/Brave-Browser/Application/brave.exe",
"chromium": "Chromium/Application/chrome.exe",
@@ -38,8 +38,8 @@
border-bottom: 1px dashed #64748b;
}
.field-import_mode ul,
.field-import_discovered_profile ul {
.abx-import-mode,
.abx-profile-picker {
margin: 0;
padding: 0;
list-style: none;
@@ -47,20 +47,26 @@
gap: 12px;
}
.field-import_mode ul {
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
.abx-import-mode {
grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
}
.field-import_discovered_profile ul {
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
max-height: 460px;
overflow: auto;
padding-right: 4px;
.abx-profile-picker {
grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.field-import_mode li,
.field-import_discovered_profile li {
.abx-import-mode > div,
.abx-profile-picker > div {
margin: 0;
min-width: 0;
}
/* Import rows grow with their contents instead of sharing a fixed flex
height. Avoid overflow-x:hidden turning overflow-y:visible into auto. */
#content-main #persona_form .persona-card-import > .form-row,
#content-main #persona_form .persona-card-import fieldset > div {
flex: none;
overflow: visible;
}
.field-import_mode label,
@@ -68,7 +74,6 @@
display: flex;
gap: 12px;
align-items: flex-start;
min-height: 100%;
padding: 14px 16px;
border-radius: 14px;
border: 1px solid #dbe4ee;
@@ -167,9 +172,14 @@
color: #991b1b;
}
body.model-persona.change-form #content-main form fieldset.persona-card-primary {
flex: 1 1 520px !important;
max-width: calc(66.66% - 10px) !important;
#content-main #persona_form .field-name .flex-container {
max-width: 100% !important;
}
#persona_form .field-name input {
width: 100%;
max-width: none;
box-sizing: border-box;
}
body.model-persona.change-form #content-main form fieldset.persona-card-timestamps {
@@ -257,6 +267,11 @@ document.addEventListener('DOMContentLoaded', function () {
or by pasting in a CDP url from
<code class="persona-import-copy" data-copy-text="chrome://inspect#remote-debugging" title="Copy chrome://inspect#remote-debugging">chrome://inspect#remote-debugging</code> (e.g. <code>http://127.0.0.1:9222</code>).
</p>
<p>
You can also import cookies into this persona from another browser using the
<a href="https://archivebox.github.io/archivebox-browser-extension/" target="_blank" rel="noopener noreferrer">ArchiveBox browser extension</a>.
Create the persona here, then select it in the extension's settings to sync cookies from that browser.
</p>
</div>
</section>
{{ block.super }}
@@ -264,9 +279,9 @@ document.addEventListener('DOMContentLoaded', function () {
{% block after_field_sets %}
{{ block.super }}
<section id="plugin-config" class="module aligned persona-plugin-config">
<fieldset id="plugin-config" class="module aligned wide persona-plugin-config">
<h2>Plugin Config</h2>
<p>These typed controls update the same Persona config JSON shown above. Shared config keys stay synced across plugin sections.</p>
{% include "plugins/plugin_config_grid.html" with plugin_groups=adminform.form.plugin_groups %}
</section>
</fieldset>
{% endblock %}
+2 -1
View File
@@ -287,7 +287,8 @@
<code>daily</code> - Run once per day<br/>
<code>weekly</code> - Run once per week<br/>
<code>0 */6 * * *</code> - Every 6 hours (cron format)<br/>
<code>0 0 * * 0</code> - Every Sunday at midnight (cron format)
<code>0 0 * * 0</code> - Every Sunday at midnight (cron format)<br/>
<a href="https://crontab.guru/" target="_blank" rel="noopener">Cron Format Helper</a>
</div>
</div>
+17
View File
@@ -16,6 +16,23 @@ def test_persona_help_runs_successfully(tmp_path):
assert "list" in result.stdout
def test_persona_create_permissions_preserves_existing_persona(initialized_archive):
from archivebox.tests.conftest import run_python_cwd
result = run_archivebox_cmd(["persona", "create", "--permissions=private", "host-profile"], cwd=initialized_archive)
assert result.returncode == 0, result.stderr
existing = run_archivebox_cmd(["persona", "create", "--permissions=public", "host-profile"], cwd=initialized_archive)
assert existing.returncode == 0, existing.stderr
stdout, stderr, returncode = run_python_cwd(
"import os; os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'archivebox.core.settings'); "
"import django; django.setup(); from archivebox.personas.models import Persona; "
"p = Persona.objects.get(name='host-profile'); assert p.permissions == 'private'; print('private')",
cwd=initialized_archive,
)
assert returncode == 0, stderr
assert "private" in stdout
def test_persona_import_missing_source_is_actionable_and_does_not_create(initialized_archive, tmp_path):
result = run_archivebox_cmd(
["persona", "create", "--import=brave", "--source", str(tmp_path / "missing"), "broken"],
+60 -2
View File
@@ -1,9 +1,11 @@
import asyncio
import json
import os
import re
import shutil
import socket
from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import TimeoutError as FutureTimeoutError
from pathlib import Path
from types import SimpleNamespace
from urllib.parse import parse_qs, quote, urlsplit
@@ -359,6 +361,45 @@ def test_opencode_proxy_preserves_protocol_headers(admin_client, live_opencode):
assert deleted.status_code == 200, deleted.content
def test_opencode_oauth_callback_waits_for_user_and_preserves_cancellation(live_opencode):
from abx_plugins.plugins.opencode import runtime
settings = {**live_opencode.settings, "timeout": 1}
headers = {"Content-Type": "application/json"}
status, _, body = runtime.proxy(settings, "POST", "provider/openai/oauth/authorize", (), headers, b'{"method":0}')
assert status == 200
authorization = json.loads(body)
assert urlsplit(authorization["url"]).hostname == "auth.openai.com"
redirect = parse_qs(urlsplit(authorization["url"]).query)["redirect_uri"][0]
callback_origin = urlsplit(redirect)
assert callback_origin.hostname == "localhost"
with ThreadPoolExecutor(max_workers=1) as executor:
callback = executor.submit(runtime.proxy, settings, "POST", "provider/openai/oauth/callback", (), headers, b'{"method":0}')
try:
# A real pending authorization must outlive the ordinary API read
# timeout. No tokens or substituted provider responses are used.
with pytest.raises(FutureTimeoutError):
callback.result(timeout=2)
finally:
cancelled = requests.get(f"{callback_origin.scheme}://{callback_origin.netloc}/cancel", timeout=5)
assert cancelled.status_code == 200
assert cancelled.text == "Login cancelled"
status, response_headers, body = callback.result(timeout=5)
assert status == 500
assert response_headers["Content-Type"].startswith("application/json")
error = json.loads(body)
assert error["name"] == "UnknownError"
assert error["data"]["ref"].startswith("err_")
runtime._stop_owned_process()
# The pnpm launcher can exit before its server child. Stopping the owned
# process must release both listeners so another collection can authorize.
with pytest.raises(requests.ConnectionError):
requests.get(settings["origin"] + "/global/health", timeout=2)
with pytest.raises(requests.ConnectionError):
requests.get(f"{callback_origin.scheme}://{callback_origin.netloc}/cancel", timeout=2)
def test_opencode_static_assets_cache_privately_and_revalidate(admin_client, live_opencode):
headers = {"HTTP_HOST": ADMIN_TEST_HOST, "HTTP_SEC_FETCH_SITE": "same-origin"}
page = admin_client.get("/admin/agent/opencode/", **headers)
@@ -392,9 +433,26 @@ def test_opencode_proxy_sse_response_is_unbuffered(admin_client, live_opencode):
assert response.headers["Cache-Control"] == "no-store"
def test_opencode_proxy_sse_delivers_first_event_immediately(admin_client, live_opencode):
@pytest.mark.parametrize("path", ["event", "global/event"])
def test_opencode_proxy_sse_delivers_first_event_immediately(admin_client, live_opencode, path):
from abx_plugins.plugins.opencode import runtime
# The real /event endpoint emits heartbeats indefinitely. A bounded
# upstream read exposes accidental buffering without hanging the test.
status, headers, body = runtime.proxy(
{**live_opencode.settings, "timeout": 1},
"GET",
path,
(),
{},
b"",
)
assert status == 200
assert not isinstance(body, bytes)
assert headers["Content-Type"] == "text/event-stream"
asyncio.run(body.aclose())
response = admin_client.get(
"/admin/agent/opencode/global/event",
f"/admin/agent/opencode/{path}",
HTTP_HOST=ADMIN_TEST_HOST,
HTTP_SEC_FETCH_SITE="same-origin",
)
+127 -6
View File
@@ -20,8 +20,21 @@ from .test_server_security_browser import browser_runtime as browser_runtime
pytestmark = pytest.mark.django_db(transaction=True)
@pytest.mark.parametrize(
"agent_server",
[
("safe-onedomain-nojsreplay", False),
("safe-subdomains-fullreplay", True),
("danger-onedomain-fullreplay", False),
("auto", False),
("auto", True),
],
indirect=True,
)
def test_agent_navigation_stays_inside_mount(agent_server, browser_runtime):
server_url, _, _ = agent_server
server_url, data_dir, _ = agent_server
filename = "proxy acceptance #é.txt"
(data_dir / filename).write_text("Proxy file read: café", encoding="utf-8")
script = r"""
const assert = require('node:assert/strict');
const puppeteer = require('puppeteer');
@@ -31,6 +44,14 @@ const config = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));
args: ['--no-sandbox', '--disable-frame-rate-limit']});
try {
const page = await browser.newPage();
const escapedRequests = [];
page.on('request', request => {
const url = new URL(request.url());
if (request.frame()?.parentFrame() && url.origin === config.url &&
!url.pathname.startsWith('/admin/agent/opencode/')) {
escapedRequests.push(request.method() + ' ' + url.pathname);
}
});
await page.setViewport({width: 1440, height: 900});
await page.goto(config.url + '/admin/login/', {waitUntil: 'domcontentloaded'});
await page.locator('#login-form input[name="username"]').fill('agent-browser-test');
@@ -44,7 +65,9 @@ const config = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));
const links = await frame.$$eval('a[href*="/session"]', nodes => nodes.map(node => node.getAttribute('href')));
assert.ok(links.length, 'OpenCode must expose session navigation');
for (const href of links) assert.ok(href.startsWith('/admin/agent/opencode/'), href);
const initialSessionUrl = frame.url();
await frame.locator('::-p-aria(New session[role="button"])').click();
await frame.waitForFunction(previous => location.href !== previous, {}, initialSessionUrl);
await frame.waitForSelector('[contenteditable="true"]');
let navigation;
for (const link of await frame.$$('a[href*="/session"]')) {
@@ -61,6 +84,101 @@ const config = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));
assert.equal((await frame.goto(sessionUrl, {waitUntil: 'domcontentloaded'})).status(), 200);
await frame.waitForSelector('[contenteditable="true"]');
assert.ok(!(await frame.$eval('body', node => node.innerText)).includes('Something went wrong'));
// Real JSON methods, encoded file paths, and both SSE subscriptions must
// work on the admin origin in every routing mode, without installing or
// authenticating a paid model provider during the test.
const requests = await frame.evaluate(async filename => {
const base = location.origin + '/admin/agent/opencode';
const json = async (path, method = 'GET', body) => {
const response = await fetch(base + path, {
method, headers: {'Content-Type': 'application/json'},
...(body === undefined ? {} : {body: JSON.stringify(body)}),
});
if (!response.ok) throw new Error(method + ' ' + path + ': ' + response.status);
if (!response.headers.get('Content-Type')?.includes('application/json')) {
throw new Error('Non-JSON response: ' + path);
}
return response.json();
};
const providers = await json('/provider');
const auth = await json('/provider/auth');
const file = await json('/file/content?path=' + encodeURIComponent(filename));
const session = await json('/session', 'POST', {title: 'Proxy request verification'});
let renamed;
try {
renamed = await json('/session/' + session.id, 'PATCH', {title: 'Proxy: café & # symbols'});
const readback = await json('/session/' + session.id);
if (readback.title !== renamed.title) throw new Error('Session mutation was not persisted');
} finally { await json('/session/' + session.id, 'DELETE'); }
const streams = [];
for (const path of ['/event', '/global/event']) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(base + path, {signal: controller.signal});
if (!response.ok || !response.headers.get('Content-Type')?.includes('text/event-stream')) {
throw new Error('Invalid event stream: ' + path);
}
const reader = response.body.getReader();
const first = await reader.read();
streams.push(new TextDecoder().decode(first.value));
await reader.cancel();
} finally { clearTimeout(timeout); controller.abort(); }
}
return {providers: providers.all.map(provider => provider.id), auth, file, renamed, streams};
}, config.filename);
for (const provider of ['openai', 'anthropic']) assert.ok(requests.providers.includes(provider), provider);
assert.ok(requests.auth.openai.some(method => method.type === 'oauth'));
assert.equal(requests.file.content, 'Proxy file read: café');
assert.equal(requests.renamed.title, 'Proxy: café & # symbols');
for (const event of requests.streams) assert.ok(event.includes('server.connected'), event);
for (const provider of ['OpenAI', 'Anthropic']) {
await frame.locator('[data-action="prompt-model"]').click();
await frame.locator('::-p-aria(' + provider + '[role="button"])').click();
if (provider === 'OpenAI') {
await frame.waitForSelector('::-p-aria(ChatGPT Pro/Plus Headless[role="button"])');
await frame.waitForSelector('::-p-aria(ChatGPT Pro/Plus Browser[role="button"])');
await frame.locator('::-p-aria(API key Browser[role="button"])').click();
}
const input = await frame.waitForSelector('::-p-aria(' + provider + ' API key[role="textbox"])');
assert.equal(await input.evaluate(node => node.value), '');
await frame.waitForSelector('::-p-aria(Continue[role="button"])');
await frame.locator('::-p-aria(Close[role="button"])').click();
}
// Submit a real shell command from a fresh draft. This exercises draft
// promotion and the shell API without needing a paid model or API key.
await frame.locator('::-p-aria(New session[role="button"])').click();
await frame.waitForFunction(() => location.pathname.endsWith('/new-session'));
await (await frame.waitForSelector('[contenteditable="true"]')).focus();
const modifier = await page.evaluate(() => navigator.platform.includes('Mac') ? 'Meta' : 'Control');
await page.keyboard.down(modifier);
await page.keyboard.down('Shift');
await page.keyboard.press('x');
await page.keyboard.up('Shift');
await page.keyboard.up(modifier);
await page.keyboard.type('printf ABX_DRAFT_SHELL_OK');
await frame.locator('::-p-aria(Send[role="button"])').click();
await frame.waitForFunction(() => /\/session\/ses_/.test(location.pathname));
assert.ok(new URL(frame.url()).pathname.startsWith('/admin/agent/opencode/'), frame.url());
await frame.waitForFunction(async () => {
const sessionID = location.pathname.match(/\/session\/(ses_[^/]+)/)[1];
const response = await fetch('/admin/agent/opencode/session/' + sessionID + '/message');
if (!response.ok) throw new Error('Shell message readback: ' + response.status);
const messages = await response.json();
return messages.some(message => message.parts.some(part =>
part.type === 'tool' && part.state.status === 'completed' &&
part.state.output.trim() === 'ABX_DRAFT_SHELL_OK'));
}, {polling: 250});
// The tabbed layout's own route parser must recognize mounted sessions.
// Otherwise Home incorrectly appears selected and clicking it does nothing.
const shellSessionUrl = frame.url();
const home = await frame.waitForSelector('[aria-label="Home"]');
assert.equal(await home.evaluate(node => node.getAttribute('aria-pressed')), 'false');
await home.click();
await frame.waitForFunction(() => location.pathname.replace(/\/+$/, '') === '/admin/agent/opencode');
assert.equal(await home.evaluate(node => node.getAttribute('aria-pressed')), 'true');
await home.click();
await frame.waitForFunction(expected => location.href === expected, {}, shellSessionUrl);
// Exercise the actual public PTY API and native browser WebSocket. No
// intercepted traffic or replacement server: this runs a real shell.
const terminal = await frame.evaluate(async () => {
@@ -97,6 +215,7 @@ const config = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));
} finally { await fetch(base + '/pty/' + pty.id, {method: 'DELETE'}); }
});
assert.ok(terminal.includes('ABX_TERMINAL_OK'), terminal);
assert.deepEqual(escapedRequests, [], 'OpenCode requests must stay inside its proxy mount');
assert.equal((await page.goto(config.url + '/add/', {waitUntil: 'domcontentloaded'})).status(), 200);
console.log('AGENT_NAVIGATION_OK');
} finally { await browser.close(); }
@@ -104,7 +223,7 @@ const config = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));
"""
result = subprocess.run(
[str(browser_runtime["node_binary"]), "-e", script],
input=json.dumps({"chrome": str(browser_runtime["chrome_binary"]), "url": server_url}),
input=json.dumps({"chrome": str(browser_runtime["chrome_binary"]), "url": server_url, "filename": filename}),
env={**os.environ, "NODE_PATH": browser_runtime["node_path"]},
text=True,
capture_output=True,
@@ -115,14 +234,16 @@ const config = JSON.parse(require('node:fs').readFileSync(0, 'utf8'));
@pytest.fixture
def agent_server(installed_opencode, browser_runtime):
def agent_server(installed_opencode, browser_runtime, request):
port = get_free_port()
url = f"http://localhost:{port}"
mode, subdomains = getattr(request, "param", ("safe-onedomain-nojsreplay", False))
base_url = f"http://archivebox.localhost:{port}" if subdomains else f"http://localhost:{port}"
url = f"http://admin.archivebox.localhost:{port}" if subdomains else base_url
config = installed_opencode.config
_set_archivebox_config(
config.data_dir,
f"BASE_URL={url}",
"SERVER_SECURITY_MODE=safe-onedomain-nojsreplay",
f"BASE_URL={base_url}",
f"SERVER_SECURITY_MODE={mode}",
)
user = run_archivebox_cmd(
[
@@ -0,0 +1,61 @@
"""Exercise automatic server addressing through real HTTP login pages."""
import re
import requests
from .conftest import cli_env, get_free_port, run_archivebox_cmd, start_archivebox_server, stop_archivebox_process
def test_safe_single_domain_login_does_not_require_base_url(tmp_path):
port = get_free_port()
env = cli_env(
disable_extractors=True,
BASE_URL="",
SERVER_SECURITY_MODE="safe-onedomain-nojsreplay",
ADMIN_USERNAME="automatic-url-test",
ADMIN_PASSWORD="Automatic-url-test-password-93!",
ALLOWED_HOSTS="*",
)
result = run_archivebox_cmd(["init", "--quick"], cwd=tmp_path, env=env, timeout=60)
assert result.returncode == 0, result.stderr or result.stdout
process = start_archivebox_server(tmp_path, port=port, env=env, daemonize=False, log_name="server.log")
try:
for hostname in ("localhost", "archivebox.localhost", "admin.archivebox.localhost", "192.168.1.20", "100.100.10.20"):
session = requests.Session()
response = session.get(
f"http://127.0.0.1:{port}/admin/login/",
headers={"Host": f"{hostname}:{port}"},
timeout=15,
allow_redirects=False,
)
assert response.status_code == 200, (hostname, response.status_code)
assert 'name="password"' in response.text, hostname
assert "base_url not set" not in response.text.lower(), hostname
assert "archivebox-setup-wizard" not in response.text, hostname
csrf = re.search(r'name="csrfmiddlewaretoken" value="([^"]+)"', response.text)
assert csrf, hostname
login = session.post(
f"http://127.0.0.1:{port}/admin/login/",
headers={"Host": f"{hostname}:{port}"},
data={
"username": env["ADMIN_USERNAME"],
"password": env["ADMIN_PASSWORD"],
"csrfmiddlewaretoken": csrf[1],
"next": "/admin/",
},
timeout=15,
allow_redirects=False,
)
assert login.status_code == 302, (hostname, login.status_code)
admin = session.get(
f"http://127.0.0.1:{port}/admin/",
headers={"Host": f"{hostname}:{port}"},
timeout=15,
allow_redirects=False,
)
assert admin.status_code == 200, (hostname, admin.status_code)
assert "base_url not set" not in admin.text.lower(), hostname
assert "archivebox-setup-wizard" not in admin.text, hostname
finally:
stop_archivebox_process(process)
@@ -127,6 +127,10 @@ def test_persona_admin_add_view_renders_import_ui(admin_client):
assert b"auth.json" in response.content
assert b"Plugin Config" in response.content
assert b'name="plugin_config__wget__WGET_TIMEOUT"' in response.content
assert b'<fieldset id="plugin-config" class="module aligned wide persona-plugin-config">' in response.content
assert b'href="https://archivebox.github.io/archivebox-browser-extension/"' in response.content
assert b"import cookies into this persona from another browser" in response.content
assert "wide" in response.context["adminform"].fieldsets[0][1]["classes"]
def test_import_persona_from_source_copies_profile_without_browser_export(admin_user):
+11 -5
View File
@@ -230,11 +230,14 @@ assert_writable_dir "$DATA_DIR/logs"
assert_writable_dir "$DATA_DIR/archive"
assert_writable_dir "$PERSONAS_DIR/Default/chrome_profile"
# check if novnc x11 $DISPLAY is available
export DISPLAY="${DISPLAY:-"novnc:0.0"}"
if ! xdpyinfo > /dev/null 2>&1; then
# cant connect to x11 display, unset it so that chrome doesn't try to connect to it and hang indefinitely
unset DISPLAY
# Preserve an explicit DISPLAY (including an empty value to disable X11).
# Only probe the implicit noVNC default: a missing probe or unavailable server
# must not silently discard the user's display configuration.
if [[ -z "${DISPLAY+x}" ]]; then
export DISPLAY="novnc:0.0"
if ! xdpyinfo > /dev/null 2>&1; then
unset DISPLAY
fi
fi
# Active browser processes do not survive container restarts, but their lock
@@ -250,6 +253,9 @@ find /tmp "$TMP_DIR" -maxdepth 1 -type d -name "archivebox-chrome-profile.*" -mm
ensure_dir "/home/$ARCHIVEBOX_USER"
# A nested read-only browser-profile mount can create this parent as root.
# OpenCode's installer needs to create a sibling config directory as archivebox.
ensure_dir "${XDG_CONFIG_HOME:-/home/$ARCHIVEBOX_USER/.config}"
ensure_small_runtime_tree "$ABXBUS_CACHE_DIR"
ensure_small_runtime_tree "$ABXBUS_CACHE_DIR/semaphores"
ensure_small_runtime_tree "$UV_CACHE_DIR"
+1 -1
View File
@@ -1,6 +1,6 @@
<footer class="abx-footer" aria-label="ArchiveBox ecosystem">
<div class="abx-footer-intro"><div><a class="abx-brand" href="https://archivebox.io/"><svg class="abx-logo" viewBox="0 0 40 40" aria-hidden="true"><rect width="40" height="40" rx="10" fill="#9b2854"/><path d="M10 14h20v17H10z" fill="#fff4ed"/><path d="M8 9h24v6H8z" fill="#fff4ed"/><path d="M16 19h8v3h-8z" fill="#9b2854"/><path d="M12 31V17" stroke="#9b2854" stroke-width="2"/></svg><span>ArchiveBox</span></a><p class="abx-tagline">Open-source tools for keeping a lasting copy of the web.<br>Your data. Your devices. Your archive.</p></div><p class="abx-footer-motto">A home for the web<br>you want to keep.</p></div>
<div class="abx-footer-grid"><section class="abx-footer-column"><h2>Apps &amp; tools</h2><ul><li><a href="https://archivebox.io/">Self-hosted Web Archive</a><a class="abx-source" href="https://github.com/ArchiveBox/ArchiveBox" aria-label="Self-hosted Web Archive source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#get-started">iOS App for iPhone &amp; iPad</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="iOS App for iPhone &amp; iPad source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#your-server-your-choice">macOS App + Server App</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="macOS App + Server App source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/archivebox-browser-extension/">Browser Extensions</a><a class="abx-source" href="https://github.com/ArchiveBox/archivebox-browser-extension" aria-label="Browser Extensions source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-dl/">Command-line Downloader</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-dl" aria-label="Command-line Downloader source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-plugins/">Plugins &amp; Extractors</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-plugins" aria-label="Plugins &amp; Extractors source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 Line truncated
<div class="abx-footer-grid"><section class="abx-footer-column"><h2>Apps &amp; tools</h2><ul><li><a href="https://archivebox.io/">ArchiveBox Server</a><a class="abx-source" href="https://github.com/ArchiveBox/ArchiveBox" aria-label="ArchiveBox Server source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#get-started">ArchiveBox for macOS &amp; iOS</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="ArchiveBox for macOS &amp; iOS source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/archivebox-browser-extension/">ArchiveBox Browser Extension</a><a class="abx-source" href="https://github.com/ArchiveBox/archivebox-browser-extension" aria-label="ArchiveBox Browser Extension source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-plugins/">ArchiveBox Plugin Library</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-plugins" aria-label="ArchiveBox Plugin Library source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-dl/">One-shot abx-dl CLI</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-dl" aria-label="One-shot abx-dl CLI source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#your-server-your-choice">ArchiveBox Server.app</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="ArchiveBox Server.app source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 1Line truncated
<div class="abx-footer-bottom"><p>Built in the open. Supported by our community.</p><p><a href="https://github.com/ArchiveBox">GitHub organization</a> · <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview">Security &amp; privacy</a> · <a href="https://archivebox.io">ArchiveBox.io ↗</a></p></div>
</footer>
+1 -1
View File
@@ -1,7 +1,7 @@
<header class="abx-header">
<a class="abx-brand" href="https://archivebox.io/"><svg class="abx-logo" viewBox="0 0 40 40" aria-hidden="true"><rect width="40" height="40" rx="10" fill="#9b2854"/><path d="M10 14h20v17H10z" fill="#fff4ed"/><path d="M8 9h24v6H8z" fill="#fff4ed"/><path d="M16 19h8v3h-8z" fill="#9b2854"/><path d="M12 31V17" stroke="#9b2854" stroke-width="2"/></svg><span>ArchiveBox</span><span class="abx-subsite">UI Screenshots</span></a>
<nav class="abx-nav" aria-label="Main navigation">
<details class="abx-apps"><summary>Apps</summary><div class="abx-app-links"><a href="https://archivebox.io/">ArchiveBox Server</a><a href="https://archivebox.github.io/ios-archivebox/">ArchiveBox for macOS &amp; iOS</a><a href="https://archivebox.github.io/archivebox-browser-extension/">ArchiveBox Browser Extension</a><a href="https://archivebox.github.io/abx-plugins/">ArchiveBox Plugin Library</a><a href="https://archivebox.github.io/abx-dl/">One-shot <code>abx-dl</code> CLI</a><a href="https://github.com/ArchiveBox">More on Github...</a></div></details>
<details class="abx-apps"><summary>Apps</summary><div class="abx-app-links"><a href="https://archivebox.io/">ArchiveBox Server</a><a href="https://archivebox.github.io/ios-archivebox/">ArchiveBox for macOS &amp; iOS</a><a href="https://archivebox.github.io/archivebox-browser-extension/">ArchiveBox Browser Extension</a><a href="https://archivebox.github.io/abx-plugins/">ArchiveBox Plugin Library</a><a href="https://archivebox.github.io/abx-dl/"><span>One-shot <code>abx-dl</code> CLI</span></a><a href="https://github.com/ArchiveBox">More on Github...</a></div></details>
<a href="https://archivebox.io/screenshots/">Screenshots</a><a href="https://github.com/ArchiveBox/ArchiveBox/wiki">Docs</a>
<a href="https://github.com/ArchiveBox/ArchiveBox">GitHub ↗</a>
<a class="abx-cta" href="https://archivebox.io/#install">Get started</a>
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# Real Compose regression checks. Build the image under test first, then run:
# IMAGE=archivebox/archivebox:issue-1872 ./bin/validate_docker_display.sh
set -Eeuo pipefail
export IMAGE="${IMAGE:-archivebox/archivebox:dev}"
validation_dir="$(mktemp -d "${TMPDIR:-/tmp}/archivebox-display.XXXXXX")"
compose=(docker compose --project-name "archivebox-display-$$" --file "$validation_dir/compose.yml")
cleanup() {
"${compose[@]}" down --volumes --remove-orphans
echo "Validation files: $validation_dir"
}
trap cleanup EXIT
cat > "$validation_dir/compose.yml" <<'YAML'
services:
archivebox:
image: ${IMAGE}
volumes:
- ./data:/data
- ./data/personas:/data/personas
- tmp:/tmp/archivebox
shm_size: 1gb
novnc:
image: theasp/novnc:latest
environment:
DISPLAY_WIDTH: 1280
DISPLAY_HEIGHT: 800
RUN_XTERM: "no"
healthcheck:
test: ["CMD", "xdpyinfo", "-display", ":0"]
interval: 2s
timeout: 2s
retries: 10
volumes:
tmp:
YAML
"${compose[@]}" up -d --wait novnc
# Check the real runtime dependency as well as successful X11 connectivity.
"${compose[@]}" run --rm archivebox sh -ec '
command -v xdpyinfo
test "$DISPLAY" = novnc:0.0
xdpyinfo >/dev/null
'
"${compose[@]}" run --rm -e DISPLAY=novnc:0.0 archivebox sh -ec '
test "$DISPLAY" = novnc:0.0
xdpyinfo >/dev/null
'
# Explicit values belong to the caller, even when X11 is unavailable.
"${compose[@]}" run --rm -e DISPLAY=unavailable:0 archivebox sh -ec '
test "$DISPLAY" = unavailable:0
'
# An explicit empty value disables automatic display discovery.
"${compose[@]}" run --rm -e DISPLAY= archivebox sh -ec '
test "${DISPLAY+x}" = x
test -z "$DISPLAY"
'
"${compose[@]}" stop novnc
"${compose[@]}" run --rm archivebox sh -ec '
test "${DISPLAY+x}" != x
'
"${compose[@]}" run --rm -e DISPLAY=novnc:0.0 archivebox sh -ec '
test "$DISPLAY" = novnc:0.0
'
echo 'PASS: Compose DISPLAY discovery, explicit override, empty opt-out, and headless fallback'
+16
View File
@@ -149,6 +149,22 @@ ssh -N -L 8080:127.0.0.1:8080 user@your-server
4. Open a page and confirm you can view it while logged in. For a new persona, log in to the sites you want to archive. Then follow [Save and check the page](#3-save-and-check-the-page), selecting the same persona.
#### One-off Compose setup
To set up a persona without starting the ArchiveBox server, enable the same `novnc` service and healthy `depends_on` block, then run:
```bash
docker compose up -d --wait novnc
docker compose run --rm archivebox persona create personal
docker compose run --rm -e DISPLAY=novnc:0.0 archivebox persona open personal
```
Connect at <http://localhost:8080/vnc.html>, log in, and close the browser when finished. The persona remains in `data/personas/personal` across one-off containers.
`persona open` resolves the installed Chromium binary automatically. Do not hard-code `/data/lib/env/bin/chromium` or a versioned Playwright cache path: the browser location varies by image version and architecture.
An explicitly set `DISPLAY` is preserved. When it is unset, ArchiveBox probes `novnc:0.0` and falls back to headless operation if unavailable. Set `DISPLAY=` to disable this automatic display selection.
## Troubleshooting Chromium Install
<a name="more-info--troubleshooting"></a>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "archivebox",
"version": "0.9.35rc473",
"version": "0.9.35rc517",
"repository": "github:ArchiveBox/ArchiveBox",
"license": "MIT",
"dependencies": {
Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+11
View File
@@ -0,0 +1,11 @@
# Integration brand icons
Original brand artwork used to identify tools and services.
- [google-drive.svg](https://raw.githubusercontent.com/homarr-labs/dashboard-icons/main/svg/google-drive.svg)
- [n8n.svg](https://raw.githubusercontent.com/homarr-labs/dashboard-icons/main/svg/n8n.svg)
- [slack.svg](https://raw.githubusercontent.com/homarr-labs/dashboard-icons/main/svg/slack.svg)
- [ldap.png](https://www.tenfold-security.com/wp-content/uploads/LDAP.png)
- [codex.svg](https://raw.githubusercontent.com/lobehub/lobe-icons/master/packages/static-svg/icons/codex.svg)
- [claude-code.svg](https://raw.githubusercontent.com/lobehub/lobe-icons/master/packages/static-svg/icons/claudecode-color.svg)
- [aws-s3-wordmark.svg](https://cdn.worldvectorlogo.com/logos/amazon-s3.svg): original AWS S3 wordmark, with its SVG viewBox focused on the S3 lettering for readability at icon size.
@@ -0,0 +1 @@
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="430 38 160 104" width="160" height="104"><style>.st0{fill:#252f3e}.st1{fill:#f90}</style><title>AS3Logo</title><path class="st0" d="M84.7 65.3c-.1 3 .3 6 1.1 8.9.9 2.5 2 4.9 3.2 7.2.4.7.7 1.5.7 2.3-.1 1.2-.8 2.4-1.9 3l-6.3 4.2c-.8.5-1.7.9-2.6.9-1.1-.1-2.2-.6-3-1.4-1.3-1.4-2.6-3-3.6-4.7-1-1.7-2-3.6-3.1-5.9-7.8 9.2-17.6 13.8-29.4 13.8-8.4 0-15.1-2.4-20-7.2s-7.4-11.2-7.4-19.2c0-8.5 3-15.4 9.1-20.6s14.2-7.8 24.5-7.8c3.5 0 7.1.3 10.6.8 3.7.5 7.5 1.3 11.5 2.2v-7.3c0-7.6-1.6-12.9-4.7-16s-8.6-4.6-16.3-4.6c-3.6 0-7.3.4-10.8 1.3-3.7.9-7.3 2-10.8 3.4-1.1.5-2.3.9-3.5 1.3-.5.2-1.1.3-1.6.3-1.4 0-2.1-1-2.1-3.1v-4.9c-.1-1.2.2-2.4.7-3.5.8-.9 1.7-1.6 2.8-2.1 4-2 8.2-3.5 12.6-4.5C39.5.8 44.8.2 50 .2c11.9 0 20.6 2.7 26.2 8.1s8.3 13.6 8.3 24.6v32.4h.2zM44.1 80.5c3.5 0 7-.6 10.3-1.8 3.7-1.3 6.9-3.5 9.5-6.4 1.6-1.8 2.8-4 3.4-6.4.7-2.8 1-5.8 1-8.7V53c-3-.7-6.1-1.3-9.2-1.7-3.1-.4-6.3-.6-9.4-.6-6.7 0-11.6 1.3-14.9 4s-4.9 6.5-4.9 11.5c0 4.7 1.2 8.2 3.7 10.6s5.9 3.7 10.5 3.7zm80.3 10.8c-1.3.1-2.7-.2-3.8-1-1-1.1-1.8-2.4-2.1-3.9L95 9.1c-.5-1.3-.8-2.6-.9-4-.1-1.2.7-2.3 1.9-2.5h10.4c1.9 0 3.2.3 3.9 1s1.4 2 2 3.9L129 73.7l15.6-66.2c.5-2 1.1-3.3 1.9-3.9 1.2-.7 2.6-1.1 4-1h8c1.9 0 3.2.3 4 1 1 1.1 1.7 2.4 1.9 3.9l15.8 67 17.3-67c.3-1.5 1-2.8 2-3.9 1.2-.7 2.5-1.1 3.9-1h9.3c1.2-.2 2.3.7 2.5 1.9v.6c0 .5-.1 1.1-.2 1.6-.2.9-.4 1.7-.7 2.5l-24.1 77.3c-.6 2-1.3 3.3-2.1 3.9-1.1.7-2.5 1.1-3.8 1h-8.6c-1.9 0-3.2-.3-4-1-1-1.1-1.7-2.5-1.9-4l-15.5-64.5-15.4 64.4c-.2 1.5-.9 2.9-1.9 4-1.2.8-2.6 1.1-4 1h-8.6zM252.9 94c-5.2 0-10.4-.6-15.4-1.8-5-1.2-8.9-2.5-11.5-4-1.3-.6-2.4-1.6-3.1-2.8-.4-.9-.6-1.8-.6-2.8v-5.1c0-2.1.8-3.1 2.3-3.1.6 0 1.2.1 1.8.3.6.2 1.5.6 2.5 1 3.5 1.6 7.2 2.7 11 3.5 3.9.8 7.9 1.2 11.9 1.2 6.3 0 11.2-1.1 14.6-3.3 3.3-2 5.3-5.6 5.2-9.5.1-2.6-.9-5.1-2.7-7-1.8-1.9-5.2-3.6-10.1-5.2l-14.5-4.5c-7.3-2.3-12.7-5.7-16-10.2-3.2-4.2-5-9.2-5-14.5-.1-3.9.8-7.7 2.7-11.1 1.8-3.2 4.2-6 7.2-8.2 3.1-2.4 6.6-4.1 10.4-5.2 4.1-1.2 8.3-1.8 12.6-1.7 2.2 0 4.5.1 6.7.4 2.3.3 4.4.7 6.5 1.1s3.9 1 5.7 1.6c1.5.5 2.9 1.1 4.2 1.8 1.2.6 2.2 1.4 3 2.5.7 1 1 2.1.9 3.3v4.7c0 2.1-.8 3.2-2.3 3.2-1.3-.2-2.6-.6-3.8-1.2-6-2.7-12.6-4-19.2-3.9-5.7 0-10.2.9-13.3 2.8s-4.7 4.8-4.7 8.9c-.1 2.7 1 5.3 3 7.1 2 1.9 5.7 3.8 11 5.5l14.2 4.5c7.2 2.3 12.4 5.5 15.5 9.6 3.1 4 4.7 9 4.6 14 .1 4-.8 8-2.6 11.6-1.8 3.4-4.3 6.4-7.3 8.8-3.3 2.6-7.1 4.5-11.1 5.6-4.6 1.4-9.4 2.1-14.3 2.1z"/><path class="st1" d="M271.8 142.6c-32.9 24.3-80.7 37.2-121.8 37.2-57.6 0-109.5-21.3-148.7-56.7-3.1-2.8-.3-6.6 3.4-4.4 42.4 24.6 94.7 39.5 148.8 39.5 39-.2 77.6-8.1 113.5-23.2 5.5-2.5 10.2 3.6 4.8 7.6z"/><path class="st1" d="M285.5 127c-4.2-5.4-27.8-2.6-38.5-1.3-3.2.4-3.7-2.4-.8-4.5 18.8-13.2 49.7-9.4 53.3-5 3.6 4.4-1 35.4-18.6 50.2-2.7 2.3-5.3 1.1-4.1-1.9 4-9.9 12.9-32.2 8.7-37.5z"/><path class="st0" d="M460.6 112.4c1 2 2.5 3.7 4.3 5 1.9 1.3 4 2.3 6.3 2.8 2.4.6 4.9.9 7.4.9 1.9 0 3.7-.2 5.6-.4 1.9-.3 3.8-.8 5.6-1.7 1.7-.8 3.2-2 4.3-3.4 1.2-1.6 1.8-3.5 1.7-5.5.1-2.2-.8-4.3-2.3-5.8-1.7-1.6-3.8-2.8-6-3.7-2.7-1.1-5.5-1.9-8.4-2.6-3.1-.7-6.3-1.6-9.5-2.5-3.3-.8-6.5-1.8-9.7-3-3-1.1-5.9-2.7-8.4-4.7-2.5-1.9-4.5-4.3-6-7.1-1.6-3.2-2.4-6.7-2.3-10.3-.1-4.1.9-8.2 3-11.8 1.9-3.3 4.5-6.2 7.6-8.4 3.2-2.3 6.8-3.9 10.6-5 3.9-1.1 7.9-1.6 11.9-1.6 4.5 0 8.9.5 13.3 1.5 4.1.9 7.9 2.6 11.3 5 3.3 2.3 6 5.3 7.9 8.8 2 4 3 8.5 2.9 13h-18.8c-.1-2.3-.7-4.5-1.7-6.5-.9-1.7-2.2-3.1-3.8-4.1-1.7-1-3.5-1.7-5.4-2.1-2.2-.4-4.4-.6-6.6-.6-1.6 0-3.2.2-4.7.5s-3 .9-4.3 1.7c-1.3.8-2.3 1.9-3.1 3.1-.9 1.4-1.3 3-1.2 4.7-.1 1.5.3 2.9 1 4.2 1 1.4 2.3 2.4 3.9 3 2.6 1.1 5.3 2 8 2.7 3.4.9 7.9 2.1 13.4 3.5 1.6.3 3.9.9 6.9 1.8 3.1.9 6 2.3 8.7 4.1 3 2 5.6 4.5 7.5 7.5 2.1 3.2 3.2 7.2 3.2 12.2 0 3.9-.8 7.7-2.4 11.3-1.6 3.5-4 6.6-7 9-3.4 2.7-7.3 4.7-11.5 5.9-5.2 1.5-10.5 2.2-15.9 2.1-4.8 0-9.5-.6-14.2-1.8-4.4-1.1-8.5-3-12.1-5.7-3.5-2.6-6.4-5.9-8.4-9.8-2.2-4.4-3.2-9.2-3-14.1H459c-.1 2.9.5 5.5 1.6 7.9zM551.8 82.5c2.1-.1 4.1-.6 6-1.4 1.8-.7 3.4-1.9 4.6-3.4 1.3-1.7 1.9-3.8 1.8-5.9 0-3.7-1.2-6.6-3.7-8.5-2.4-2-5.4-3-8.5-3-4.5 0-7.8 1.5-10.1 4.4-2.4 3.2-3.5 7.1-3.3 11.1h-16.7c.1-4.2.9-8.3 2.4-12.2 1.4-3.5 3.4-6.8 6.1-9.5 2.7-2.7 5.8-4.8 9.3-6.1 3.9-1.5 8-2.2 12.1-2.2 3.5 0 7 .5 10.4 1.5 3.4 1 6.5 2.6 9.3 4.6 2.7 2 5 4.6 6.7 7.5 1.8 3.1 2.7 6.7 2.6 10.3.1 3.9-1 7.8-3 11.1-2.1 3.3-5.3 5.6-9.1 6.6v.3c4.4.9 8.4 3.3 11.2 6.9 2.8 3.7 4.2 8.2 4.1 12.7.1 4.2-.8 8.4-2.6 12.1-1.7 3.5-4.1 6.5-7.1 8.9-3.1 2.4-6.5 4.3-10.3 5.4-3.9 1.2-8 1.9-12.1 1.9-4.5.1-9-.7-13.3-2.1-3.8-1.3-7.3-3.4-10.2-6.1-2.9-2.8-5.1-6.1-6.5-9.9-1.6-4.3-2.3-8.8-2.2-13.4h16.7c.1 2.2.4 4.5 1.1 6.6.6 2 1.6 3.8 2.9 5.5 1.3 1.5 2.8 2.8 4.6 3.6 2.1 1 4.3 1.4 6.6 1.4 3.7.1 7.3-1.2 10-3.6 2.7-2.4 4.1-5.8 4.1-10 0-3.3-.6-5.8-1.9-7.5-1.2-1.7-2.9-3-4.9-3.8-2.1-.8-4.3-1.2-6.5-1.3-2.4-.1-4.6-.2-6.7-.2V82.5c2 .2 4.1.2 6.1 0zM375.4 1.9h7v176h-7z"/></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

@@ -0,0 +1 @@
<svg fill="#569A31" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Amazon S3</title><path d="M20.913 13.147l.12-.895c.947.576 1.258.922 1.354 1.071-.16.031-.562.046-1.474-.176zm-2.174 7.988a.547.547 0 0 0-.005.073c0 .084-.207.405-1.124.768a10.28 10.28 0 0 1-1.438.432c-1.405.325-3.128.504-4.853.504-4.612 0-7.412-1.184-7.412-1.704a.547.547 0 0 0-.005-.073L1.81 5.602c.135.078.28.154.432.227.042.02.086.038.128.057.134.062.272.122.417.18l.179.069c.154.058.314.114.478.168.043.013.084.029.13.043.207.065.423.127.646.187l.176.044c.175.044.353.087.534.127a23.414 23.414 0 0 0 .843.17l.121.023c.252.045.508.085.768.122.071.011.144.02.216.03.2.027.4.053.604.077l.24.027c.245.026.49.05.74.07l.081.009c.275.022.552.04.83.056l.233.012c.21.01.422.018.633.025a33.088 33.088 0 0 0 2.795-.026l.232-.011c.278-.016.555-.034.83-.056l.08-.008c.25-.02.497-.045.742-.072l.238-.026c.205-.024.408-.05.609-.077.07-.01.141-.019.211-.03.261-.037.519-.078.772-.122l.111-.02c.215-.04.427-.082.634-.125l.212-.047c.186-.041.368-.085.546-.13l.166-.042c.225-.06.444-.122.654-.189.04-.012.077-.026.115-.038a10.6 10.6 0 0 0 .493-.173c.058-.021.114-.044.17-.066.15-.06.293-.12.43-.185.038-.017.079-.034.116-.052.153-.073.3-.15.436-.228l-.976 7.245c-2.488-.78-5.805-2.292-7.311-3a1.09 1.09 0 0 0-1.088-1.085c-.6 0-1.088.489-1.088 1.088 0 .6.488 1.089 1.088 1.089.196 0 .378-.056.537-.148 1.72.812 5.144 2.367 7.715 3.15zm-7.42-20.047c5.677 0 9.676 1.759 9.75 2.736l-.014.113c-.01.033-.031.067-.048.101-.015.028-.026.057-.047.087-.024.033-.058.068-.09.102-.028.03-.051.06-.084.09-.038.035-.087.07-.133.105-.04.03-.074.06-.119.091-.053.036-.116.071-.177.107-.05.03-.095.06-.15.09-.068.036-.147.073-.222.11-.059.028-.114.057-.177.085-.084.038-.177.074-.268.111-.068.027-.13.054-.203.082-.097.036-.205.072-.31.107-.075.026-.148.053-.228.079-.111.035-.233.069-.35.103-.085.024-.165.05-.253.073-.124.034-.258.065-.389.098-.093.022-.181.046-.278.068-.139.032-.287.061-.433.091-.098.02-.191.041-.293.06-.155.03-.32.057-.482.084-.1.018-.198.036-.302.052-.166.026-.342.048-.515.072-.11.014-.213.03-.325.044-.181.023-.372.041-.56.06-.11.012-.218.025-.332.036-.188.016-.386.029-.58.043-.122.009-.24.02-.364.028-.207.012-.422.02-.635.028-.12.005-.234.012-.354.016a35.605 35.605 0 0 1-2.069 0c-.12-.004-.234-.011-.352-.016-.214-.008-.43-.016-.637-.028-.122-.008-.238-.02-.36-.027-.195-.015-.394-.028-.584-.044-.11-.01-.215-.024-.324-.035-.19-.02-.384-.038-.568-.06l-.315-.044c-.176-.024-.355-.046-.525-.073-.1-.015-.192-.033-.29-.05-.167-.028-.335-.055-.494-.086-.096-.018-.183-.038-.276-.056-.151-.032-.305-.062-.45-.095-.09-.02-.173-.043-.26-.064-.138-.034-.277-.067-.407-.102-.082-.022-.157-.046-.235-.069a11.75 11.75 0 0 1-.368-.108c-.075-.024-.141-.049-.213-.073-.11-.037-.223-.075-.325-.113-.067-.025-.125-.051-.188-.077-.096-.038-.195-.076-.282-.115-.06-.027-.11-.054-.166-.08-.08-.039-.162-.077-.233-.116-.052-.028-.094-.055-.142-.084-.063-.038-.13-.075-.185-.113-.043-.029-.075-.058-.113-.086-.048-.037-.098-.073-.139-.11-.032-.029-.054-.057-.08-.087-.033-.035-.069-.07-.093-.104-.02-.03-.031-.058-.046-.086-.018-.035-.039-.068-.049-.102l-.015-.113c.076-.977 4.074-2.736 9.748-2.736zm12.182 12.124c-.118-.628-.84-1.291-2.31-2.128l.963-7.16a.531.531 0 0 0 .005-.073C22.16 1.581 16.447 0 11.32 0 6.194 0 .482 1.581.482 3.851a.58.58 0 0 0 .005.072L2.819 21.25c.071 2.002 5.236 2.75 8.5 2.75 1.805 0 3.615-.188 5.098-.531.598-.138 1.133-.3 1.592-.48 1.18-.467 1.789-1.053 1.813-1.739l.945-7.018c.557.131 1.016.197 1.389.197.54 0 .902-.137 1.134-.413a.956.956 0 0 0 .21-.804Z"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1 @@
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude Code</title><path clip-rule="evenodd" d="M20.998 10.949H24v3.102h-3v3.028h-1.487V20H18v-2.921h-1.487V20H15v-2.921H9V20H7.488v-2.921H6V20H4.487v-2.921H3V14.05H0V10.95h3V5h17.998v5.949zM6 10.949h1.488V8.102H6v2.847zm10.51 0H18V8.102h-1.49v2.847z" fill="#D97757" fill-rule="evenodd"></path></svg>

After

Width:  |  Height:  |  Size: 425 B

+1
View File
@@ -0,0 +1 @@
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Codex</title><path clip-rule="evenodd" d="M8.086.457a6.105 6.105 0 013.046-.415c1.333.153 2.521.72 3.564 1.7a.117.117 0 00.107.029c1.408-.346 2.762-.224 4.061.366l.063.03.154.076c1.357.703 2.33 1.77 2.918 3.198.278.679.418 1.388.421 2.126a5.655 5.655 0 01-.18 1.631.167.167 0 00.04.155 5.982 5.982 0 011.578 2.891c.385 1.901-.01 3.615-1.183 5.14l-.182.22a6.063 6.063 0 01-2.934 1.851.162.162 0 00-.108.102c-.255.736-.511 1.364-.987 1.992-1.199 1.582-2.962 2.462-4.948 2.451-1.583-.008-2.986-.587-4.21-1.736a.145.145 0 00-.14-.032c-.518.167-1.04.191-1.604.185a5.924 5.924 0 01-2.595-.622 6.058 6.058 0 01-2.146-1.781c-.203-.269-.404-.522-.551-.821a7.74 7.74 0 01-.495-1.283 6.11 6.11 0 01-.017-3.064.166.166 0 00.008-.074.115.115 0 00-.037-.064 5.958 5.958 0 01-1.38-2.202 5.196 5.196 0 01-.333-1.589 6.915 6.915 0 01.188-2.132c.45-1.484 1.309-2.648 2.577-3.493.282-.188.55-.334.802-.438.286-.12.573-.22.861-.304a.129.129 0 00.087-.087A6.016 6.016 0 015.635 2.31C6.315 1.464 7.132.846 8.086.457zm-.804 7.85a.848.848 0 00-1.473.842l1.694 2.965-1.688 2.848a.849.849 0 001.46.864l1.94-3.272a.849.849 0 00.007-.854l-1.94-3.393zm5.446 6.24a.849.849 0 000 1.695h4.848a.849.849 0 000-1.696h-4.848z"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 512 512"><path d="m38.7 419.3 22.6 39c4.7 8.2 11.4 14.7 19.4 19.4l80.6-139.6H0c0 9.1 2.3 18.2 7 26.4z" style="fill:#0066da"/><path d="M256 173.9 175.4 34.3c-7.9 4.7-14.7 11.1-19.4 19.4L7 311.7c-4.6 8-7 17.1-7 26.4h161.3z" style="fill:#00ac47"/><path d="M431.4 477.7c7.9-4.7 14.7-11.1 19.4-19.4l9.4-16.1 44.9-77.7c4.7-8.2 7-17.3 7-26.4H350.7l34.3 67.4z" style="fill:#ea4335"/><path d="m256 173.9 80.6-139.6c-7.9-4.7-17-7-26.4-7H201.8c-9.4 0-18.5 2.6-26.4 7z" style="fill:#00832d"/><path d="M350.7 338.1H161.3L80.6 477.7c7.9 4.7 17 7 26.4 7h298c9.4 0 18.5-2.6 26.4-7z" style="fill:#2684fc"/><path d="M430.5 182.7 356 53.7c-4.7-8.2-11.4-14.7-19.4-19.4L256 173.9l94.7 164.2h161c0-9.1-2.3-18.2-7-26.4z" style="fill:#ffba00"/></svg>

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 121.3 512.1 269.6"><path d="M458.1 229.1c-25.1 0-46.2-17.2-52.2-40.4h-61.8c-13.2 0-24.4 9.5-26.6 22.5l-2.2 13.3c-2 12.2-8.2 23.4-17.5 31.6 9.3 8.2 15.5 19.3 17.5 31.6l2.2 13.3c2.2 13 13.4 22.5 26.6 22.5h7.9c6-23.2 27.1-40.4 52.2-40.4 29.8 0 53.9 24.1 53.9 53.9s-24.1 53.9-53.9 53.9c-25.1 0-46.2-17.2-52.2-40.4h-7.9c-26.3 0-48.8-19-53.2-45l-2.2-13.3c-2.2-13-13.4-22.5-26.6-22.5h-21.4c-6 23.2-27.1 40.4-52.2 40.4s-46.2-17.2-52.2-40.4H106c-6 23.2-27.1 40.4-52.2 40.4C24.1 309.9 0 285.8 0 256s24.1-53.9 53.9-53.9c25.1 0 46.2 17.2 52.2 40.4h30.3c6-23.2 27.1-40.4 52.2-40.4s46.2 17.2 52.2 40.4h21.4c13.2 0 24.4-9.5 26.6-22.5l2.2-13.3c4.3-26 26.8-45 53.2-45H406c6-23.2 27.1-40.4 52.2-40.4 29.8 0 53.9 24.1 53.9 53.9s-24.2 53.9-54 53.9m0-27c14.9 0 26.9-12.1 26.9-26.9s-12.1-26.9-26.9-26.9-26.9 12.1-26.9 26.9 12 26.9 26.9 26.9M53.9 282.9c14.9 0 26.9-12.1 26.9-26.9s-12.1-26.9-26.9-26.9-27 12-27 26.9 12.1 26.9 27 26.9M215.6 256c0 14.9-12.1 26.9-26.9 26.9s-26.9-12.1-26.9-26.9 12.1-26.9 26.9-26.9 26.9 12 26.9 26.9m215.6 80.8c0 14.9-12.1 26.9-26.9 26.9-14.9 0-26.9-12.1-26.9-26.9s12.1-26.9 26.9-26.9 26.9 12.1 26.9 26.9" style="fill-rule:evenodd;clip-rule:evenodd;fill:#ea4b71"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="49.13 2.23 413.74 507.44"><linearGradient id="a" x1="-659.761" x2="-640.696" y1="769.342" y2="769.342" gradientTransform="matrix(21.1429 0 0 -21.1429 14003.722 16522.121)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#729fcf"/><stop offset=".316" style="stop-color:#babdb6"/><stop offset="1" style="stop-color:#3465a4"/></linearGradient><linearGradient id="b" x1="131.24" x2="589.471" y1="310.846" y2="310.846" gradientTransform="matrix(.9013 0 0 -1.1095 -68.802 600.87)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#729fcf"/><stop offset="1" style="stop-color:#204a87"/></linearGradient><path d="M254.3 12.8C147 12.8 59.7 51.1 59.7 98.1v315.7c0 47.1 87.3 85.3 194.6 85.3s198-38.3 198-85.3V98.1c0-47-90.7-85.3-198-85.3z" style="fill:url(#a);stroke:url(#b);stroke-width:21.1429;stroke-miterlimit:10"/><linearGradient id="c" x1="-655.123" x2="-638.939" y1="779.44" y2="746.331" gradientTransform="matrix(21.1429 0 0 -21.1429 14003.722 16522.121)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#3977c3"/><stop offset="1" style="stop-color:#89aedc;stop-opacity:0"/></linearGradient><path d="M254.4 23.4C154.3 23.4 73 59.1 73 103v302.1c0 43.9 81.4 79.6 181.4 79.6S439 449 439 405.1V103c0-43.9-84.6-79.6-184.6-79.6z" style="opacity:.5443;fill:none;stroke:url(#c);stroke-width:21.1429;stroke-miterlimit:10"/><linearGradient id="d" x1="-651.29" x2="-651.29" y1="775.963" y2="778.151" gradientTransform="matrix(21.9314 0 0 -20.1834 14538.794 15792.006)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#fff"/><stop offset="1" style="stop-color:#729fcf"/></linearGradient><path d="M437.2 97c0 39.6-81.5 71.7-182.1 71.7S73 136.6 73 97s81.5-71.7 182.1-71.7S437.2 57.4 437.2 97z" style="fill:#3465a4;stroke:url(#d);stroke-width:1.0049;stroke-miterlimit:10"/><linearGradient id="e" x1="-654.544" x2="-654.729" y1="774.918" y2="768.138" gradientTransform="matrix(21.1429 0 0 -21.1429 14000.701 16577.998)" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#fff"/><stop offset="1" style="stop-color:#fff;stop-opacity:0"/></linearGradient><path d="m113.7 160.4 4.9 229.2 62.4 17.6-2-228.3s28.3 0 74.1-2.9c-71.2-3.2-152.7-33.8-180.4-53.6 19.4 28.5 41 38 41 38" style="opacity:.4937;fill:url(#e)"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 512 512"><path d="M107.9 323.6c0 29.7-24 53.8-53.8 53.8S.3 353.4.3 323.6c0-29.7 24-53.8 53.8-53.8h53.8zm26.9 0c0-29.7 24-53.8 53.8-53.8s53.8 24 53.8 53.8V458c0 29.7-24 53.8-53.8 53.8s-53.8-24-53.8-53.8z" style="fill:#e01e5a"/><path d="M188.6 107.7c-29.7 0-53.8-24-53.8-53.8S158.8.1 188.6.1s53.8 24 53.8 53.8v53.8zm0 27.3c29.7 0 53.8 24 53.8 53.8s-24 53.8-53.8 53.8H53.8C24 242.6 0 218.5 0 188.8S24 135 53.8 135z" style="fill:#36c5f0"/><path d="M404.1 188.8c0-29.7 24-53.8 53.8-53.8s53.8 24 53.8 53.8-24 53.8-53.8 53.8h-53.8zm-26.9 0c0 29.7-24 53.8-53.8 53.8-29.7 0-53.8-24-53.8-53.8V54c0-29.7 24-53.8 53.8-53.8s53.8 24 53.8 53.8z" style="fill:#2eb67d"/><path d="M323.4 404.3c29.7 0 53.8 24 53.8 53.8 0 29.7-24 53.8-53.8 53.8-29.7 0-53.8-24-53.8-53.8v-53.8zm0-26.9c-29.7 0-53.8-24-53.8-53.8s24-53.8 53.8-53.8h134.8c29.7 0 53.8 24 53.8 53.8 0 29.7-24 53.8-53.8 53.8z" style="fill:#ecb22e"/></svg>

After

Width:  |  Height:  |  Size: 969 B

+14
View File
@@ -0,0 +1,14 @@
# Plugin brand icons
Original brand artwork used to identify supported tools. SVG fills use the brand colors.
- [chrome.svg](https://raw.githubusercontent.com/devicons/devicon/master/icons/chrome/chrome-original.svg)
- [ublock.svg](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/ublockorigin.svg)
- [github.svg](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/github.svg)
- [archive-org.svg](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/internetarchive.svg)
- [claude.svg](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/claude.svg)
- [webrecorder.svg](https://webrecorder.net/favicon.svg)
- [singlefile.png](https://raw.githubusercontent.com/gildas-lormeau/SingleFile/master/src/ui/resources/icon_128.png)
- [youtube.svg](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/youtube.svg)
- [tailscale.svg](https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/tailscale.svg)
- [tlsnotary.svg](https://tlsnotary.org/img/logo/tlsn-logo-blue.svg)
@@ -0,0 +1 @@
<svg fill="#333333" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Internet Archive</title><path d="M22.667 22.884V24H1.333v-1.116zm-.842-1.675v1.396H2.175v-1.396zM4.233 6.14l.234.118.118 1.882.117 3.058v2.941l-.117 3.666-.02 2.47-.332.098H3.062l-.352-.098-.136-2.47-.118-3.646v-2.941l.118-3.078.107-1.892.244-.107zm16.842 0l.235.118.117 1.882.117 3.058v2.941l-.117 3.666-.02 2.47-.332.098h-1.171l-.352-.098-.137-2.47-.117-3.646v-2.941l.117-3.078.108-1.892.244-.107zm-11.79 0l.235.118.117 1.882.117 3.058v2.941l-.117 3.666-.02 2.47-.331.098H8.114l-.352-.098-.136-2.47-.117-3.646v-2.941l.117-3.078.107-1.892.244-.107zm6.457 0l.234.118.117 1.882.118 3.058v2.941l-.118 3.666-.019 2.47-.332.098H14.57l-.351-.098-.137-2.47-.117-3.646v-2.941l.117-3.078.108-1.892.244-.107zm6.083-2.511V5.58H2.175V3.628zM11.798 0l10.307 2.347-.413.723H1.951l-.618-.587Z"/></svg>

After

Width:  |  Height:  |  Size: 881 B

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><circle fill="#fff" cx="64.149" cy="64.236" r="60.999"/><path fill-opacity=".1" d="M102.966 75.327c0-21.439-17.379-38.819-38.817-38.819s-38.818 17.38-38.818 38.819h11.09c0-15.314 12.415-27.727 27.727-27.727 15.313 0 27.727 12.413 27.727 27.727"/><circle fill-opacity=".1" cx="66.922" cy="71.999" r="21.072"/><linearGradient id="chrome-original-a" gradientUnits="userSpaceOnUse" x1="395.191" y1="484.168" x2="395.191" y2="484.723" gradientTransform="matrix(82 0 0 82 -32341.5 -39660.313)"><stop offset="0" stop-color="#81B4E0"/><stop offset="1" stop-color="#0C5A94"/></linearGradient><circle fill="url(#chrome-original-a)" cx="64.149" cy="64.235" r="22.736"/><linearGradient id="chrome-original-b" gradientUnits="userSpaceOnUse" x1="-608.91" y1="-597.648" x2="-608.91" y2="-547.185" gradientTransform="translate(675 599.775)"><stop offset="0" stop-color="#F06B59"/><stop offset="1" stop-color="#DF2227"/></linearGradient><path fill="url(#chrome-original-b)" d="M119.602 36.508C104.336 5.792 67.06-6.732 36.343 8.534A62.105 62.105 0 0012.578 29.3l24.955 43.253c-4.597-14.606 3.521-30.174 18.127-34.77a27.676 27.676 0 017.935-1.274"/><linearGradient id="chrome-original-c" gradientUnits="userSpaceOnUse" x1="-657.835" y1="-491.393" x2="-632.327" y2="-533.537" gradientTransform="translate(675 599.775)"><stop offset="0" stop-color="#388B41"/><stop offset="1" stop-color="#4CB749"/></linearGradient><path fill="url(#chrome-original-c)" d="M12.578 29.3c-19.1 28.492-11.486 67.071 17.005 86.171a62.133 62.133 0 0029.575 10.319l26.063-44.363c-9.745 11.811-27.22 13.486-39.032 3.74a27.717 27.717 0 01-8.657-12.613"/><linearGradient id="chrome-original-d" gradientUnits="userSpaceOnUse" x1="-572.385" y1="-486.91" x2="-599.557" y2="-552.345" gradientTransform="translate(675 599.775)"><stop offset="0" stop-color="#E4B022"/><stop offset=".3" stop-color="#FCD209"/></linearGradient><path fill="url(#chrome-original-d)" d="M59.158 125.791c34.204 2.585 64.027-23.047 66.613-57.25a62.097 62.097 0 00-6.17-32.031H63.595c15.312.07 27.67 12.541 27.598 27.854a27.725 27.725 0 01-5.972 17.064"/><linearGradient id="chrome-original-e" gradientUnits="userSpaceOnUse" x1="-649.391" y1="-528.885" x2="-649.391" y2="-573.247" gradientTransform="translate(675 599.775)"><stop offset="0" stop-opacity=".15"/><stop offset=".3" stop-opacity=".06"/><stop offset="1" stop-opacity=".03"/></linearGradient><path fill="url(#chrome-original-e)" d="M12.578 29.3l24.955 43.253a27.725 27.725 0 011.107-18.854L13.686 27.636"/><linearGradient id="chrome-original-f" gradientUnits="userSpaceOnUse" x1="-588.158" y1="-514.559" x2="-618.657" y2="-483.505" gradientTransform="translate(675 599.775)"><stop offset="0" stop-opacity=".15"/><stop offset=".3" stop-opacity=".06"/><stop offset="1" stop-opacity=".03"/></linearGradient><path fill="url(#chrome-original-f)" d="M59.158 125.791l26.063-44.363a27.731 27.731 0 01-16.082 9.426l-11.091 34.937"/><linearGradient id="chrome-original-g" gradientUnits="userSpaceOnUse" x1="-588.6" y1="-505.621" x2="-584.163" y2="-549.431" gradientTransform="translate(675 599.775)"><stop offset="0" stop-opacity=".15"/><stop offset=".3" stop-opacity=".06"/><stop offset="1" stop-opacity=".03"/></linearGradient><path fill="url(#chrome-original-g)" d="M119.602 36.508H63.595a27.727 27.727 0 0121.626 10.537l35.491-8.873"/></svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+1
View File
@@ -0,0 +1 @@
<svg fill="#D97757" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

+1
View File
@@ -0,0 +1 @@
<svg fill="#181717" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

+1
View File
@@ -0,0 +1 @@
<svg fill="#242424" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Tailscale</title><path d="M24 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm-9 9a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm0-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm6-6a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM3 24a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zm18 .5a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM6 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm9-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0zm-3 2.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5zM6 3a3 3 0 1 1-6 0 3 3 0 0 1 6 0zM3 5.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/></svg>

After

Width:  |  Height:  |  Size: 646 B

+11
View File
@@ -0,0 +1,11 @@
<svg width="529" height="548" viewBox="0 0 529 548" xmlns="http://www.w3.org/2000/svg">
<path
d="M153.581 4.41505C153.581 1.08579 157.014 -1.04229 159.856 0.525709L202.517 24.065C203.907 24.8316 204.774 26.3268 204.774 27.9544V58.7885H226.105C228.461 58.7885 230.371 60.7624 230.371 63.1974V133.741L217.573 124.923V72.0154H204.774V504.359C204.774 505.115 204.586 505.859 204.227 506.519L182.897 545.751C181.266 548.75 177.089 548.75 175.458 545.751L154.128 506.519C153.769 505.859 153.581 505.115 153.581 504.359V4.41505Z"
fill="#243f5f" />
<path d="M127.984 160.194V477.639H76.7903V213.102H0V160.194H127.984Z" fill="#243f5f" />
<path d="M383.952 477.639H435.145V213.102H460.742V477.639H511.935V160.194H383.952V477.639Z"
fill="#243f5f" />
<path
d="M230.371 160.194H358.355V213.102H281.565V292.463H358.355V477.639H230.371V424.732H307.161V345.37H230.371V160.194Z"
fill="#243f5f" />
</svg>

After

Width:  |  Height:  |  Size: 943 B

+1
View File
@@ -0,0 +1 @@
<svg fill="#800000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>uBlock Origin</title><path d="M12 0C7.502 3 6.002 3 1.5 3c0 15.002 0 15.002 10.5 21 10.5-5.998 10.5-5.998 10.5-21-4.498 0-5.998 0-10.5-3zM5.956 7.472h1.512v4.536c0 1.322.19 1.508 1.512 1.508 1.323 0 1.512-.19 1.512-1.512V7.472H12v.767a3.75 3.75 0 012.268-.767 3.79 3.79 0 013.776 3.78 3.79 3.79 0 01-3.78 3.775 3.765 3.764 0 01-2.684-1.133c-.464.77-1.315 1.133-2.6 1.133-2.079 0-3.024-.944-3.024-3.023zm8.308 1.512A2.254 2.254 0 0012 11.252a2.254 2.254 0 002.268 2.264 2.254 2.254 0 002.264-2.268 2.254 2.254 0 00-2.268-2.264z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 8 8"><style>.b{fill:#088eaf}.g{fill:#4d7c0f}@media (prefers-color-scheme:dark){.b{fill:#0aaed7}.g{fill:#65a414}}</style><path d="M1.415 2.819a1.324 1.324 0 0 0 .82 2.364h1.147c.731 0 1.324-.593 1.324-1.324V3.55q.001-.037.026-.063a.1.1 0 0 1 .063-.025h.618a.088.088 0 0 1 .088.088v.309a2.12 2.12 0 0 1-2.119 2.118H2.235A2.12 2.12 0 0 1 .851 2.255l-.439-.439a.04.04 0 0 1-.009-.049.04.04 0 0 1 .04-.027h1.439c.024 0 .044.02.044.044v1.439a.04.04 0 0 1-.028.04.05.05 0 0 1-.048-.009z" class="b"/><path d="M6.497 4.899a1.325 1.325 0 0 0-.82-2.364H4.53c-.731 0-1.324.593-1.324 1.324v.309a.1.1 0 0 1-.026.062.1.1 0 0 1-.063.026h-.618a.09.09 0 0 1-.088-.088v-.309A2.12 2.12 0 0 1 4.53 1.74h1.147a2.12 2.12 0 0 1 1.384 3.723l.439.439a.05.05 0 0 1 .01.048.04.04 0 0 1-.041.027H6.031a.044.044 0 0 1-.045-.044V4.495q.001-.029.028-.041a.04.04 0 0 1 .048.01z" class="g"/></svg>

After

Width:  |  Height:  |  Size: 938 B

+1
View File
@@ -0,0 +1 @@
<svg fill="#FF0000" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>YouTube</title><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>

After

Width:  |  Height:  |  Size: 475 B

+262 -182
View File
@@ -20,7 +20,8 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&amp;display=swap" rel="stylesheet">
<link rel="stylesheet" href="./shadcn-theme.css">
<link rel="stylesheet" href="./styles.css">
<link rel="stylesheet" href="./styles.css?v=integration-icons-v1">
<script src="./install.js" defer></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
@@ -49,7 +50,7 @@
<header class="abx-header">
<a class="abx-brand" href="https://archivebox.io/"><svg class="abx-logo" viewBox="0 0 40 40" aria-hidden="true"><rect width="40" height="40" rx="10" fill="#9b2854"/><path d="M10 14h20v17H10z" fill="#fff4ed"/><path d="M8 9h24v6H8z" fill="#fff4ed"/><path d="M16 19h8v3h-8z" fill="#9b2854"/><path d="M12 31V17" stroke="#9b2854" stroke-width="2"/></svg><span>ArchiveBox</span><span class="abx-subsite">Web Archive</span></a>
<nav class="abx-nav" aria-label="Main navigation">
<details class="abx-apps"><summary>Apps</summary><div class="abx-app-links"><a href="https://archivebox.io/">ArchiveBox Server</a><a href="https://archivebox.github.io/ios-archivebox/">ArchiveBox for macOS &amp; iOS</a><a href="https://archivebox.github.io/archivebox-browser-extension/">ArchiveBox Browser Extension</a><a href="https://archivebox.github.io/abx-plugins/">ArchiveBox Plugin Library</a><a href="https://archivebox.github.io/abx-dl/">One-shot <code>abx-dl</code> CLI</a><a href="https://github.com/ArchiveBox">More on Github...</a></div></details>
<details class="abx-apps"><summary>Apps</summary><div class="abx-app-links"><a href="https://archivebox.io/">ArchiveBox Server</a><a href="https://archivebox.github.io/ios-archivebox/">ArchiveBox for macOS &amp; iOS</a><a href="https://archivebox.github.io/archivebox-browser-extension/">ArchiveBox Browser Extension</a><a href="https://archivebox.github.io/abx-plugins/">ArchiveBox Plugin Library</a><a href="https://archivebox.github.io/abx-dl/"><span>One-shot <code>abx-dl</code> CLI</span></a><a href="https://github.com/ArchiveBox">More on Github...</a></div></details>
<a href="#use-cases">Use cases</a><a href="#configuration">Configuration</a><a href="#layout-security">Layout &amp; security</a><a href="https://github.com/ArchiveBox/ArchiveBox/wiki">Docs</a>
<a href="https://github.com/ArchiveBox/ArchiveBox">GitHub ↗</a>
<a class="abx-cta" href="#install">Get started</a>
@@ -64,7 +65,7 @@
<h1><span class="hero-mainline">Preserve the web.</span><span class="hero-subline">On infrastructure you control.</span></h1>
<p class="lede">ArchiveBox saves websites, bookmarks, RSS feeds, social posts, media, source code, and research material in durable files like HTML, PDF, PNG, TXT, JSON, WARC, MP4, and SQLite.</p>
<div class="hero-actions" aria-label="Primary actions">
<a class="button primary" href="#install">Run with Docker Compose</a>
<a class="button primary" href="#install">Get ArchiveBox</a>
<a class="button secondary" href="./screenshots/">View screenshots</a>
</div>
<br/>
@@ -100,7 +101,11 @@
<span class="ab-prompt">$</span> <span class="ab-cursor" aria-hidden="true">&nbsp;</span></pre>
</div>
</div>
<img class="product-shot" src="https://github.com/ArchiveBox/ArchiveBox/assets/511499/e8e0b6f8-8fdf-4b7f-8124-c10d8699bdb2" alt="ArchiveBox snapshot list in the admin web interface">
<div class="device-showcase">
<a class="device-desktop" href="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" aria-label="Enlarge the ArchiveBox Web UI screenshot"><img class="product-shot" src="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" width="1600" height="1000" alt="ArchiveBox Web UI showing saved pages with thumbnails and capture formats"></a>
<a class="device-phone" href="https://archivebox.github.io/ios-archivebox/" aria-label="Explore ArchiveBox for iPhone"><img src="https://archivebox.github.io/ios-archivebox/docs/screenshots/home-iphone.png" width="1500" height="3000" alt="ArchiveBox on iPhone, with its collection, tags, and server connection inside an iPhone frame"></a>
</div>
<p class="device-caption">Browse and save from any device.<br>Free, self-hosted, 0 analytics.</p>
</div>
</section>
@@ -113,38 +118,55 @@
<a href="https://github.com/ArchiveBox/ArchiveBox#archive-layout">Filesystem access</a>
</section>
<section class="section split">
<div>
<section class="section features-section">
<div class="section-heading">
<p class="eyebrow">Why ArchiveBox</p>
<h2>Designed for useful archives, not proprietary silos.</h2>
<h2>Designed to make your archived data useful <em>today.</em></h2>
</div>
<div class="feature-grid">
<article>
<h3>Readable for decades</h3>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="7" rx="2"/><rect x="3" y="14" width="18" height="7" rx="2"/><path d="M7 6.5h.01M7 17.5h.01M11 6.5h6M11 17.5h6"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/06-admin-dashboard-desktop.png"><img src="https://archivebox.io/screenshots/06-admin-dashboard-desktop.png" width="1600" height="1000" loading="lazy" alt="Self-hosted ArchiveBox dashboard"></a>
</div>
<h3>Own all your data</h3>
<p>Run it as a Docker web app, use one-off CLI commands, or automate with APIs while keeping private and public data neatly separated.</p>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 3v12m-5-5 5 5 5-5M4 16v5h16v-5"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/20-crawl-schedules-desktop.png"><img src="https://archivebox.io/screenshots/20-crawl-schedules-desktop.png" width="1600" height="1000" loading="lazy" alt="Scheduled archive imports"></a>
</div>
<h3>Import URLs from anywhere</h3>
<p>Import URLs from <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart#2-get-your-list-of-urls-to-archive">bookmarks, browser history, feeds, and bookmarking apps</a>, or <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">text files</a>. Save links with our <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#browser-extension-usage">browser extension</a>, <a href="https://archivebox.github.io/ios-archivebox/">Mac and iPhone share menus, Siri, and Shortcuts</a>.</p>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="m12 3 10 5-10 5L2 8l10-5Zm-10 9 10 5 10-5M2 16l10 5 10-5"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/50-snapshot-view-pdf-desktop.png"><img src="https://archivebox.io/screenshots/50-snapshot-view-pdf-desktop.png" width="1600" height="1000" loading="lazy" alt="Saved page with multiple capture formats"></a>
</div>
<h3>Capture changes over time</h3>
<p>ArchiveBox can <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Scheduled-Archiving">import new URLs and capture snapshots on a schedule</a>. Compare snapshots over time to see how sites have changed.</p>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M3 7V5a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/><path d="M3 9h18"/></svg></span>
<a class="card-thumbnail" href="./assets/archive-files-finder.png"><img src="./assets/archive-files-finder.png" width="1044" height="492" loading="lazy" alt="Archived HTML and folders in Finder"></a>
</div>
<h3>Designed to last 100yr+</h3>
<p>Snapshots are stored as ordinary files and folders, with metadata in SQLite and JSON. You can browse the collection without depending on a hosted service.</p>
</article>
<article>
<h3>Multiple captures per URL</h3>
<p>ArchiveBox can save rendered HTML, screenshots, PDFs, WARC files, article text, headers, favicons, media, subtitles, and source repositories.</p>
</article>
<article>
<h3>Bring your sources</h3>
<p>Import one URL, pipe text into the CLI, upload exported bookmarks, or schedule recurring pulls from RSS feeds and other text-based source lists.</p>
</article>
<article>
<h3>Self-hosted by default</h3>
<p>Run it as a Docker web app, use one-off CLI commands, or automate with APIs while keeping private and public material under your own policy.</p>
</article>
</div>
</section>
<section id="use-cases" class="section">
<div class="section-heading">
<p class="eyebrow">Who it is for</p>
<h2>Archiving workflows for individuals, professionals, and institutions.</h2>
<h2>Powerful features for individuals, professionals, and institutions.</h2>
</div>
<div class="audience-grid">
<article class="audience-card">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M6 3h12v18l-6-4-6 4V3Z"/></svg></span>
<h3>Personal archivists and self-hosters</h3>
<p>Save bookmarks, browser history, RSS feeds, social media, form content, videos, podcasts, music, photos, and personal knowledge collections.</p>
<ul>
@@ -152,17 +174,21 @@
<li>Use the browser extension, CLI, Web UI, and scheduled imports together.</li>
<li>Export static HTML or browse the filesystem directly.</li>
</ul>
<figure class="card-shot phone-pair"><a href="https://archivebox.github.io/ios-archivebox/" aria-label="See the ArchiveBox iPhone app and Safari extension"><img src="https://archivebox.github.io/ios-archivebox/docs/screenshots/share-iphone.png" width="1500" height="3000" loading="lazy" alt="iPhone share sheet confirming a URL was saved with tags"><img src="https://archivebox.github.io/ios-archivebox/docs/screenshots/extension-iphone.png?v=2" width="1500" height="3000" loading="lazy" alt="ArchiveBox’s Safari extension inside an iPhone frame"></a></figure>
</article>
<article class="audience-card">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 3v18M5 21h14M3 7h18M6 7l-4 8h8L6 7Zm12 0-4 8h8l-4-8Z"/></svg></span>
<h3>Lawyers and journalists</h3>
<p>Capture web pages, articles, source material, and public records while preserving reviewable copies outside of volatile platforms.</p>
<p>Keep copies of articles, source material, and public records, even after the original pages change or disappear.</p>
<ul>
<li>Store screenshots, PDFs, headers, WARC files, and text extraction.</li>
<li>Tag and review sources through the self-hosted web interface.</li>
<li>Tune privacy, authentication, and publishing settings for casework.</li>
<li>Use ZK proofs with <a href="https://tlsnotary.zervice.io/">TLSNotary</a> to prove content authenticity.</li>
</ul>
<figure class="card-shot"><a href="https://archivebox.io/screenshots/58-snapshot-view-tlsnotary-desktop.png"><img src="https://archivebox.io/screenshots/58-snapshot-view-tlsnotary-desktop.png" width="1600" height="1000" loading="lazy" alt="TLSNotary output verifying an archived response on the snapshot details page"></a></figure>
</article>
<article class="audience-card">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 5v16M12 5C9 2 5 2 2 3v16c3-1 7-1 10 2 3-3 7-3 10-2V3c-3-1-7-1-10 2Z"/></svg></span>
<h3>Researchers and institutions</h3>
<p>Support OSINT, social media research, AI-powered research agents, libraries, governments, and collection-building teams.</p>
<ul>
@@ -170,75 +196,171 @@
<li>Keep machine-readable metadata in JSON and SQLite.</li>
<li>Extend extraction pipelines through the ArchiveBox ecosystem.</li>
</ul>
<figure class="card-shot card-shot--crawl-options"><a href="https://archivebox.io/screenshots/05-add-urls-tablet.png"><img src="https://archivebox.io/screenshots/05-add-urls-tablet.png" width="1024" height="1366" loading="lazy" alt="Archive depth, domain and subpath scope, URL allowlist, and URL denylist options on the Add page"></a></figure>
</article>
</div>
</section>
<section id="install" class="section install-section">
<div class="install-copy">
<p class="eyebrow">Recommended install</p>
<h2>Start with Docker Compose.</h2>
<p>Docker Compose is the recommended ArchiveBox setup for the easiest install and update path, better isolation, and bundled archiving dependencies like Chrome, wget, yt-dlp, SingleFile, and readability tools.</p>
<div class="mini-links">
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Install#option-a-docker--docker-compose-setup-%EF%B8%8F">Docker install guide</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Docker">Docker usage wiki</a>
<a href="https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/dev/docker-compose.yml">docker-compose.yml</a>
<section id="install" class="section install-section" aria-labelledby="install-title">
<div class="section-heading"><p class="eyebrow">Get ArchiveBox</p><h2 id="install-title">Quickstart</h2><p>Choose how you want to run your archive. Docker Compose is recommended for most installs.</p></div>
<div class="install-window">
<div class="install-window-bar">
<div class="install-window-controls" aria-hidden="true"><span></span><span></span><span></span></div>
<span class="install-window-title">ArchiveBox — Quickstart</span>
</div>
<div class="install-tabs" aria-label="Installation methods">
<a class="install-tab" id="install-tab-macos" href="#install-macos"><img src="https://archivebox.github.io/ios-archivebox/docs/icons/apple.svg" width="28" height="28" alt=""><span>macOS app</span></a>
<a class="install-tab" id="install-tab-electron" href="#install-electron"><img src="./assets/install/archivebox-server.png" width="28" height="28" alt=""><span>Windows/Linux app</span></a>
<a class="install-tab" data-group-start id="install-tab-compose" href="#install-compose"><img src="https://user-images.githubusercontent.com/511499/117447182-29758200-af0b-11eb-97bd-58723fee62ab.png" width="28" height="28" alt=""><span>Docker Compose</span></a>
<a class="install-tab" id="install-tab-docker" href="#install-docker"><img src="https://user-images.githubusercontent.com/511499/117447182-29758200-af0b-11eb-97bd-58723fee62ab.png" width="28" height="28" alt=""><span>Docker</span></a>
<a class="install-tab" data-group-start id="install-tab-uv" href="#install-uv"><img src="https://user-images.githubusercontent.com/511499/117447613-ba4c5d80-af0b-11eb-8f89-1d98e31b6a79.png" width="28" height="28" alt=""><span>pip / uv</span></a>
<a class="install-tab" id="install-tab-apt" href="#install-apt"><img src="https://user-images.githubusercontent.com/511499/117448075-49597580-af0c-11eb-91ba-f34fff10096b.png" width="28" height="28" alt=""><span>apt</span></a>
<a class="install-tab" id="install-tab-brew" href="#install-brew"><img src="https://user-images.githubusercontent.com/511499/117447803-f2ec3700-af0b-11eb-87d3-671d114f011d.png" width="28" height="28" alt=""><span>Homebrew</span></a>
<a class="install-tab" id="install-tab-community" href="#install-community"><img src="https://user-images.githubusercontent.com/511499/118077361-f0616580-b381-11eb-973c-ee894a3349fb.png" width="28" height="28" alt=""><span>Other packages</span></a>
<a class="install-tab" data-group-start id="install-tab-script" href="#install-script"><img src="https://user-images.githubusercontent.com/511499/117456282-08665e80-af16-11eb-91a1-8102eff54091.png" width="28" height="28" alt=""><span>curl | sh</span></a>
<a class="install-tab" id="install-tab-platforms" href="#install-platforms"><img src="https://github.com/ArchiveBox/ArchiveBox/assets/511499/0c46e949-00fe-49c8-a613-ee14501c014c" width="28" height="28" alt=""><span>Self-hosting</span></a>
<a class="install-tab" id="install-tab-hosting" href="#install-hosting"><img src="https://user-images.githubusercontent.com/511499/117448723-1663b180-af0d-11eb-837f-d43959227810.png" width="28" height="28" alt=""><span>Cloud hosting</span></a>
<a class="install-tab" data-group-start id="install-tab-extension" href="#install-extension"><img src="./assets/install/browser-extension.png" width="28" height="28" alt=""><span>Browser Extension</span></a>
</div>
<div class="install-panel" id="install-compose" aria-labelledby="install-tab-compose">
<figure class="install-art install-art--container"><div class="install-art-stage"><div class="install-art-route"><div class="install-art-tile"><img src="./assets/install/docker-desktop.png" alt="" class="" loading="lazy"><span>Docker Compose</span></div><span class="install-art-arrow" aria-hidden="true">+</span><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div><a class="install-art-shot" href="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" aria-label="Enlarge ArchiveBox web interface"><img src="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" alt="ArchiveBox web interface" class="" loading="lazy"></a><span class="install-art-file">docker-compose.yml</span></div><figcaption>Recommended</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Create a directory and get the config</h4><p><a href="https://docs.docker.com/get-docker/">Install Docker</a> first.</p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>mkdir -p ~/archivebox/data &amp;&amp; cd ~/archivebox
curl -fsSL &#x27;https://docker-compose.archivebox.io&#x27; &gt; docker-compose.yml</code></pre></div></div></div></div>
<div class="step"><span>2</span><div><h4>Start ArchiveBox</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>docker compose pull
docker compose up -d --wait</code></pre></div></div><p>A new collection initializes automatically.</p></div></div>
<div class="step"><span>3</span><div><h4>Finish setup and archive your first page</h4><p>Open <a href="http://admin.archivebox.localhost:8000/admin/">the admin UI</a> to create your first admin account and finish the setup wizard. On a remote server, open <code>/admin/</code> on its hostname or IP instead.</p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>docker compose exec archivebox archivebox add &#x27;https://example.com&#x27;</code></pre></div></div></div></div>
</div>
</div>
<div class="command-card">
<div class="step">
<span>1</span>
<div>
<h3>Create a data directory</h3>
<div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><span class="ab-prompt">$</span> <span class="ab-cmd">mkdir -p ~/archivebox/data &amp;&amp; cd ~/archivebox</span></pre></div></div>
</div>
</div>
<div class="step">
<span>2</span>
<div>
<h3>Download Docker Compose config</h3>
<div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><span class="ab-prompt">$</span> <span class="ab-cmd">curl -fsSL 'https://docker-compose.archivebox.io' &gt; docker-compose.yml</span></pre></div></div>
</div>
</div>
<div class="step">
<span>3</span>
<div>
<h3>Start ArchiveBox (initializes automatically)</h3>
<div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><span class="ab-prompt">$</span> <span class="ab-cmd">docker compose up -d --wait</span></pre></div></div>
</div>
</div>
<div class="step">
<span>4</span>
<div>
<h3>Add your first URL</h3>
<div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><span class="ab-prompt">$</span> <span class="ab-cmd">docker compose exec archivebox archivebox add 'https://example.com'</span></pre></div></div>
</div>
<div class="install-panel" id="install-macos" aria-labelledby="install-tab-macos">
<figure class="install-art install-art--macos"><div class="install-art-stage"><div class="install-drag-card"><a class="install-art-tile" href="https://github.com/ArchiveBox/ios-archivebox/releases/latest/download/ArchiveBox.app.zip" style="color: inherit" aria-label="Download ArchiveBox.app for macOS"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox.app</span></a><span class="install-art-arrow" aria-hidden="true">→</span><div class="install-art-tile"><img src="./assets/install/applications-folder.png" alt="" class="" loading="lazy"><span>Applications</span></div></div><a class="install-art-shot" href="https://archivebox.github.io/ios-archivebox/docs/screenshots/server-mac.png" aria-label="Enlarge ArchiveBox Server on macOS"><img src="https://archivebox.github.io/ios-archivebox/docs/screenshots/server-mac.png" alt="ArchiveBox Server on macOS" class="" loading="lazy"></a></div><figcaption>macOS 26+ · Apple Silicon</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Download and open the app</h4><a class="button primary install-download" href="https://github.com/ArchiveBox/ios-archivebox/releases/latest/download/ArchiveBox.app.zip"><svg width="30" height="40" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 7.3.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2026 Fonticons, Inc. --><path fill="currentColor" d="M319.1 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7-55.8 .9-115.1 44.5-115.1 133.2 0 26.2 4.8 53.3 14.4 81.2 12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zM262.5 104.5c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg><span>Download ArchiveBox.app</span><svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12m-5-5 5 5 5-5M5 16v4h14v-4"/></svg></a><p>Move it to Applications, and open it.</p></div></div>
<div class="step"><span>2</span><div><h4>Follow the setup guide</h4><p>The app’s setup wizard helps you start a server on your Mac or connect to an existing one.</p></div></div>
<div class="step"><span>3</span><div><h4>Connect your apps</h4><p>Use the <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#ui-usage">Web UI</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Authentication#rest-api">REST API</a>, or <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#cli-usage">CLI</a>. Connect the <a href="https://archivebox.github.io/ios-archivebox/">mobile app</a>, <a href="https://archivebox.github.io/archivebox-browser-extension/">browser extension</a>, and other clients using your server URL and API key.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-docker" aria-labelledby="install-tab-docker">
<figure class="install-art install-art--container"><div class="install-art-stage"><div class="install-art-route"><div class="install-art-tile"><img src="./assets/install/docker-desktop.png" alt="" class="" loading="lazy"><span>Docker</span></div><span class="install-art-arrow" aria-hidden="true">+</span><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div><a class="install-art-shot" href="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" aria-label="Enlarge ArchiveBox web interface"><img src="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" alt="ArchiveBox web interface" class="" loading="lazy"></a></div><figcaption>One container. Your archive.</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Create a collection and start the server</h4><p><a href="https://docs.docker.com/get-docker/">Install Docker</a> first.</p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>mkdir -p ~/archivebox/data &amp;&amp; cd ~/archivebox/data
docker run -d --name archivebox -v &quot;$PWD:/data&quot; -p 8000:8000 archivebox/archivebox:dev</code></pre></div></div></div></div>
<div class="step"><span>2</span><div><h4>Finish setup</h4><p>Open <a href="http://admin.archivebox.localhost:8000/admin/">the admin UI</a> to create your first admin account and finish the setup wizard. On a remote server, open <code>/admin/</code> on its hostname or IP instead.</p></div></div>
<div class="step"><span>3</span><div><h4>Archive your first page</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>docker exec archivebox archivebox add &#x27;https://example.com&#x27;</code></pre></div></div></div></div>
</div>
</div>
<div class="install-panel" id="install-script" aria-labelledby="install-tab-script">
<figure class="install-art install-art--script"><div class="install-art-stage"><div class="install-script-card"><span class="install-script-prompt">$</span><code>curl <span>get.archivebox.io</span><br> | sh</code><div class="install-script-progress" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i></div></div><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div><figcaption>One command to get started</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Run the setup script</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>curl -fsSL &#x27;https://get.archivebox.io&#x27; | bash</code></pre></div></div><p>You can <a href="https://github.com/ArchiveBox/ArchiveBox/blob/dev/bin/setup.sh">read the script</a> before running it.</p></div></div>
<div class="step"><span>2</span><div><h4>Follow the prompts and finish setup</h4><p>Follow the installer’s instructions to start using your collection.</p><p>Open <a href="http://admin.archivebox.localhost:8000/admin/">the admin UI</a> to create your first admin account and finish the setup wizard. On a remote server, open <code>/admin/</code> on its hostname or IP instead.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-uv" aria-labelledby="install-tab-uv">
<figure class="install-art install-art--package"><div class="install-art-stage"><div class="install-package-card"><div class="install-art-tile"><img src="https://user-images.githubusercontent.com/511499/117447613-ba4c5d80-af0b-11eb-8f89-1d98e31b6a79.png" alt="" class="" loading="lazy"><span>pip / uv</span></div><span class="install-package-line" aria-hidden="true"></span><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div><div class="install-art-chips"><span>HTML</span><span>PDF</span><span>PNG</span><span>WARC</span></div></div><figcaption>Python package</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Install the Python package</h4><p><a href="https://docs.astral.sh/uv/getting-started/installation/">Install uv</a> first.</p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>uv tool install --python 3.13 --prerelease explicit --upgrade &#x27;archivebox&gt;=0.9.0rc0,&lt;0.10&#x27;
archivebox version</code></pre></div></div></div></div>
<div class="step"><span>2</span><div><h4>Create a collection and start the server</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>mkdir -p ~/archivebox/data &amp;&amp; cd ~/archivebox/data
archivebox init
archivebox install
archivebox server 0.0.0.0:8000</code></pre></div></div></div></div>
<div class="step"><span>3</span><div><h4>Finish setup</h4><p>Open <a href="http://admin.archivebox.localhost:8000/admin/">the admin UI</a> to create your first admin account and finish the setup wizard. On a remote server, open <code>/admin/</code> on its hostname or IP instead.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-apt" aria-labelledby="install-tab-apt">
<figure class="install-art install-art--package"><div class="install-art-stage"><div class="install-package-card"><div class="install-art-tile"><img src="https://user-images.githubusercontent.com/511499/117448075-49597580-af0c-11eb-91ba-f34fff10096b.png" alt="" class="" loading="lazy"><span>apt</span></div><span class="install-package-line" aria-hidden="true"></span><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div><div class="install-art-chips"><span>HTML</span><span>PDF</span><span>PNG</span><span>WARC</span></div></div><figcaption>Ubuntu / Debian</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Add the repository and install</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>echo &#x27;deb [trusted=yes] https://archivebox.github.io/debian-archivebox dev main&#x27; | sudo tee /etc/apt/sources.list.d/archivebox.list
sudo apt update
sudo apt install archivebox
(cd /tmp &amp;&amp; archivebox version)</code></pre></div></div></div></div>
<div class="step"><span>2</span><div><h4>Create a collection and start the server</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>mkdir -p ~/archivebox/data &amp;&amp; cd ~/archivebox/data
archivebox init
sudo archivebox install
archivebox server 0.0.0.0:8000</code></pre></div></div></div></div>
<div class="step"><span>3</span><div><h4>Finish setup</h4><p>Open <a href="http://admin.archivebox.localhost:8000/admin/">the admin UI</a> to create your first admin account and finish the setup wizard. On a remote server, open <code>/admin/</code> on its hostname or IP instead.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-brew" aria-labelledby="install-tab-brew">
<figure class="install-art install-art--package"><div class="install-art-stage"><div class="install-package-card"><div class="install-art-tile"><img src="https://user-images.githubusercontent.com/511499/117447803-f2ec3700-af0b-11eb-87d3-671d114f011d.png" alt="" class="" loading="lazy"><span>Homebrew</span></div><span class="install-package-line" aria-hidden="true"></span><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div><div class="install-art-chips"><span>HTML</span><span>PDF</span><span>PNG</span><span>WARC</span></div></div><figcaption>macOS / Linux</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Install from the ArchiveBox tap</h4><p><a href="https://brew.sh/#install">Install Homebrew</a> first. Run these commands as your normal user, without sudo.</p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>brew tap archivebox/archivebox
brew trust archivebox/archivebox
brew install archivebox
archivebox version</code></pre></div></div></div></div>
<div class="step"><span>2</span><div><h4>Create a collection and start the server</h4><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>mkdir -p ~/archivebox/data &amp;&amp; cd ~/archivebox/data
archivebox init
archivebox install
archivebox server 0.0.0.0:8000</code></pre></div></div></div></div>
<div class="step"><span>3</span><div><h4>Finish setup</h4><p>Open <a href="http://admin.archivebox.localhost:8000/admin/">the admin UI</a> to create your first admin account and finish the setup wizard. On a remote server, open <code>/admin/</code> on its hostname or IP instead.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-community" aria-labelledby="install-tab-community">
<figure class="install-art install-art--community"><div class="install-art-stage"><div class="install-art-platforms"><div class="install-art-tile"><img src="https://user-images.githubusercontent.com/511499/118077361-f0616580-b381-11eb-973c-ee894a3349fb.png" alt="" class="" loading="lazy"><span>Arch Linux</span></div><div class="install-art-tile"><img src="https://user-images.githubusercontent.com/511499/118077946-29e6a080-b383-11eb-94f0-d4871da08c3f.png" alt="" class="" loading="lazy"><span>FreeBSD</span></div><div class="install-art-tile"><img src="https://user-images.githubusercontent.com/511499/118077861-002d7980-b383-11eb-86a7-5936fad9190f.png" alt="" class="" loading="lazy"><span>Nix</span></div><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div></div></div><figcaption>Community packages</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Choose your platform</h4><p>Community packages may lag behind the Docker and Python releases.</p><p><a href="https://aur.archlinux.org/packages/archivebox/">Arch Linux (AUR)</a></p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>yay -S archivebox</code></pre></div></div><p>FreeBSD (uv shortcut)</p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>curl -fsSL &#x27;https://get.archivebox.io&#x27; | bash</code></pre></div></div><p><a href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/archivebox/default.nix">Nix</a></p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>nix-env --install archivebox</code></pre></div></div><p><a href="https://packages.guix.gnu.org/packages/archivebox/">Guix</a></p><div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><code>guix install archivebox</code></pre></div></div></div></div>
<div class="step"><span>2</span><div><h4>Set up your collection</h4><p>Follow your package’s setup instructions, then use the <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#cli-usage">CLI usage guide</a> to initialize and manage your archive.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-electron" aria-labelledby="install-tab-electron">
<figure class="install-art install-art--desktop"><div class="install-art-stage"><div class="install-desktop-base"><div class="install-art-tile"><img src="./assets/install/docker-desktop.png" alt="" class="" loading="lazy"><span>Docker Desktop</span></div></div><a class="install-desktop-shot" href="https://github.com/ArchiveBox/ArchiveBox/assets/511499/575ef92f-bb3e-4a7c-a4ba-986c1fd76ecf"><img src="https://github.com/ArchiveBox/ArchiveBox/assets/511499/575ef92f-bb3e-4a7c-a4ba-986c1fd76ecf" alt="ArchiveBox desktop app running, with its menu and Add URLs window" class="" loading="lazy"></a></div><figcaption>Windows / Linux · Desktop app preview</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Install Docker Desktop</h4><p><a href="https://www.docker.com/products/docker-desktop/">Download Docker Desktop</a> and start it on your computer.</p></div></div>
<div class="step"><span>2</span><div><h4>Download or build the app</h4><p>Follow the <a href="https://github.com/ArchiveBox/electron-archivebox#quickstart">Windows / Linux app setup instructions</a>.</p><p>This is an alpha project; contributors are welcome.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-platforms" aria-labelledby="install-tab-platforms">
<figure class="install-art install-art--server"><div class="install-art-stage"><svg class="install-server-rack" viewBox="0 0 160 180" aria-hidden="true"><rect x="18" y="12" width="124" height="156" rx="12"/><rect x="32" y="28" width="96" height="34" rx="5"/><rect x="32" y="73" width="96" height="34" rx="5"/><rect x="32" y="118" width="96" height="34" rx="5"/><path d="M47 45h43m-43 45h43m-43 45h43"/><circle cx="111" cy="45" r="4"/><circle cx="111" cy="90" r="4"/><circle cx="111" cy="135" r="4"/></svg><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div><div class="install-art-chips"><span>NAS</span><span>Home server</span></div></div><figcaption>On your own hardware</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Choose your platform</h4><p>Community integrations may lag behind the Docker and Python releases.</p><div class="mini-links"><a href="https://unraid.net/community/apps?q=archivebox#r">Unraid</a><a href="https://community-scripts.github.io/ProxmoxVE/scripts?id=archivebox">Proxmox</a><a href="https://github.com/YunoHost-Apps/archivebox_ynh">YunoHost</a><a href="https://www.cloudron.io/store/io.archivebox.cloudronapp.html">Cloudron</a><a href="https://docs.saltbox.dev/sandbox/apps/archivebox/">Saltbox</a><a href="https://portainer-templates.as93.net/archivebox">Portainer</a><a href="https://runtipi.io/docs/apps-available">Runtipi</a></div></div></div>
<div class="step"><span>2</span><div><h4>Install and open ArchiveBox</h4><p>Follow the platform’s installation guide, configure persistent storage, then open the app to finish setup.</p><p>For TrueNAS, see the <a href="https://github.com/ArchiveBox/ArchiveBox#quickstart">README’s platform notes</a> before choosing an integration.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-hosting" aria-labelledby="install-tab-hosting">
<figure class="install-art install-art--cloud"><div class="install-art-stage"><svg class="install-cloud" viewBox="0 0 240 160" aria-hidden="true"><path d="M62 125a40 40 0 0 1-5-80 62 62 0 0 1 117-5 43 43 0 0 1 9 85Z"/><path d="M120 128v26m-58 0h116"/></svg><div class="install-art-tile"><img src="./assets/install/archivebox-server.png" alt="" class="" loading="lazy"><span>ArchiveBox</span></div><div class="install-art-chips"><span>Your server</span><span>Anywhere</span></div></div><figcaption>Cloud hosting / VPS</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Choose a provider</h4><div class="mini-links"><a href="https://elest.io/open-source/archivebox">Elest.io</a><a href="https://www.stellarhosted.com/archivebox/">StellarHosted</a><a href="https://www.pikapods.com/pods?run=archivebox">PikaPods</a></div><p>Check the provider’s current plans, supported versions, and storage options.</p></div></div>
<div class="step"><span>2</span><div><h4>Deploy and finish setup</h4><p>Use the provider’s ArchiveBox deployment flow, then open your instance to create an admin account. For an unmanaged VPS, follow the Docker Compose quickstart on your server.</p></div></div>
</div>
</div>
<div class="install-panel" id="install-extension" aria-labelledby="install-tab-extension">
<figure class="install-art install-art--extension"><div class="install-art-stage"><a class="install-art-shot" href="https://archivebox.github.io/archivebox-browser-extension/screenshots/saved-urls-desktop.png" aria-label="Enlarge ArchiveBox browser extension saved URLs"><img src="https://archivebox.github.io/archivebox-browser-extension/screenshots/saved-urls-desktop.png" alt="ArchiveBox browser extension saved URLs" class="" loading="lazy"></a><div class="install-art-route"><div class="install-art-tile"><img src="./assets/install/browser-extension.png" alt="" class="" loading="lazy"><span>Save from your browser</span></div></div></div><figcaption>Chrome · Firefox · Edge · Safari</figcaption></figure>
<div class="command-card">
<div class="step"><span>1</span><div><h4>Install the browser extension</h4><div class="mini-links"><a href="https://chrome.google.com/webstore/detail/habonpimjphpdnmcfkaockjnffodikoj">Chrome / Brave</a><a href="https://addons.mozilla.org/firefox/addon/archivebox-exporter/">Firefox</a><a href="https://microsoftedge.microsoft.com/addons/detail/archivebox/dmlljpjhnfjgchbkcgheebcffocgooeh">Edge</a><a href="https://archivebox.github.io/ios-archivebox/">Safari / iOS</a></div></div></div>
<div class="step"><span>2</span><div><h4>Connect your ArchiveBox server</h4><p>Open the extension’s Configuration page, enter your server URL and API key, then test the connection. Use one of the server install tabs if you don’t have a server yet.</p></div></div>
<div class="step"><span>3</span><div><h4>Save a page</h4><p>Open a page, click the ArchiveBox extension, and add your tags. You can also import bookmarks and history from the extension’s options.</p><p><a href="https://archivebox.github.io/archivebox-browser-extension/">Extension guide ↗</a></p></div></div>
</div>
</div>
</section>
<section class="section compact-docs" aria-labelledby="other-installs-title">
<h2 id="other-installs-title">Other install paths</h2>
<p>ArchiveBox can also run with plain Docker, pip, brew, deb packages, or the optional setup script. Docker Compose remains the default recommendation, especially when you want bundled dependencies and clean upgrades.</p>
<div class="doc-link-grid">
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Install">Bare metal install</a>
<a href="https://github.com/ArchiveBox/ArchiveBox#quickstart">README quickstart</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#cli-usage">CLI usage</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration">Configuration</a>
</div>
</section>
<section id="configuration" class="section deep-section">
<div class="section-heading">
<p class="eyebrow">Configuration</p>
<h2>Configure ArchiveBox with powerful options.</h2>
<p>ArchiveBox can be configured with environment variables, the <code>archivebox config</code> CLI, or by editing <code>./ArchiveBox.conf</code>. The same configuration model works in Docker, Docker Compose, bare-metal installs, scheduled jobs, and one-off CLI runs.</p>
<div class="section-heading configuration-heading">
<div>
<p class="eyebrow">Configuration</p>
<h2>50+ plugins &amp; flexible configuration options.</h2>
<p><a href="https://abx-plugins.archivebox.io/"><strong>Browse plugins and extractors ↗</strong></a></p>
</div>
<ul class="plugin-stack" aria-label="Featured plugins">
<li><a href="https://abx-plugins.archivebox.io/#chrome" aria-label="Chrome plugin" title="Chrome"><img src="./assets/plugins/chrome.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#ublock" aria-label="uBlock Origin plugin" title="uBlock Origin"><img src="./assets/plugins/ublock.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#git" aria-label="GitHub / Git plugin" title="GitHub / Git"><img src="./assets/plugins/github.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#archivedotorg" aria-label="Internet Archive plugin" title="Internet Archive"><img src="./assets/plugins/archive-org.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#claudecode" aria-label="Claude / Anthropic plugin" title="Claude / Anthropic"><img src="./assets/plugins/claude.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#archivewebpage" aria-label="Webrecorder plugin" title="Webrecorder"><img src="./assets/plugins/webrecorder.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#singlefile" aria-label="SingleFile plugin" title="SingleFile"><img src="./assets/plugins/singlefile.png" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://abx-plugins.archivebox.io/#ytdlp" aria-label="YouTube / yt-dlp plugin" title="YouTube / yt-dlp"><img src="./assets/plugins/youtube.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://tailscale.com/" aria-label="Tailscale" title="Tailscale"><img src="./assets/plugins/tailscale.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://tlsnotary.zervice.io/" aria-label="TLSNotary" title="TLSNotary"><img src="./assets/plugins/tlsnotary.svg" width="44" height="44" loading="lazy" alt=""></a></li>
</ul>
<p class="configuration-description">ArchiveBox can be configured via the admin UI, CLI, <code>ArchiveBox.conf</code>, or by importing config and cookies from Chrome / other browsers. The same configuration model works in Docker, Docker Compose, bare-metal installs, scheduled jobs, and one-off CLI runs.</p>
</div>
<div class="prose-grid">
<article>
<h3>Common settings people search for</h3>
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M4 3v7m0 4v7M12 3v11m0 4v3M20 3v3m0 4v11M1 10h6m2 8h6m2-12h6"/></svg></span>
<h3>Adjust how pages are captured</h3>
<p>Use <code>TIMEOUT</code> for slow networks, <code>CHECK_SSL_VALIDITY</code> for sites with broken certificates, <code>PUBLIC_INDEX</code>, <code>PUBLIC_SNAPSHOTS</code>, and <code>PUBLIC_ADD_VIEW</code> for publishing policy, and browser user-agent settings for sites that block obvious bots.</p>
<p>For authenticated or difficult sites, review <code>CHROME_USER_DATA_DIR</code>, <code>COOKIES_FILE</code>, <code>CHROME_USER_AGENT</code>, <code>WGET_USER_AGENT</code>, and <code>CURL_USER_AGENT</code>. Public archive operators should also configure instance branding and contact details with settings like <code>FOOTER_INFO</code> and <code>CUSTOM_TEMPLATES_DIR</code>.</p>
<div class="ab-terminal">
<div class="ab-terminal__bar">
<div class="ab-terminal__dots"><span class="ab-terminal__dot" aria-hidden="true">&nbsp;</span><span class="ab-terminal__dot" aria-hidden="true">&nbsp;</span><span class="ab-terminal__dot" aria-hidden="true">&nbsp;</span></div>
@@ -254,6 +376,7 @@
</div>
</article>
<article>
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M8 3v5m8-5v5M6 8h12v4a6 6 0 0 1-12 0V8Zm6 10v4"/></svg></span>
<h3>Dependencies and extractors</h3>
<p>ArchiveBox uses standard tools like Chrome or Chromium, wget, curl, yt-dlp, git, SingleFile, Readability, and article parsers. Docker bundles these dependencies for easier upgrades and better isolation; non-Docker installs can run <code>archivebox install</code> and <code>archivebox --version</code> to check what is available.</p>
<ul class="readme-list">
@@ -269,22 +392,45 @@
</section>
<section class="section data-section">
<div class="section-heading">
<p class="eyebrow">Inputs and outputs</p>
<h2>Feed it URLs from any source. Save redundant, portable captures.</h2>
<div class="section-heading integration-heading">
<div>
<p class="eyebrow">Inputs and outputs</p>
<h2>Integrate with tools you already use.</h2>
</div>
<ul class="plugin-stack integration-stack" aria-label="Tools and integrations">
<li><a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#rclone" aria-label="Google Drive" title="Google Drive"><img src="./assets/integrations/google-drive.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://n8n.io/" aria-label="n8n" title="n8n"><img src="./assets/integrations/n8n.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://openai.com/codex/" aria-label="Codex" title="Codex"><img src="./assets/integrations/codex.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://claude.com/product/claude-code" aria-label="Claude Code" title="Claude Code"><img src="./assets/integrations/claude-code.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://slack.com/" aria-label="Slack" title="Slack"><img src="./assets/integrations/slack.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#rclone" aria-label="AWS S3" title="AWS S3"><img src="./assets/integrations/aws-s3-wordmark.svg" width="44" height="44" loading="lazy" alt=""></a></li>
<li><a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ldap_enabled" aria-label="LDAP" title="LDAP"><img src="./assets/integrations/ldap.png" width="44" height="44" loading="lazy" alt=""></a></li>
</ul>
</div>
<div class="data-grid">
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 3v12m-5-5 5 5 5-5M4 16v5h16v-5"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/05-add-urls-desktop.png"><img src="https://archivebox.io/screenshots/05-add-urls-desktop.png" width="1600" height="1000" loading="lazy" alt="Add URLs to ArchiveBox"></a>
</div>
<h3>Inputs</h3>
<p>Archive one URL at a time or schedule imports from bookmarks, browser history, RSS, JSON, CSV, TXT, SQL, HTML, Markdown, Pocket, Pinboard, Instapaper, Shaarli, Wallabag, and more.</p>
<p>Archive <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-single-url">one URL at a time</a> or <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Scheduled-Archiving">schedule imports</a> from <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart#2-get-your-list-of-urls-to-archive">bookmarks</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-list-of-links-from-browser-history">browser history</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">RSS</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">JSON</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">CSV</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">TXT</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">SQL</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">HTML</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#import-a-list-of-urls-from-a-text-file">Markdown</a>, <a href="https://support.mozilla.org/en-US/kb/exporting-your-pocket-list">Pocket</a>, <a href="https://pinboard.in/export/">Pinboard</a>, <a href="https://www.instapaper.com/user">Instapaper</a>, <a href="https://github.com/shaarli/Shaarli/blob/master/doc/md/Usage.md#importexport">Shaarli</a>, <a href="https://doc.wallabag.org/user/import/wallabagv2/">Wallabag</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart#2-get-your-list-of-urls-to-archive">and more</a>.</p>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M14 2H5v20h14V7l-5-5Zm0 0v5h5M8 12h8m-8 4h6"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/11-snapshot-files-desktop.png"><img src="https://archivebox.io/screenshots/11-snapshot-files-desktop.png" width="1600" height="1000" loading="lazy" alt="Files saved for an archived page"></a>
</div>
<h3>Outputs</h3>
<p>Each snapshot can include original HTML, rendered single-file HTML, PDF, screenshot PNG, WARC, title, article text, favicon, headers, media, subtitles, metadata, thumbnails, and git clones.</p>
<p>Each snapshot can include <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#wget_enabled">original HTML</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#singlefile_enabled">rendered single-file HTML</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#pdf_enabled">PDF</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#screenshot_enabled">screenshot PNG</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#wget_enabled">WARC</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#title_enabled">title</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#readability_enabled">article text</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#favicon_enabled">favicon</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#headers_enabled">headers</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ytdlp_enabled">media</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ytdlp_enabled">subtitles</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#disk-layout">metadata</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ytdlp_enabled">thumbnails</a>, and <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#git_enabled">git clones</a>.</p>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8m-4-4v4"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png"><img src="https://archivebox.io/screenshots/09-snapshots-grid-desktop.png" width="1600" height="1000" loading="lazy" alt="Browse an archive in the Web UI"></a>
</div>
<h3>Access</h3>
<p>Manage the same collection through the Web UI, CLI, REST API, Python API, SQLite, or the data folder itself. The tools are complementary, not separate products.</p>
<p>Manage the same collection through the <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#ui-usage">Web UI</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#cli-usage">CLI</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Authentication#rest-api">REST API</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#python-api-usage">Python API</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#sql-shell-usage">SQLite</a>, or the <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#disk-layout">data folder</a> itself. Use whichever fits your workflow.</p>
</article>
</div>
</section>
@@ -292,35 +438,21 @@
<section id="layout-security" class="section deep-section">
<div class="section-heading">
<p class="eyebrow">Disk layout, exporting, and security</p>
<h2>A normal folder, a SQLite index, and files you can inspect without ArchiveBox.</h2>
<p>All ArchiveBox state for a collection lives in one data folder: the SQLite database, configuration, logs, and archived content. Snapshots are organized on disk as ordinary files and folders so they can be backed up, searched, published carefully, or browsed by hand.</p>
<h2>Browse your captures as normal files without needing ArchiveBox.</h2>
<p>Your captures are ordinary HTML, images, PDFs, and media files. Open them from Finder, search them with any filesystem search tools, let AI agents browse them directly, and back them up as regular files.</p>
</div>
<div class="prose-grid prose-grid--wide">
<article>
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M3 7V5a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/><path d="M3 9h18"/></svg></span>
<h3>Archive layout</h3>
<div class="ab-terminal">
<div class="ab-terminal__bar">
<div class="ab-terminal__dots"><span class="ab-terminal__dot" aria-hidden="true">&nbsp;</span><span class="ab-terminal__dot" aria-hidden="true">&nbsp;</span><span class="ab-terminal__dot" aria-hidden="true">&nbsp;</span></div>
<span>~/archivebox/data</span>
</div>
<div class="ab-terminal__body">
<pre><span class="ab-out">data/</span>
<span class="ab-out"> index.sqlite3</span> <span class="ab-dim"># main metadata database</span>
<span class="ab-out"> ArchiveBox.conf</span> <span class="ab-dim"># collection configuration</span>
<span class="ab-out"> archive/</span>
<span class="ab-out"> 1617687755/</span>
<span class="ab-out"> index.html</span>
<span class="ab-out"> index.json</span>
<span class="ab-out"> screenshot.png</span>
<span class="ab-out"> output.pdf</span>
<span class="ab-out"> warc/1617687755.warc.gz</span>
<span class="ab-out"> media/some_video.mp4</span>
<span class="ab-out"> git/somerepo.git</span></pre>
</div>
</div>
<p>Each snapshot folder includes static <code>index.html</code> and <code>index.json</code> metadata plus extractor outputs such as HTML, PDFs, screenshots, WARC files, media, subtitles, headers, favicons, article text, and git repositories.</p>
<p>Each snapshot has a folder for every capture method. HTML lives in folders such as <code>dom/</code> and <code>singlefile/</code>; images, PDFs, and media have their own folders too.</p>
<p>Snapshot metadata is saved alongside the outputs. Your collection’s database and configuration live outside the individual snapshot folders.</p>
<figure class="finder-shot">
<a href="./assets/archive-files-finder.png"><img src="./assets/archive-files-finder.png" width="1044" height="492" loading="lazy" alt="macOS Finder with the date, news.ycombinator.com, and snapshot folders expanded down to dom/output.html, with the saved HTML file selected"></a>
</figure>
</article>
<article>
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M14 2H5v20h14V7l-5-5Zm0 0v5h5M8 12h8m-8 4h6"/></svg></span>
<h3>Static exports and publishing</h3>
<p>You can export the archive index as static HTML, JSON, or CSV with <code>archivebox list</code> so collections can be reviewed without running the web server. Keep generated exports next to the <code>archive/</code> folder so relative snapshot paths continue to work.</p>
<div class="ab-terminal ab-terminal--inline"><div class="ab-terminal__body"><pre><span class="ab-prompt">$</span> <span class="ab-cmd">archivebox list --html --with-headers &gt; index.html</span>
@@ -337,79 +469,52 @@
<div class="notice-grid">
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="4" y="10" width="16" height="12" rx="2"/><path d="M8 10V6a4 4 0 0 1 8 0v4m-4 5v3"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/02-login-desktop.png"><img src="https://archivebox.io/screenshots/02-login-desktop.png" width="1600" height="1000" loading="lazy" alt="ArchiveBox sign-in page"></a>
</div>
<h3>Private content</h3>
<p>If you archive private URLs, paywalled pages, unlisted media, Google Docs, or browser sessions, assume snapshot viewers may see private URLs, cookies, session tokens, headers, and page content unless you configure access carefully.</p>
<p>Restrict public access with <code>PUBLIC_INDEX=False</code>, <code>PUBLIC_SNAPSHOTS=False</code>, and <code>PUBLIC_ADD_VIEW=False</code>, then create authenticated users with <code>archivebox manage createsuperuser</code>.</p>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview">Read the security overview</a>
<p>Archive private URLs, paywalled pages, unlisted media, and Google Docs using an <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Chromium-Install#setting-up-a-chromium-user-profile">imported Chrome profile</a> or a <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Chromium-Install#non-docker-setup-local-host">dedicated browser persona</a>. Choose which captures stay private and who can access them.</p>
<p>Restrict public access with <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_index"><code>PUBLIC_INDEX=False</code></a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#permissions"><code>PERMISSIONS=private</code></a>, and <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#public_add_view"><code>PUBLIC_ADD_VIEW=False</code></a>, then create authenticated users with <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Authentication#username--password-the-default"><code>archivebox manage createsuperuser</code></a>.</p>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview#publishing">Read the security overview</a>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="m7 5-6 7 6 7m10-14 6 7-6 7M14 3l-4 18"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/49-snapshot-view-dom-desktop.png"><img src="https://archivebox.io/screenshots/49-snapshot-view-dom-desktop.png" width="1600" height="1000" loading="lazy" alt="Archived page rendered from saved HTML"></a>
</div>
<h3>Archived JavaScript</h3>
<p>Archived pages that execute JavaScript can make requests from the same domain as the web UI when viewed. If this risk matters for your collection, review the publishing guidance and consider disabling extractor outputs that execute archived JS when opened.</p>
<p><code>archivebox config --set SAVE_WGET=False SAVE_DOM=False</code></p>
<a href="https://github.com/ArchiveBox/ArchiveBox/issues/239">Read Issue #239</a>
<p>ArchiveBox uses a <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Chromium-Install#chrome--chromium-setup">Chrome browser</a> during archiving to run JavaScript and capture the rendered page.</p>
<p><a href="https://archiveweb.page/guide">ArchiveWeb.page</a> records pages for replay, including their scripts and network responses. Replay captured pages with JavaScript using <a href="https://replayweb.page/docs/user-guide/">ReplayWeb.page</a>, Webrecorder’s archive viewer.</p>
</article>
<article>
<div class="card-media">
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 4 18 4 18 0V5M3 12c0 4 18 4 18 0"/></svg></span>
<a class="card-thumbnail" href="https://archivebox.io/screenshots/10-snapshot-admin-detail-desktop.png"><img src="https://archivebox.io/screenshots/10-snapshot-admin-detail-desktop.png" width="1600" height="1000" loading="lazy" alt="Snapshot details and saved archive size"></a>
</div>
<h3>Storage requirements</h3>
<p>ArchiveBox can use roughly 1 GB to 50 GB per 1,000 snapshots depending on media, video, audio, and extractor settings. Tune <code>YTDLP_ENABLED</code> and <code>YTDLP_MAX_SIZE</code> for media-heavy collections.</p>
<p>Keep <code>index.sqlite3</code> on local storage or SSD when possible. Large <code>archive/</code> folders can live on NFS, SMB, FUSE, S3-backed, or HDD storage, but Docker and fileshare setups may need ownership and root-squash adjustments. Avoid older filesystems like EXT3 or FAT for very large archives.</p>
<p>ArchiveBox can use roughly 1 GB to 50 GB per 1,000 snapshots depending on media, video, audio, and extractor settings. Tune <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ytdlp_enabled"><code>YTDLP_ENABLED</code></a> and <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration#ytdlp_max_size"><code>YTDLP_MAX_SIZE</code></a> for media-heavy collections.</p>
<p>Keep <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#supported-remote-filesystems"><code>index.sqlite3</code></a> on local storage or SSD when possible. Large <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#supported-remote-filesystems"><code>archive/</code></a> folders can live on <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#rclone">NFS</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#rclone">SMB</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#rclone">FUSE</a>, <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#rclone">S3-backed</a>, or <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#supported-local-filesystems">HDD storage</a>, but Docker and fileshare setups may need <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#nfs">ownership and root-squash adjustments</a>. Avoid older filesystems like <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-Up-Storage#ext2-ext3-fat32-exfat">EXT3 or FAT</a> for very large archives.</p>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#large-archives">Plan for large archives</a>
</article>
</div>
</section>
<section id="ecosystem" class="section ecosystem">
<div class="section-heading">
<p class="eyebrow">Ecosystem</p>
<h2>Core projects that make ArchiveBox extensible.</h2>
</div>
<div class="project-grid">
<article>
<h3>abx-plugins</h3>
<p>Extractor and plugin packages used to preserve more types of content.</p>
<div>
<a href="https://github.com/ArchiveBox/abx-plugins">GitHub</a>
<a href="https://archivebox.github.io/abx-plugins/">Docs</a>
</div>
</article>
<article>
<h3>abx-dl</h3>
<p>Download and extraction tooling for saving web content and media.</p>
<div>
<a href="https://github.com/ArchiveBox/abx-dl">GitHub</a>
</div>
</article>
<article>
<h3>abxpkg</h3>
<p>Runtime package management for dependencies used by ArchiveBox and plugins.</p>
<div>
<a href="https://github.com/ArchiveBox/abxpkg">GitHub</a>
<a href="https://archivebox.github.io/abxpkg/">Docs</a>
</div>
</article>
<article>
<h3>abxbus</h3>
<p>Event bus infrastructure for ArchiveBox automation and integrations.</p>
<div>
<a href="https://github.com/ArchiveBox/abxbus">GitHub</a>
<a href="https://abxbus.archivebox.io">Site</a>
</div>
</article>
</div>
</section>
<section id="background" class="section deep-section">
<div class="section-heading">
<p class="eyebrow">Background and motivation</p>
<h2>Built for decentralized preservation.</h2>
<h2>Keep a copy of the web you care about.</h2>
<p>ArchiveBox exists because link rot, platform churn, censorship, and disappearing media routinely erase useful knowledge. The project aims to make the web content you care about viewable with common software in 50 to 100 years, without requiring ArchiveBox or a hosted replay service to understand your files.</p>
</div>
<div class="prose-grid">
<article>
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="7" rx="2"/><rect x="3" y="14" width="18" height="7" rx="2"/><path d="M7 6.5h.01M7 17.5h.01M11 6.5h6M11 17.5h6"/></svg></span>
<h3>Why self-host?</h3>
<p>Centralized public archives are essential, but not every page belongs in a global public service. ArchiveBox lets individuals and organizations save public or private material they can access, keep it locally or within their institution, and decide what to publish case by case.</p>
<p>The project differentiates itself by combining a comprehensive CLI, a self-hosted web UI, API surfaces, scheduled imports, standard output formats, and a simple on-disk data layout that remains useful without the app running.</p>
<p>Use the Web UI for browsing, the CLI and API for automation, and ordinary files for backups and exports.</p>
</article>
<article>
<span class="card-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M12 3v18M5 21h14M3 7h18M6 7l-4 8h8L6 7Zm12 0-4 8h8l-4-8Z"/></svg></span>
<h3>Ethical and legal context</h3>
<p>Responsible archiving depends on your jurisdiction, your use case, and your publishing policy. ArchiveBox is a tool; operators remain responsible for handling private data, copyright, DMCA or GDPR requests, and local legal requirements.</p>
<p>Public instances should publish contact and removal information, avoid monetizing copied content, and review the security and publishing documentation before exposing snapshots to anonymous viewers.</p>
@@ -417,7 +522,7 @@
</div>
<div class="alternatives-band">
<h3>Related web archiving tools and communities</h3>
<p>ArchiveBox is a broad, self-hosted archive manager. For specialized crawling, replay, bookmark management, or research workflows, the wider web archiving ecosystem is worth knowing.</p>
<p>Looking for specialized crawling, replay, or bookmark management? Explore these other web archiving projects.</p>
<div class="doc-link-grid">
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Web-Archiving-Community#web-archiving-projects">Web archiving projects</a>
<a href="https://archiveweb.page">ArchiveWeb.page</a>
@@ -431,37 +536,12 @@
</div>
</section>
<section class="section docs-band">
<div>
<p class="eyebrow">Documentation</p>
<h2>Further Reading.</h2>
<p>The README and wiki cover supported sources, outputs, scheduled archiving, storage backends, authentication, security, publishing, Chrome setup, upgrades, troubleshooting, API usage, development, and the broader web archiving community.</p>
</div>
<div class="doc-link-grid">
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Quickstart">Quickstart</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Install">Install</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Docker">Docker</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Usage">Usage</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration">Configuration</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki#can-save-these-things-for-each-site">Supported outputs</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Scheduled-Archiving">Scheduled archiving</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Storage">Storage backends</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Setting-up-Authentication">Authentication</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview">Security overview</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Chromium-Install">Chromium setup</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting">Troubleshooting</a>
<a href="https://docs.archivebox.io">API docs</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/issues">Issue tracker</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Roadmap">Roadmap</a>
<a href="https://github.com/ArchiveBox/ArchiveBox/releases">Changelog</a>
</div>
</section>
</main>
<!-- BEGIN ARCHIVEBOX FOOTER — generated by monorepo/site-chrome/sync.py -->
<footer class="abx-footer" aria-label="ArchiveBox ecosystem">
<div class="abx-footer-intro"><div><a class="abx-brand" href="https://archivebox.io/"><svg class="abx-logo" viewBox="0 0 40 40" aria-hidden="true"><rect width="40" height="40" rx="10" fill="#9b2854"/><path d="M10 14h20v17H10z" fill="#fff4ed"/><path d="M8 9h24v6H8z" fill="#fff4ed"/><path d="M16 19h8v3h-8z" fill="#9b2854"/><path d="M12 31V17" stroke="#9b2854" stroke-width="2"/></svg><span>ArchiveBox</span></a><p class="abx-tagline">Open-source tools for keeping a lasting copy of the web.<br>Your data. Your devices. Your archive.</p></div><p class="abx-footer-motto">A home for the web<br>you want to keep.</p></div>
<div class="abx-footer-grid"><section class="abx-footer-column"><h2>Apps &amp; tools</h2><ul><li><a href="https://archivebox.io/">Self-hosted Web Archive</a><a class="abx-source" href="https://github.com/ArchiveBox/ArchiveBox" aria-label="Self-hosted Web Archive source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#get-started">iOS App for iPhone &amp; iPad</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="iOS App for iPhone &amp; iPad source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#your-server-your-choice">macOS App + Server App</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="macOS App + Server App source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/archivebox-browser-extension/">Browser Extensions</a><a class="abx-source" href="https://github.com/ArchiveBox/archivebox-browser-extension" aria-label="Browser Extensions source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-dl/">Command-line Downloader</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-dl" aria-label="Command-line Downloader source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-plugins/">Plugins &amp; Extractors</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-plugins" aria-label="Plugins &amp; Extractors source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 Line truncated
<div class="abx-footer-grid"><section class="abx-footer-column"><h2>Apps &amp; tools</h2><ul><li><a href="https://archivebox.io/">ArchiveBox Server</a><a class="abx-source" href="https://github.com/ArchiveBox/ArchiveBox" aria-label="ArchiveBox Server source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#get-started">ArchiveBox for macOS &amp; iOS</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="ArchiveBox for macOS &amp; iOS source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/archivebox-browser-extension/">ArchiveBox Browser Extension</a><a class="abx-source" href="https://github.com/ArchiveBox/archivebox-browser-extension" aria-label="ArchiveBox Browser Extension source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-plugins/">ArchiveBox Plugin Library</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-plugins" aria-label="ArchiveBox Plugin Library source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/abx-dl/">One-shot abx-dl CLI</a><a class="abx-source" href="https://github.com/ArchiveBox/abx-dl" aria-label="One-shot abx-dl CLI source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 12 .75Z"/></svg></a></li><li><a href="https://archivebox.github.io/ios-archivebox/#your-server-your-choice">ArchiveBox Server.app</a><a class="abx-source" href="https://github.com/ArchiveBox/ios-archivebox" aria-label="ArchiveBox Server.app source on GitHub" title="View source on GitHub"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 .75a11.25 11.25 0 0 0-3.56 21.92c.56.1.77-.24.77-.54v-2.1c-3.14.68-3.8-1.33-3.8-1.33-.51-1.3-1.25-1.65-1.25-1.65-1.02-.7.08-.69.08-.69 1.13.08 1.73 1.16 1.73 1.16 1 1.72 2.63 1.22 3.27.93.1-.73.39-1.22.71-1.5-2.5-.28-5.13-1.25-5.13-5.56 0-1.23.44-2.23 1.16-3.02-.12-.28-.5-1.43.11-2.98 0 0 .95-.3 3.1 1.15a10.8 10.8 0 0 1 5.64 0c2.15-1.46 3.1-1.15 3.1-1.15.62 1.55.23 2.7.12 2.98.72.79 1.16 1.8 1.16 3.02 0 4.32-2.64 5.27-5.15 5.55.4.35.76 1.03.76 2.08v3.11c0 .3.2.65.77.54A11.25 11.25 0 0 0 1Line truncated
<div class="abx-footer-local"><p>Open-source self-hosted web archiving. MIT licensed, nonprofit-supported, and built for durable collections.</p>
<div>
<a href="https://github.com/ArchiveBox/ArchiveBox/blob/dev/LICENSE">License</a>
+46
View File
@@ -0,0 +1,46 @@
(() => {
const tablist = document.querySelector('.install-tabs');
const tabs = Array.from(tablist.querySelectorAll('.install-tab'));
const panels = tabs.map(tab => document.querySelector(tab.getAttribute('href')));
function selectTab(index) {
tabs.forEach((tab, i) => {
tab.setAttribute('aria-selected', String(i === index));
tab.tabIndex = i === index ? 0 : -1;
panels[i].hidden = i !== index;
});
}
tablist.setAttribute('role', 'tablist');
tabs.forEach((tab, index) => {
tab.setAttribute('role', 'tab');
tab.setAttribute('aria-controls', panels[index].id);
panels[index].setAttribute('role', 'tabpanel');
panels[index].tabIndex = 0;
tab.addEventListener('click', event => {
event.preventDefault();
selectTab(index);
});
tab.addEventListener('keydown', event => {
let next;
if (event.key === 'ArrowRight') next = (index + 1) % tabs.length;
else if (event.key === 'ArrowLeft') next = (index - 1 + tabs.length) % tabs.length;
else if (event.key === 'Home') next = 0;
else if (event.key === 'End') next = tabs.length - 1;
else if (event.key === ' ') next = index;
else return;
event.preventDefault();
selectTab(next);
tabs[next].focus();
});
});
function selectHash() {
const index = panels.findIndex(panel => `#${panel.id}` === location.hash);
if (index !== -1) selectTab(index);
}
selectTab(0);
selectHash();
window.addEventListener('hashchange', selectHash);
})();
+1
View File
@@ -20,6 +20,7 @@
.abx-apps[open] > summary::before { transform: rotate(90deg); }
.abx-header .abx-app-links { position: absolute; right: 0; top: calc(100% + 12px); width: 305px; max-height: min(70vh, 580px); overflow-y: auto; padding: 10px; border: 1px solid #e9e2e3; border-radius: 14px; background: #fcfaf7; box-shadow: 0 16px 48px #2d152522; }
.abx-header .abx-app-links a { display: flex; min-height: 42px; padding: 9px 12px; border-radius: 7px; white-space: normal; }
.abx-header .abx-app-links code { display: inline; vertical-align: baseline; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 1em; font-weight: inherit; line-height: inherit; margin: 0 .3em; padding: 0; border: 0; background: transparent; color: inherit; }
.abx-header .abx-app-links a:hover { background: #f2e8ed; }
.abx-footer { position: relative; z-index: 1; display: block; width: 100%; max-width: none; margin: 72px 0 0; padding: 60px max(24px, calc((100% - 1280px) / 2)) 24px; border: 0; border-top: 3px solid #7e284a; background: radial-gradient(ellipse at 12% 0, #54243b55, transparent 48%), linear-gradient(120deg, #201923, #14151b 75%); color: #ddd2dd; color-scheme: dark; }
.abx-footer .abx-footer-intro { display: flex; align-items: flex-start; justify-content: space-between; gap: 32px; margin: 0 0 42px; }
+766 -15
View File
@@ -432,11 +432,184 @@ h3 {
.product-shot {
width: 100%;
height: auto;
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.device-showcase {
position: relative;
padding: 24px 58px 42px 0;
}
.device-desktop {
display: block;
transform: rotate(-2deg);
}
.device-phone {
position: absolute;
right: 16px;
bottom: 0;
width: 31%;
max-width: 170px;
transform: rotate(5deg);
filter: drop-shadow(0 12px 16px #21192126);
}
.device-phone img {
width: 100%;
height: auto;
}
.device-caption {
margin: 0;
color: var(--muted-text);
font-size: 0.9rem;
text-align: center;
}
.card-icon {
display: inline-flex;
width: 42px;
height: 42px;
align-items: center;
justify-content: center;
margin-bottom: 18px;
border: 1px solid hsl(var(--primary) / 0.14);
border-radius: 12px;
background: hsl(var(--primary) / 0.06);
color: var(--brand);
}
.card-icon svg {
width: 24px;
height: 24px;
fill: none;
stroke: currentColor;
stroke-width: 1.6;
stroke-linecap: round;
stroke-linejoin: round;
}
.features-section .section-heading {
max-width: 960px;
}
.features-section h2 em {
color: var(--brand);
}
.features-section .feature-grid {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.card-shot {
margin: 24px 0 0;
}
.card-shot > a {
display: block;
overflow: hidden;
border: 1px solid var(--line);
border-radius: 6px;
background: var(--soft);
}
.card-shot img {
width: 100%;
height: auto;
}
.card-media {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 18px;
}
.card-media .card-icon {
flex-shrink: 0;
margin: 0;
}
.card-thumbnail {
display: block;
width: 112px;
height: 70px;
overflow: hidden;
border: 1px solid var(--line);
border-radius: 6px;
background: var(--soft);
}
.card-thumbnail img {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.card-thumbnail:hover,
.card-thumbnail:focus-visible {
outline: 2px solid var(--brand);
outline-offset: 3px;
}
.audience-card .card-shot {
margin-top: auto;
padding-top: 24px;
}
.audience-card .card-shot > a {
height: 230px;
}
.audience-card .card-shot img {
height: 100%;
object-fit: cover;
object-position: top left;
}
.audience-card .card-shot--crawl-options > a {
display: flex;
justify-content: center;
}
.audience-card .card-shot--crawl-options img {
max-width: 340px;
object-position: center bottom;
}
.audience-card .phone-pair > a {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 8px;
background: linear-gradient(135deg, #f4e8ed, #edf1e8);
}
.audience-card .phone-pair img {
width: calc(50% - 4px);
object-fit: contain;
object-position: center;
}
.finder-shot {
max-width: 400px;
margin: 20px 0 0;
}
.finder-shot img {
width: 100%;
height: auto;
border-radius: 10px;
box-shadow: var(--shadow);
}
.trust-strip {
position: relative;
display: flex;
@@ -510,6 +683,109 @@ h3 {
margin-bottom: 34px;
}
.configuration-heading,
.integration-heading {
display: grid;
grid-template-columns: minmax(0, 1fr) 320px;
align-items: center;
gap: 20px 40px;
max-width: none;
}
.configuration-heading .configuration-description {
grid-column: 1 / -1;
max-width: 780px;
margin: 0;
}
.plugin-stack {
display: grid;
grid-template-columns: repeat(5, 54px);
justify-content: center;
gap: 12px 0;
margin: 0;
padding: 12px 20px 12px 0;
list-style: none;
}
.integration-stack {
grid-template-columns: repeat(4, 54px);
}
.integration-stack li:nth-child(n + 5) a {
left: 12px;
}
.plugin-stack li:nth-child(4n + 1) { --tilt: -10deg; }
.plugin-stack li:nth-child(4n + 2) { --tilt: 6deg; }
.plugin-stack li:nth-child(4n + 3) { --tilt: -5deg; }
.plugin-stack li:nth-child(4n) { --tilt: 10deg; }
.plugin-stack a {
position: relative;
display: grid;
width: 68px;
height: 68px;
place-items: center;
border: 1px solid var(--line);
border-radius: 20px;
background: #fff;
box-shadow: 0 7px 18px #21192114;
transform: rotate(var(--tilt));
}
.plugin-stack li:nth-child(n + 6) a {
left: 12px;
}
.plugin-stack a:hover,
.plugin-stack a:focus-visible {
z-index: 1;
outline: 2px solid var(--brand);
outline-offset: 3px;
transform: translateY(-4px);
}
.plugin-stack img {
width: 44px;
height: 44px;
object-fit: contain;
}
@media (max-width: 980px) {
.configuration-heading,
.integration-heading {
grid-template-columns: minmax(0, 1fr);
gap: 12px;
}
.plugin-stack {
grid-template-columns: repeat(10, 26px);
justify-content: start;
padding: 10px 0 16px;
}
.integration-stack {
grid-template-columns: repeat(7, 38px);
}
.plugin-stack a {
width: 44px;
height: 44px;
border-radius: 12px;
}
.plugin-stack li:nth-child(n + 6) a,
.integration-stack li:nth-child(n + 5) a {
left: 0;
}
.plugin-stack img {
width: 28px;
height: 28px;
}
}
.audience-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
@@ -522,7 +798,7 @@ h3 {
}
.audience-card ul {
margin: auto 0 0;
margin: 0 0 20px;
padding-left: 19px;
color: var(--muted-text);
}
@@ -532,15 +808,478 @@ h3 {
}
.install-section {
display: grid;
grid-template-columns: minmax(0, 0.72fr) minmax(360px, 1fr);
gap: 34px;
align-items: start;
scroll-margin-top: 100px;
}
.install-copy {
position: sticky;
top: 112px;
.install-window {
overflow: hidden;
border: 1px solid #51483c;
border-radius: var(--radius);
background: #14110d;
color: #ece4d0;
box-shadow: 0 18px 45px rgb(28 24 20 / 18%), 0 2px 6px rgb(28 24 20 / 12%);
}
.install-window-bar {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 12px;
min-height: 42px;
padding: 10px 16px;
border-bottom: 1px solid #3a352c;
background: linear-gradient(#373129, #2b261f);
}
.install-window-controls {
display: flex;
gap: 8px;
}
.install-window-controls span {
width: 12px;
height: 12px;
border-radius: 50%;
background: #ff5f57;
box-shadow: inset 0 0 0 1px rgb(0 0 0 / 12%);
}
.install-window-controls span:nth-child(2) {
background: #febc2e;
}
.install-window-controls span:nth-child(3) {
background: #28c840;
}
.install-window-title {
color: #c8bfae;
font-family: var(--font-mono);
font-size: 0.75rem;
}
.install-tab[data-group-start] {
margin-left: 14px;
}
.install-tabs {
display: flex;
flex-wrap: nowrap;
overflow-x: auto;
padding: 10px 10px 0;
background: #24201a;
scrollbar-color: #6e6254 #24201a;
scrollbar-width: thin;
}
.install-tab {
display: flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
gap: 8px;
padding: 13px 18px;
border: 1px solid transparent;
border-bottom: 1px solid #3a352c;
border-radius: 7px 7px 0 0;
color: #b9b0a0;
font-family: var(--font-mono);
font-size: 0.8rem;
white-space: nowrap;
}
.install-tab img {
flex-shrink: 0;
width: 24px;
height: 24px;
padding: 2px;
border-radius: 4px;
background: #fff;
object-fit: contain;
}
.install-tab:hover {
background: #302a22;
color: #fff;
text-decoration: none;
}
.install-tab[aria-selected="true"] {
border-color: #3a352c;
border-bottom-color: #14110d;
background: #14110d;
color: #fff;
box-shadow: inset 0 2px #d59aae;
}
.install-tab:focus-visible,
.install-panel:focus-visible {
outline: 2px solid #d59aae;
outline-offset: -4px;
}
.install-panel {
display: grid;
grid-template-columns: minmax(0, 0.55fr) minmax(360px, 1fr);
gap: 32px;
padding: 32px;
align-items: start;
scroll-margin-top: 100px;
}
.install-panel[hidden] {
display: none;
}
.install-panel + .install-panel {
margin-top: 34px;
}
.install-tabs[role="tablist"] ~ .install-panel {
margin-top: 0;
}
.install-art {
margin: 0;
min-width: 0;
}
.install-art-stage {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
min-height: 310px;
padding: 26px 18px;
border-radius: 12px;
background: radial-gradient(ellipse at 50% 25%, #494151, #242126 75%);
overflow: hidden;
}
.install-art figcaption {
margin-top: 14px;
color: #b9b0a0;
text-align: center;
font-size: 0.78rem;
}
.install-art-tile {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
min-width: 0;
text-align: center;
}
.install-art-tile img {
width: 76px;
height: 76px;
object-fit: contain;
border-radius: 16px;
filter: drop-shadow(0 6px 9px #0003);
}
.install-art-tile span {
font-size: 0.74rem;
line-height: 1.35;
}
.install-art-route,
.install-drag-card {
display: grid;
grid-template-columns: minmax(0, 1fr) 30px minmax(0, 1fr);
align-items: center;
width: 100%;
gap: 8px;
}
.install-art-arrow {
font-size: 2rem;
color: #d0c4d8;
text-align: center;
}
.install-drag-card {
padding: 22px 12px;
background: linear-gradient(135deg, #fff, #e9e7ee);
border-radius: 9px;
box-shadow: 0 10px 24px #0004;
color: #302b36;
}
.install-drag-card .install-art-arrow {
color: #aaa4b2;
}
.install-drag-card .install-art-tile img {
width: 70px;
height: 70px;
}
.install-art-shot {
display: block;
width: 100%;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 12px 24px #0005;
}
.install-art-shot img {
width: 100%;
height: auto;
}
.install-art--macos .install-art-stage {
gap: 20px;
}
.install-art--macos .install-art-shot {
transform: rotate(-2deg);
}
.install-art--desktop .install-art-stage {
height: 365px;
background: radial-gradient(ellipse at 70% 30%, #4b5871, #222631 75%);
}
.install-desktop-base {
position: absolute;
bottom: 22px;
left: 24px;
width: 160px;
padding: 24px 12px;
background: #e5f1ff;
border: 1px solid #fff;
border-radius: 12px;
color: #194268;
transform: rotate(-10deg);
box-shadow: 0 14px 28px #0005;
}
.install-desktop-shot {
position: absolute;
top: 26px;
right: 22px;
width: 75%;
height: 215px;
overflow: hidden;
border: 5px solid #eeeaf0;
border-radius: 10px;
transform: rotate(6deg);
box-shadow: 0 12px 24px #0006;
}
.install-desktop-shot img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: top;
}
.install-art-file,
.install-art-chips span {
padding: 8px 12px;
border: 1px solid #81748b;
border-radius: 6px;
background: #302837;
color: #ece4f1;
font: 0.7rem var(--font-mono);
}
.install-art-file {
transform: rotate(3deg);
margin-top: -40px;
}
.install-package-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
width: 78%;
padding: 24px;
border: 1px solid #84758c;
border-radius: 14px;
background: linear-gradient(145deg, #504256, #2e2633);
transform: rotate(-4deg);
box-shadow: 12px 12px 0 -4px #332d3a, 12px 12px 0 -3px #65596f, 0 18px 28px #0004;
}
.install-package-line {
height: 24px;
border-left: 2px dashed #b7a4c1;
}
.install-art-chips {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px;
}
.install-art-platforms {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
width: 100%;
}
.install-art-platforms .install-art-tile {
padding: 18px 8px;
border: 1px solid #776880;
border-radius: 12px;
background: #ffffff0a;
}
.install-script-card {
width: 100%;
padding: 24px 18px;
border: 1px solid #76667f;
border-radius: 10px;
background: #19161d;
transform: rotate(-4deg);
box-shadow: 0 14px 24px #0005;
}
.install-script-card code {
font-size: clamp(0.65rem, 1.1vw, 0.85rem);
}
.install-script-prompt,
.install-script-card code span {
color: #c5e4b1;
}
.install-script-progress {
display: flex;
gap: 5px;
margin-top: 18px;
}
.install-script-progress i {
height: 5px;
flex: 1;
border-radius: 3px;
background: #8ca976;
}
.install-server-rack {
width: 155px;
height: 175px;
fill: #353847;
stroke: #9eadd0;
stroke-width: 2;
}
.install-server-rack circle {
fill: #a7cf96;
stroke: none;
}
.install-art--server .install-art-tile,
.install-art--cloud .install-art-tile {
margin-top: -65px;
z-index: 1;
}
.install-cloud {
width: 230px;
height: 160px;
fill: #5e5573;
stroke: #bdb0d2;
stroke-width: 2;
}
.install-art--extension .install-art-route {
display: flex;
justify-content: center;
}
.install-art--extension .install-art-shot {
transform: rotate(-3deg);
}
.install-panel .eyebrow {
color: #b9b0a0;
}
.install-panel a {
color: #e9adc2;
}
.install-panel .install-download {
width: 100%;
gap: 18px;
margin-bottom: 18px;
padding: 22px 24px;
color: var(--brand-text);
font-size: clamp(1.5rem, 2.5vw, 2rem);
line-height: 1.2;
text-align: left;
}
.install-download svg {
flex: 0 0 auto;
width: 0.95em;
height: 1.25em;
}
.install-download:focus-visible {
outline: 3px solid #e9adc2;
outline-offset: 4px;
}
.install-panel .command-card {
padding: 0;
border: 0;
border-radius: 0;
box-shadow: none;
background: #3a352c;
}
.install-panel .step {
grid-template-columns: 26px minmax(0, 1fr);
gap: 14px;
padding: 20px 0;
background: #14110d;
}
.install-panel .step:first-child {
padding-top: 0;
}
.install-panel .step:last-child {
padding-bottom: 0;
}
.install-panel .step > span {
width: 26px;
height: 26px;
background: #302a22;
color: #e9adc2;
font-family: var(--font-mono);
font-size: 0.8rem;
}
.install-panel .ab-terminal {
background: #1c1915;
}
.install-panel h4 {
margin: 0 0 12px;
font-size: 1.08rem;
line-height: 1.25;
}
.install-panel .ab-terminal + p {
margin-top: 14px;
}
.install-panel .step p:last-child {
margin-bottom: 0;
}
.command-card {
@@ -754,10 +1493,14 @@ h3 {
}
@media (max-width: 980px) {
.features-section .feature-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.site-header,
.hero,
.split,
.install-section,
.install-panel,
.docs-band,
.site-footer {
grid-template-columns: 1fr;
@@ -795,12 +1538,20 @@ h3 {
}
@media (max-width: 680px) {
.section,
.trust-strip,
.site-footer {
width: min(358px, calc(100vw - 32px));
margin-left: 16px;
margin-right: 16px;
.features-section .feature-grid {
grid-template-columns: 1fr;
}
.install-panel {
padding: 22px 16px;
}
.install-panel .step {
grid-template-columns: minmax(0, 1fr);
}
.install-panel .step > span {
display: none;
}
.section {
+5 -5
View File
@@ -1,6 +1,6 @@
[project]
name = "archivebox"
version = "0.9.35rc473"
version = "0.9.35rc517"
requires-python = ">=3.13"
description = "Self-hosted internet archiving solution."
authors = [{name = "Nick Sweeting", email = "pyproject.toml@archivebox.io"}]
@@ -78,9 +78,9 @@ dependencies = [
### Extractor dependencies (runtime binaries resolved through abxpkg)
### Binary/Package Management
"abxbus==2.5.56", # direct imports only; version constrained by abx-dl -> abx-plugins
"abxpkg==1.12.118", # direct imports only; version constrained by abx-dl -> abx-plugins
"abx-plugins[opencode]==1.12.252", # optional AI runtime clients are owned by the plugin
"abx-dl==1.12.289", # shared ArchiveBox downloader package
"abxpkg==1.12.125", # direct imports only; version constrained by abx-dl -> abx-plugins
"abx-plugins[opencode]==1.12.278", # optional AI runtime clients are owned by the plugin
"abx-dl==1.12.315", # shared ArchiveBox downloader package
### UUID7 backport for Python <3.14
"uuid7>=0.1.0; python_version < '3.14'", # provides the uuid_extensions module on Python 3.13
"browser-cookie3>=0.20.1",
@@ -342,7 +342,7 @@ Donate = "https://github.com/ArchiveBox/ArchiveBox/wiki/Donations"
[tool.bumpver]
current_version = "v0.9.35rc473"
current_version = "v0.9.35rc517"
version_pattern = "vMAJOR.MINOR.PATCH[PYTAGNUM]"
commit_message = "bump version {old_version} -> {new_version}"
tag_message = "{new_version}"
Generated
+15 -15
View File
@@ -13,18 +13,18 @@ supported-markers = [
]
[options]
exclude-newer = "2026-09-13T06:06:59.555346705Z"
exclude-newer = "2026-09-13T21:41:28.931651087Z"
exclude-newer-span = "P5D"
[options.exclude-newer-package]
abxbus = { timestamp = "2026-09-18T06:06:58.555362062Z", span = "PT1S" }
abxbus = { timestamp = "2026-09-18T21:41:27.931664943Z", span = "PT1S" }
abx-plugins = "2100-01-01T00:00:00Z"
abx-dl = "2100-01-01T00:00:00Z"
abxpkg = "2100-01-01T00:00:00Z"
[[package]]
name = "abx-dl"
version = "1.12.289"
version = "1.12.315"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "abx-plugins", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
@@ -38,14 +38,14 @@ dependencies = [
{ name = "rich", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "rich-click", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e3/18/99113fc3117ab0cb272582e2ed66b959fc7f0efcb763f5d1ccc04095b7cc/abx_dl-1.12.289.tar.gz", hash = "sha256:b91ed92fa4d431a01165880054e85e4da00e6ebbd6d24b2472eb4e7b341f2ef5", size = 88248 }
sdist = { url = "https://files.pythonhosted.org/packages/aa/e2/7a565357693e11be91266ff874c1866a74519256b54f9b4d1a9901bd9434/abx_dl-1.12.315.tar.gz", hash = "sha256:74cbb9ebf6f9709db26886a4e6183d85a426c136dc595c780f79b4f2726fdb18", size = 87772 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/af/56/daf1fc30cce421356d6cea1497fa7e3fa31d19b84f4f554c161b50ccf479/abx_dl-1.12.289-py3-none-any.whl", hash = "sha256:bd94d50010470393b5ad6438487d63e9bfb84eb6b26217c1585be81e862cf803", size = 93264 },
{ url = "https://files.pythonhosted.org/packages/9a/97/11185dbfa4f241e01737cd0c777c7eda121b2ea6c755b100acfe3f5caf30/abx_dl-1.12.315-py3-none-any.whl", hash = "sha256:126bf06c55c943dc1a54e4caaf8b870826c897535c7ceb06ff771542103664d7", size = 93004 },
]
[[package]]
name = "abx-plugins"
version = "1.12.252"
version = "1.12.278"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "abxbus", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
@@ -54,9 +54,9 @@ dependencies = [
{ name = "rich-click", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "uv", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ee/8c/66d64ce850fbb41b8e941f2b95d79b7ddc9ebd4f7238f447a7bf98fd91d0/abx_plugins-1.12.252.tar.gz", hash = "sha256:dac5a4529fc439e37c2442d5f5a06e17dbafa33fb4a4662123e02147b2e18e41", size = 463016, upload-time = "2026-09-18T05:34:20.338Z" }
sdist = { url = "https://files.pythonhosted.org/packages/fd/3d/f76c93e93712448bdaf5452887b383eec82fa193a7f6702aafe47a806c56/abx_plugins-1.12.278.tar.gz", hash = "sha256:65993dd1290b895d72a503ab5f0e2bfa54d1b5a3e56e5ffad901fe8318ac3ede", size = 344470, upload-time = "2026-09-18T21:02:28.989Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3f/2d/151511349ff8f2ca6e11c756c98c6797030511fbad95d66461feb07a895a/abx_plugins-1.12.252-py3-none-any.whl", hash = "sha256:1d2a42d055a26d448b3a27664ff6ca80aa01498636377052eda6664e16206afa", size = 629564, upload-time = "2026-09-18T05:34:18.845Z" },
{ url = "https://files.pythonhosted.org/packages/05/29/d21f1a129049504cd1f0f68debed779b72659e7425c5d5a29ed0ca32a446/abx_plugins-1.12.278-py3-none-any.whl", hash = "sha256:cf8c0cd1ac8318d16825cbb97fb248dcbdd6ca448e5f3a5ae9e290119727efdd", size = 511364, upload-time = "2026-09-18T21:02:27.128Z" },
]
[package.optional-dependencies]
@@ -82,7 +82,7 @@ wheels = [
[[package]]
name = "abxpkg"
version = "1.12.118"
version = "1.12.125"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "platformdirs", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
@@ -90,9 +90,9 @@ dependencies = [
{ name = "rich-click", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c1/c6/d6d0c7c2481a0525e451230e34ab832c4abc71dcbadd734fdcacac18465f/abxpkg-1.12.118.tar.gz", hash = "sha256:a68b0d72b495142e87a014cd90cfe949524eb7187d981bf0775579454f7c29ef", size = 239381, upload-time = "2026-09-18T05:27:25.739Z" }
sdist = { url = "https://files.pythonhosted.org/packages/87/fc/cf3f9d370ee93202c2e9239d267ca0b0dece7dc3595d36eebbedf3ab2946/abxpkg-1.12.125.tar.gz", hash = "sha256:14d98f4ff305f5ac84030f4d1f16a2f6c511ff5480ebfb08ba133f367a0770e1", size = 239374, upload-time = "2026-09-18T07:29:21.549Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e9/67/860d7e3d81e7f15f836d1157f77955b047808237fa8ef8949b21be38adc9/abxpkg-1.12.118-py3-none-any.whl", hash = "sha256:b632be829ae692d35b88da605341bf4d4fd78af6fb7cca2ea1feddf4a39290e0", size = 253748, upload-time = "2026-09-18T05:27:24.028Z" },
{ url = "https://files.pythonhosted.org/packages/bf/5c/dd0d1690e4c1d6241f44a5194a525af6769acdf33dd366a6b4b56f33c2b0/abxpkg-1.12.125-py3-none-any.whl", hash = "sha256:cfef2e06ed01b8774e8bdf0b8de36ab592a0dfa273993c4824628ab17d7d0fd1", size = 253748, upload-time = "2026-09-18T07:29:23.043Z" },
]
[[package]]
@@ -127,7 +127,7 @@ wheels = [
[[package]]
name = "archivebox"
version = "0.9.35rc473"
version = "0.9.35rc517"
source = { editable = "." }
dependencies = [
{ name = "abx-dl", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
@@ -226,10 +226,10 @@ dev = [
[package.metadata]
requires-dist = [
{ name = "abx-dl", specifier = "==1.12.289" },
{ name = "abx-plugins", extras = ["opencode"], specifier = "==1.12.252" },
{ name = "abx-dl", specifier = "==1.12.315" },
{ name = "abx-plugins", extras = ["opencode"], specifier = "==1.12.278" },
{ name = "abxbus", specifier = "==2.5.56" },
{ name = "abxpkg", specifier = "==1.12.118" },
{ name = "abxpkg", specifier = "==1.12.125" },
{ name = "archivebox", extras = ["sonic", "ldap", "debug"], marker = "extra == 'all'" },
{ name = "atomicwrites", specifier = "==1.4.1" },
{ name = "base32-crockford", specifier = ">=0.3.0" },