diff --git a/CHANGELOG.md b/CHANGELOG.md index b8c941f..2669796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,32 @@ All notable changes to kage are recorded here. The format follows ## [Unreleased] +## [0.1.1] - 2026-06-14 + +### Added + +- `kage pack ` 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 binary` appends 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 `--base` binary for cross-platform viewers, and + `--no-compress`. +- `kage open ` serves a packed ZIM over a local HTTP server and opens + your browser, the read side of `kage pack --format zim`. +- An optional native-window viewer. Built with `-tags webview` (which needs + cgo), `kage open` and 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 `zim` package 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 @@ -39,5 +65,6 @@ can browse offline, with every script stripped out. a multi-arch container image on GHCR (Chromium bundled), checksums, SBOMs, and a cosign signature, all cut from one version tag by GoReleaser. -[Unreleased]: https://github.com/tamnd/kage/compare/v0.1.0...HEAD +[Unreleased]: https://github.com/tamnd/kage/compare/v0.1.1...HEAD +[0.1.1]: https://github.com/tamnd/kage/compare/v0.1.0...v0.1.1 [0.1.0]: https://github.com/tamnd/kage/releases/tag/v0.1.0 diff --git a/Makefile b/Makefile index 099483f..529153f 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,17 @@ LDFLAGS := -s -w \ export CGO_ENABLED := 0 -.PHONY: build install test test-short vet tidy clean run +.PHONY: build build-webview install test test-short vet tidy clean run build: go build -ldflags "$(LDFLAGS)" -o bin/$(BIN) $(PKG) +# A native-window viewer: opens packed sites in their own OS WebView window +# instead of the browser. Needs cgo, so it is built separately from the default +# pure-Go binary and the release pipeline. +build-webview: + CGO_ENABLED=1 go build -tags webview -ldflags "$(LDFLAGS)" -o bin/$(BIN) $(PKG) + install: go install -ldflags "$(LDFLAGS)" $(PKG) diff --git a/README.md b/README.md index 545c2e5..6fddfec 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,177 @@ # kage -**kage** (影, "shadow") clones a website into a self-contained folder you can -browse offline, with all the JavaScript stripped out. It renders every page in -headless Chrome, snapshots the final rendered DOM, removes every script and -event handler, and downloads the CSS, images, and fonts and rewrites them to -local paths. The result looks like the live site but runs no code: a plain -folder of `.html` files you can open straight from disk. +[![ci](https://github.com/tamnd/kage/actions/workflows/ci.yml/badge.svg)](https://github.com/tamnd/kage/actions/workflows/ci.yml) +[![Release](https://img.shields.io/github/v/release/tamnd/kage)](https://github.com/tamnd/kage/releases/latest) +[![Go Reference](https://pkg.go.dev/badge/github.com/tamnd/kage.svg)](https://pkg.go.dev/github.com/tamnd/kage) +[![Go Report Card](https://goreportcard.com/badge/github.com/tamnd/kage)](https://goreportcard.com/report/github.com/tamnd/kage) +[![License](https://img.shields.io/github/license/tamnd/kage)](./LICENSE) -```bash -kage clone example.com -kage serve kage-out/example.com -``` +**kage** (影, "shadow") clones a website into a folder you can browse offline, with every script stripped out. It opens each page in real headless Chrome, waits for the page to settle, snapshots the DOM a human would have seen, then deletes all the JavaScript and pulls the CSS, images, and fonts down to local paths. What lands on disk looks like the live site and runs no code. -## Why +[Install](#install) • [Quick start](#quick-start) • [Commands](#commands) • [Clone](#clone) • [Pack](#pack-it-into-one-file) • [Native window](#a-real-window-not-a-browser-tab) • [How it works](#how-it-works) -Saving a page with "Save As" gives you a copy that still phones home, still runs -analytics, and often renders blank because the markup is built by JavaScript at -runtime. kage takes the opposite approach: +![kage cloning paulgraham.com, packing it into one file, and serving it back offline](docs/static/demo.gif) -- **Render first, save second.** Each page goes through real headless Chrome, so - a page whose content is assembled by JavaScript is captured the way a human - would have seen it, not as an empty shell. -- **Strip every script.** Once the DOM is captured, kage removes all `