CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

web-archive

Use when capturing a URL as a durable self-contained HTML — vault-ingest URL inputs, preserving a tweet/reddit post/article before it gets taken down, claim verification against frozen content, or any "save this page so it survives a future site change" task.

Quality

88%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

web-archive

URL in, single self-contained HTML out at <project_root>\__references\__archives.web\<domain>\<slug>.<date>.html. Every CSS/JS/image/font inlined as data: URIs — works offline, portable across machines, no broken refs. Metadata is embedded inside the HTML. A SQLite index next to the archives provides fast url → path lookup.

When to use

  • /vault-ingest receives a URL → archive as backup alongside markdown conversion
  • X post / Reddit thread / blog post / article you're citing — capture before it disappears
  • User says: "save this", "archive", "snapshot", "back up this link"

Don't use for: JSON / REST APIs (use WebFetch); one-shot read of one page (use WebFetch); local files you already control.

Output layout

<project_root>/__references/__archives.web/
├── .archive.sqlite                                # index (+ future cookies/sessions)
├── x.com/
│   └── tom_doerr-status-2059312274989256935.2026-05-27.html
└── docs.python.org/
    └── 3-library-asyncio.2026-05-27.html

Filename: <path-slug>.<YYYY-MM-DD>.html. Same URL re-captured the same day with different content → <slug>.<YYYY-MM-DD>T<HHMMSS>Z.html (both kept). Identical content → cache hit, no new file.

Python API

from web_archiver import archive, lookup

result = archive(
    url="https://x.com/tom_doerr/status/2059312274989256935",
    project_root=None,        # auto-detected from cwd if omitted
    backend="auto",
    options={"timeout_sec": 60},
)
# result.archive_path (Path), .sha256, .backend, .status, .captured_at, .url, .fresh

existing = lookup(url="https://x.com/...")   # Optional[ArchiveResult]

Project-root resolution: explicit arg → WEB_ARCHIVE_PROJECT_ROOT env → cwd walk-up for .claude//.pi//__references/ marker → cwd.

CLI

web-archive archive --url <url> [--project-root <path>] [--backend NAME]
                    [--timeout-sec N] [--force] [--json]
web-archive lookup --url <url> [--project-root <path>] [--json]

Exit codes: 0 ok, 1 failed / not-found, 2 bad args.

Backend selection (backend="auto")

URL shapeBackend
Single article / docs page / blog postsinglefile
Site mirror (depth/max-files set)oe-com if available, else singlefile
Twitter / Reddit / Instagram / YouTubegallery-dl

Only singlefile is implemented today. Pinned-but-unavailable backends raise; auto downgrades silently.

Install

pip install -e <path-to>/web-archiver
npm install -g single-file-cli           # required backend

Common mistakes

  • Passing a YouTube / Reddit / Twitter URL with backend="singlefile" → useless "log in" capture. Use auto.
  • Treating fresh=False as failure → it's a cache hit. Check status.
  • Calling for JSON API URLs → wrong tool. Use WebFetch.

See __docs/output-contract.md for the full contract — embedded-metadata format, SQLite schema, slugify rules, determinism semantics.

Repository

KennethJefferson/ccg_ccSkill_WebArchiver

Path

__solutions/web-archiver/SKILL.md

Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.