abx-plugins
Purpose
abx-plugins contains standalone hook scripts and config schemas used by ArchiveBox and abx-dl.
Shared Rules
- Keep this repo on branch
main.
- Use
uv and uv run for Python commands.
- Do not use system
python, direct .venv/bin/python, or pip commands.
- Use real hook scripts, real installs, real browsers, real subprocesses, real files, and real URLs or
pytest-httpserver.
- Do not mock, monkeypatch, fake, simulate, skip, xfail, or weaken tests.
- Verify JSONL records, exit codes, config hydration, output files, and filesystem side effects.
- Read
README.md for the full plugin contract, hook lifecycle, config schema, and test surface.
Development Setup
set -euo pipefail
uv sync --inexact
uv run --no-sync --no-sources python - <<'PY'
from pathlib import Path
import abx_plugins
package = Path(abx_plugins.__file__).resolve().parent
plugins = {path.name for path in (package / "plugins").iterdir() if path.is_dir()}
assert {"base", "chrome", "hashes", "title", "wget"} <= plugins
PY
User-Facing Inspection
Inspect the installed plugin package directly:
set -euo pipefail
uv run --no-sync --no-sources python - <<'PY'
from pathlib import Path
import abx_plugins
package = Path(abx_plugins.__file__).resolve().parent
title = package / "plugins" / "title"
assert (title / "config.json").is_file()
assert (title / "on_Snapshot__54_title.js").is_file()
PY
Basic Usage
set -euo pipefail
test -d abx_plugins/plugins/title
uv run --no-sync --no-sources python -m json.tool abx_plugins/plugins/chrome/config.json >/dev/null
test -x abx_plugins/plugins/title/on_Snapshot__54_title.js
node -c abx_plugins/plugins/chrome/chrome_utils.js
Verification
set -euo pipefail
uv run --no-sync --no-sources python - <<'PY'
from pathlib import Path
from abx_plugins.plugins.base.testing import get_hook_script, get_plugin_dir
plugin_dir = get_plugin_dir("abx_plugins/plugins/title/tests/test_title.py")
hook = get_hook_script(plugin_dir, "on_Snapshot__*_title.*")
assert plugin_dir.resolve() == Path("abx_plugins/plugins/title").resolve()
assert hook is not None and hook.is_file()
PY
Chrome-specific logic belongs in the Chrome plugin helpers. Plugins inherit config from required_plugins; do not duplicate config already provided by dependencies.
1---2name: abx-plugins3description: Use this when working on ArchiveBox plugin hooks, config schemas, hook ordering, browser helpers, required binaries, and plugin tests.4---56# abx-plugins78## Purpose910`abx-plugins` contains standalone hook scripts and config schemas used by ArchiveBox and `abx-dl`.1112## Shared Rules1314- Keep this repo on branch `main`.15- Use `uv` and `uv run` for Python commands.16- Do not use system `python`, direct `.venv/bin/python`, or `pip` commands.17- Use real hook scripts, real installs, real browsers, real subprocesses, real files, and real URLs or `pytest-httpserver`.18- Do not mock, monkeypatch, fake, simulate, skip, xfail, or weaken tests.19- Verify JSONL records, exit codes, config hydration, output files, and filesystem side effects.20- Read `README.md` for the full plugin contract, hook lifecycle, config schema, and test surface.2122## Development Setup2324```bash25set -euo pipefail26uv sync --inexact27uv run --no-sync --no-sources python - <<'PY'28from pathlib import Path2930import abx_plugins3132package = Path(abx_plugins.__file__).resolve().parent33plugins = {path.name for path in (package / "plugins").iterdir() if path.is_dir()}34assert {"base", "chrome", "hashes", "title", "wget"} <= plugins35PY36```3738## User-Facing Inspection3940Inspect the installed plugin package directly:4142```bash43set -euo pipefail44uv run --no-sync --no-sources python - <<'PY'45from pathlib import Path4647import abx_plugins4849package = Path(abx_plugins.__file__).resolve().parent50title = package / "plugins" / "title"51assert (title / "config.json").is_file()52assert (title / "on_Snapshot__54_title.js").is_file()53PY54```5556## Basic Usage5758```bash59set -euo pipefail60test -d abx_plugins/plugins/title61uv run --no-sync --no-sources python -m json.tool abx_plugins/plugins/chrome/config.json >/dev/null62test -x abx_plugins/plugins/title/on_Snapshot__54_title.js63node -c abx_plugins/plugins/chrome/chrome_utils.js64```6566## Verification6768```bash69set -euo pipefail70uv run --no-sync --no-sources python - <<'PY'71from pathlib import Path7273from abx_plugins.plugins.base.testing import get_hook_script, get_plugin_dir7475plugin_dir = get_plugin_dir("abx_plugins/plugins/title/tests/test_title.py")76hook = get_hook_script(plugin_dir, "on_Snapshot__*_title.*")77assert plugin_dir.resolve() == Path("abx_plugins/plugins/title").resolve()78assert hook is not None and hook.is_file()79PY80```8182Chrome-specific logic belongs in the Chrome plugin helpers. Plugins inherit config from `required_plugins`; do not duplicate config already provided by dependencies.