Installation
User guide
Exam protocol
Offline mode
How materials are downloaded and stored, what cannot be archived, the video branch, the cache and the download report.
The “offline” switch downloads all of a program’s materials to disk. After that the network is not needed: links inside topics open from the local archive.
A material’s type field already says how:
type | Strategy |
|---|---|
docs | llms.txt / the .md variant first, otherwise mirror the section |
article, post, guide | one self-contained HTML file plus the reader |
spec, rfc | the same, usually clean HTML already |
repo | a shallow clone |
video | external yt-dlp, if it is present in the system |
paper | direct PDF download |
The liveness field is a ready-made filter. Materials marked paywall or login_required are
not fetched at all — the result would be a login page, not the material — and are shown as
“unavailable offline”, honestly.
Archiving is done by monolith, used as a library: it inlines CSS, images, fonts and scripts as data URIs and returns a single HTML5 file. Pages are saved isolated and without JS — an archived article does not need scripts, and isolation guarantees the saved page will never reach out to the network.
monolith has no JS engine of its own, so a page that renders itself on the client would be saved empty. Bundling Chromium to fix that is unnecessary: Tauri already runs on the system WebView. A hidden window opens the URL, waits for load, hands the rendered HTML to monolith and closes. No new dependencies, no extra megabytes, and the window lives on a timeout so it cannot hang the queue.
Readable text is extracted by dom_smoothie, a Rust port of readability.js — the same
algorithm browsers use for reader mode. It is a second layer on top of the archive, not a
replacement: if extraction fails, the saved HTML is shown as it is rather than an empty screen.
First we try what the site offers itself:
/llms.txt and /llms-full.txt — by now a de facto standard for developer documentation,
and the ideal offline format: clean Markdown..md variant of a page — many documentation generators serve one.sitemap.xml — when a crawl is needed but the boundaries should be known upfront.Only if none of that exists does the crawler run, with hard limits: the same domain, depth 2 by
default, a page-count ceiling and robots.txt respected. Links between saved pages are
rewritten to local ones.
yt-dlp is not bundled. The app looks for yt-dlp and ffmpeg in PATH: if they are absent
the button is disabled, with an explanation and the install command for the current OS next to
it; if they are present they run as an external process with progress and a cancel button.
PATH is parsed by the rules of its own OS — ; as the separator on Windows, : elsewhere.
The default resolution cap is 720p: a 40-minute lecture at 1080p is hundreds of megabytes, and slide legibility does not change.
<app-data>/cache/objects/<sha256[0:2]>/<sha256>
<app-data>/cache/index.sqlite
The index maps url → sha256, type, fetched_at, size, etag, last_modified. Content addressing
gives deduplication: the same RFC referenced by three programs is stored once. The cache lives
outside the bundle, because a bundle gets regenerated and the cache has to survive that.
Revalidation uses conditional requests with ETag / Last-Modified. The disk budget is
configurable, eviction is LRU, and objects belonging to programs with offline enabled are
protected from eviction.
A download ends with an honest report, not with “done”:
Downloaded 34
Skipped 6 paywall (4), login_required (2)
Failed 3 timeout (2), 404 (1)
Failed items are retried by a separate action, without re-downloading the successful ones.