b5f32b7b2b
Wrapping a packed viewer in a .app or .AppImage was its own --format app value, parallel to zim and binary. But an app is really just the binary format with a bundle around it, so a separate format meant duplicating the base/icon handling and made the three formats feel like an awkward choice. Turn it into a --app flag that builds on the binary format. It composes with --base (including a webview base) and --icon, while --format stays zim or binary. The bundle builders are unchanged; only the CLI surface moves.
6.5 KiB
6.5 KiB
Changelog
All notable changes to kage are recorded here. The format follows Keep a Changelog, and the project aims to follow Semantic Versioning.
Unreleased
0.1.2 - 2026-06-15
Security
- Chrome now keeps its sandbox on by default. It was previously launched with
--no-sandboxunconditionally, which removed Chrome's main line of defense when rendering pages from the open web (reported in #10). The sandbox is now dropped only where it genuinely cannot run: inside a container, or when running as root, and the choice is logged so it is never silent.
Added
- Container-aware Chrome flags. kage detects a container from the
IN_DOCKERenvironment variable or a/.dockerenvmarker and, only there, drops the sandbox and adds--disable-dev-shm-usage(the default 64 MB/dev/shmis too small for Chrome on large pages). Outside a container the faster shared memory is left in place. - Asset downloads retry on a transient failure (a 403/429, a 5xx, or a network blip) with a short backoff, recovering files that bot-protection rejects on the first request of a burst. Permanent failures (404, 401, ...) are not retried.
kage pack --appwraps the packed viewer in a double-click desktop app with the site's favicon as the icon. The flag builds on the binary format, so it composes with--base(including awebviewbase) and--icon. On macOS it writes a.appbundle (Info.plist, the viewer underContents/MacOS, and an.icnsgenerated from the favicon); on Linux, with a Linux--base, it writes an AppImage-style.AppDirand folds it into a single.AppImagewhenappimagetoolis installed. The icon is found in the mirror automatically (preferring a largeapple-touch-icon.png, thenfavicon.pngor a PNG-basedfavicon.ico) and can be overridden with--icon.- The release now ships a GUI-subsystem Windows base,
kage_<version>_windows-gui_<arch>.zip. Packing a viewer onto it with--format binary --baseproduces a.exethat opens with no console window behind it, the Windows equivalent of the.appdouble-click experience.
Changed
- Clearer crawl error reporting. Each failure is logged with a classified reason (
HTTP 403 Forbidden,timed out, ...), the URL, and the page that referenced it, and the end-of-run summary lists what went wrong instead of printing only a count. - Cross-platform packing detects the base binary's target OS from its executable
header (ELF, PE, or Mach-O) rather than its file name, so a Windows viewer
always gets a
.exesuffix and the run hint names the right platform even when the base is named without one.
Fixed
- The container image now runs. Chrome aborted on launch with
chrome_crashpad_handler: --database is required, so kage disables Chrome's crash reporter inside a container, and thekageuser now has a writable home (the mounted/outvolume) so the default output, resume state, and Chrome's profile no longer fail with a permission error (issue #7).
0.1.1 - 2026-06-14
Added
kage pack <mirror-dir>packs a cloned folder into one distributable file.--format zim(the default) writes an open ZIM archive, the same single-file format Kiwix uses;--format binaryappends that archive to a copy of kage to produce a self-contained executable that serves the site offline when run. Flags cover the output path, metadata (--title,--description,--language,--date), a--basebinary for cross-platform viewers, and--no-compress.kage open <file.zim>serves a packed ZIM over a local HTTP server and opens your browser, the read side ofkage pack --format zim.- An optional native-window viewer. Built with
-tags webview(which needs cgo),kage openand a packed binary present the offline site in a real window backed by the operating system's WebView (WKWebView, WebView2, WebKitGTK) instead of a browser tab, so a packed kage feels like a standalone app. The default build stays pure Go (CGO_ENABLED=0) and falls back to the system browser, so the release pipeline is unchanged. - A pure-Go
zimpackage that writes and reads the ZIM format: a fixed header, MIME and pointer lists, zstd-compressed (or stored) clusters, redirects, and a trailing MD5. It reads xz clusters so archives from other tooling open, and writes zstd or stored only. Packing is deterministic: the same mirror produces a byte-identical archive, with the UUID derived from the content rather than randomised.
0.1.0 - 2026-06-14
The first release. kage clones a live website into a self-contained folder you can browse offline, with every script stripped out.
Added
kage clone <url>renders each page in headless Chrome, snapshots the final DOM, removes every<script>,on*handler, andjavascript:URL, and downloads the CSS, images, fonts, and media, rewriting them to local paths.kage serve [dir]runs a local static file server over a cloned folder so the mirror's links and assets resolve the way they would on a real host.- Deterministic URL-to-path mapping: pages become
<slug>/index.htmldirectories, assets live under the reserved_kage/<host>/tree, and query strings fold into a short hash suffix so versioned URLs never collide. - Three concurrency tiers run in parallel: page-render workers (
--workers), asset-download workers (--asset-workers), and a Chrome page pool (--browser-pages). - A polite crawl by default: honours
robots.txt, seeds fromsitemap.xml, and scopes to the seed host.--scope-prefix,--max-depth,--max-pages,--subdomains, and--excludeshape the frontier. - Idempotent, resumable crawling. Each page is keyed by the file it writes, so
the same URL reached over http and https, with or without a trailing slash,
or as
/index.htmlversus/, is fetched exactly once. A re-run resumes from_kage/state.json;--refreshre-renders a mirror in place to pull in changed content;--forcewipes and starts clean;--no-resumeruns stateless. - Defaults to a per-user data directory (
$HOME/data/kage), overridable with-o/--out. - Cross-platform distribution: prebuilt archives,
.deb/.rpm/.apkpackages, a multi-arch container image on GHCR (Chromium bundled), checksums, SBOMs, and a cosign signature, all cut from one version tag by GoReleaser.