Packs

Extension bundles — a single .tgz that ships many extensions at once. Install one pack and get all its members in a single operation, with no per-extension steps.

What a pack is

A pack is a single .tgz archive that contains multiple extensions of any type — plugins, providers, senders, themes, homepages, IdP connectors, login pages, webhooks and documentation. Every installable extension type can travel in a pack; the only thing a pack cannot contain is another pack. It is the recommended way to distribute a curated set: a "dark ops" pack that bundles the Post-Punk theme, the Matrix homepage and the Ops plugin, or a vendor pack that ships a plugin together with the login page that fronts it, the webhook that feeds it and its own user guide.

How a pack is built

A pack is a fat .tgz with a package.json (pack metadata, extensionType: "pack"), a pack.json listing the member extensions, and one inner .tgz per member.

On install, Kwirth verifies that none of the members is already present (the whole pack is rejected otherwise), installs every member with the normal per-extension logic, records the pack in a dedicated ConfigMap (kwirth-packs), and tags each member with installedFrom: "pack:<id>".

Install rules

Managing packs

Open ☰ → Manage extensions → Packs — the same card / list layout every extension family uses. Each pack card shows its name and version, a description, a source chip (local for a file upload, a URL chip, or a Kwirth chip for registry installs), a member summary (e.g. 1 theme, 1 homepage, 1 plugin) and a single 🗑 Uninstall that removes the pack and all its members at once.

Install from a URL, a local file, or the registry — the Available packs section lists curated packs when the public kwirthmagnify registry is reachable.

Pack-owned extensions

An extension installed via a pack shows a via pack badge in the manager of its own family, and its individual uninstall button is disabled — you remove the parent pack, never a single member. This prevents partial teardowns that would leave the pack metadata inconsistent.

Creating a pack

Use the create-pack.mjs script at the repository root. Pass --include <type>:<name> to build an extension from source and embed a freshly built artifact (repeatable — types: plugin, provider, sender, theme, homepage, idp, login, webhook), or list pre-built .tgz files as positional arguments — which is how documentation travels, since it has no source folder of its own. Each run produces a distributable <id>-<version>.pack.tgz.

# Build from source and bundle in one command
node packs/create-pack.mjs dark-ops \
  --include theme:post-punk \
  --include homepage:matrix \
  --include plugin:ops \
  --name "Dark Ops" --version "1.0.0"

# Or use pre-built .tgz files directly
node packs/create-pack.mjs my-pack \
  ./dist/my-plugin-1.0.0.tgz \
  ./dist/my-theme-1.0.0.tgz \
  --name "My Pack"

The result contains the member tgzs plus a pack.json manifest and a package.json with extensionType: "pack". Upload it through ☰ → Manage extensions → Packs.

Notes

Documentation packages

Self-contained docsify sites that Kwirth installs and serves itself — documentation hosted by the platform, with no external dependency.

What a documentation package is

A documentation package is a docsify site bundled as a .tgz that Kwirth serves directly from its own back end. Once installed it is reachable in the browser with no external host — the Kwirth server itself is the documentation host.

A documentation package always documents another extension, so it is identified by the pair that points at it: targetType is the type of the documented extension (plugin, provider, sender, theme, homepage, idp, login, or core for the Kwirth core itself) and id is that extension's own id — the Excubitor guide carries targetType: plugin and id: excubitor. The id alone would not be unique, since a plugin and a theme may share a name and each ship its own guide. Packages are served at /docs/<targetType>/<id>/, and Kwirth uses the same pair to point an extension's Help buttons at its guide. The core/kwirth package — the user & admin guide — documents the core itself and ships bundled with every Kwirth deployment.

Managing packages

Open ☰ → Manage extensions → Documentation. The left panel lists every installed package; each card shows its name, version, a short description, a source chip and two actions — 📖 Open docs (opens the site in a new tab) and, for non-bundled / non-dev packages, 🗑 Uninstall.

bundledcoreShipped with Kwirth — cannot be uninstalled.
devlocalLoaded from a local build (development only).
localuploadInstalled from a file you uploaded.
KwirthregistryInstalled from the official kwirthmagnify registry.
URLremoteInstalled from a custom URL.

Installing a package

Install from a URL (paste the .tgz URL and click ⬇ Download), from a local file (Browse… and upload — extracted server-side), or from the registry (the Available documentation section, when the public kwirthmagnify registry is reachable).

Package format

A valid package is a .tgz with a root package.json carrying at least extensionType: "docs", the targetType / id pair of the extension it documents, plus name and version, and a docsify index.html with its Markdown content. targetType is exclusive to documentation packages: every other extension type declares only extensionType and its own id.

Notes