Koder Package Format (.kpkg)
Especificação do formato `.kpkg` (pacote universal da Koder Hub): estrutura ZIP+bootstrap, kpkg.toml, plataformas suportadas, assinatura, export targets. Status: Normative (v0.1.0 Draft). Consultar ao trabalhar com `platform/kpkg` ou ao gerar pacotes para a Koder Hub.
When this spec applies
All triggers
- Trabalhar em platform/kpkg (engine ou CLI)
- Gerar pacote .kpkg para a Koder Hub
- Definir target de export em build pipeline para .kpkg
Specification body
Koder Package Format — .kpkg Specification
Version: 0.1.0 — Draft
Status: Normative
1. Overview
.kpkg is the universal package format for the Koder Platform. A single .kpkg
file carries everything needed to install an application on any supported platform:
binaries for each target, metadata, icons, screenshots, and a bootstrap script that
works without the Koder Hub pre-installed.
The format serves two audiences:
- App developers — produce one artifact per release, submitted to the Koder Hub
- End users — double-click or run to install on Linux, Windows, or macOS
.kpkg is also the native format understood by the Koder Hub for silent installation,
version tracking, and rollback. Other formats (.deb, .rpm, .msix, .pkg) are
export targets produced by the kpkg CLI for distribution on external channels.
2. File Structure
A .kpkg file is a ZIP archive (PKZIP, deflate or stored) with a POSIX shell
bootstrap script prepended before the ZIP's PK\x03\x04 magic bytes. ZIP readers
ignore leading bytes, so the archive is valid on all tools. POSIX shells execute the
script and then exit before reaching the binary data.
[bootstrap script — POSIX sh, ends with `exit 0`]
[ZIP archive]
├── kpkg.toml # package manifest (required)
├── kpkg.sig # ed25519 detached signature over kpkg.toml + all payloads
├── icon.png # 512×512 RGBA app icon (required for Store listing)
├── icon@2x.png # 1024×1024 optional high-DPI icon
├── screenshots/ # optional, up to 8 files, max 3840×2160 PNG or JPEG
│ ├── 01.png
│ └── ...
├── linux-amd64/ # payload directory — one per supported platform
│ └── <entry-point> # executable (ELF binary or shell script)
├── linux-arm64/
├── win-x64/
│ └── <entry-point>.exe
├── macos-arm64/
│ └── <entry-point>.app/ # macOS .app bundle (directory)
├── macos-x64/
├── android/
│ └── app.apk
├── ios/
│ └── app.ipa
└── assets/ # optional shared assets (fonts, data, localizations)
Platform directories are optional — a package may target any subset of platforms.
A .kpkg with only linux-amd64/ and linux-arm64/ is valid.
3. Manifest — kpkg.toml
[package]
# Required fields
name = "my-app" # slug — lowercase, hyphens, no spaces
display = "My App" # human-readable name shown in the Store
version = "1.2.3" # SemVer 2.0 (no build metadata in Store key)
authors = ["Jane Doe <jane@example.com>"]
license = "MIT"
description = "One-line description shown in search results and in social-media share previews. Max 200 chars." # REQUIRED — see §3.1 below
# Optional but recommended
homepage = "https://myapp.example.com"
repository = "https://flow.koder.dev/MyOrg/my-app"
category = "productivity" # see §4 for valid values
tags = ["notes", "markdown", "editor"]
min_khub = "2.0.0" # minimum Koder Hub version required to install
[store]
# Koder Hub listing metadata
slug = "my-app" # unique Store identifier (defaults to package.name)
price = "free" # "free" | "paid:<USD cents>" | "freemium"
screenshots = ["screenshots/01.png", "screenshots/02.png"]
changelog = """
## 1.2.3
- Fixed crash on empty document
- Improved search performance
"""
[platforms]
# Declare which platforms this package supports and their entry points.
# Each key is a platform directory name; value is the executable path within it.
"linux-amd64" = "my-app"
"linux-arm64" = "my-app"
"win-x64" = "my-app.exe"
"macos-arm64" = "My App.app"
"macos-x64" = "My App.app"
"android" = "app.apk"
"ios" = "app.ipa"
[install]
# Installation behaviour — all fields optional, Koder Hub fills in defaults
data_dir = "{AppData}/my-app" # where user data lives; supports {AppData}, {Home}
config_dir = "{Config}/my-app"
cache_dir = "{Cache}/my-app"
launcher = true # create a launcher/shortcut in the OS app menu
autostart = false # start on login
icon = "icon-256.png" # REQUIRED — source icon file (path relative to kpkg.toml).
# kpkg build bundles it as icon.png inside the .kpkg.
# kpkg install places it in the OS icon theme so the
# launcher (.desktop / Start Menu / .app) shows correctly.
# Omit when the icon is already named icon.png alongside
# kpkg.toml. Supported: PNG (preferred), SVG.
# Recommended sizes: 256×256 or 512×512 px.
# Also consumed by the Hub OG image composer
# (see specs/landing-pages/packages.kmd).
[permissions]
# Declarative permissions — the Koder Hub may prompt the user before granting.
network = true # outbound internet access
filesystem = ["~/Documents/my-app"] # explicit paths; empty = no FS access beyond data_dir
notifications = true
camera = false
microphone = false
[source]
# Optional: source package manager integration (Koder Koda / kpkg deps)
# When present, `kpkg build` compiles from source before packaging.
lang = "go" # "go" | "dart" | "rust" | "koder" | ...
build_cmd = "go build -o linux-amd64/my-app ./cmd/my-app"
test_cmd = "go test ./..."
[dependencies]
# Runtime dependencies on other .kpkg packages (resolved by the Koder Hub)
# Format: slug = ">=version"
# "koder-runtime" = ">=1.0.0"
3.1. Required Fields (Hard Gate)
The following fields are required in every published .kpkg. The
kpkg build CLI MUST refuse to produce an artifact when any are missing,
empty, or malformed. The Hub registry MUST reject uploads that violate this
contract. The CI workflow generator (gen-release-workflows.py) MUST emit
a kicon validate-metadata step that fails the release on violation.
| Field | Constraint | Reason |
|---|---|---|
package.name |
non-empty slug, lowercase + hyphens | catalog key, OG title fallback |
package.display |
non-empty, ≤60 chars | shown in launcher and Hub UI |
package.version |
valid SemVer 2.0 | release ordering |
package.authors |
non-empty list | attribution + audit |
package.license |
SPDX identifier or "Proprietary" | legal compliance |
package.description |
non-empty, ≤200 chars | OG share preview, Hub catalog search snippet |
install.icon |
resolves to PNG/SVG ≥256×256 | launcher icon, Hub catalog tile, OG image composition |
Why this is a hard gate: without
descriptionandicon, the Hub backend cannot compose a valid OG image when the package page is shared on WhatsApp/Twitter/etc., and falls back to the generic Hub thumbnail. Seespecs/landing-pages/packages.kmdfor the social-share contract that consumes these fields.
4. Category Values
| Value | Description |
|---|---|
productivity |
Notes, documents, task management |
development |
Editors, terminals, dev tools, SDKs |
communication |
Messaging, email, video calls |
entertainment |
Games, media players, streaming |
education |
Learning, dictionaries, reference |
finance |
Banking, budgeting, invoicing |
health |
Fitness, medical, wellness |
graphics |
Image editors, 3D, design tools |
utilities |
System tools, file managers, automation |
security |
VPNs, password managers, encryption |
5. Bootstrap Script
The bootstrap script is prepended verbatim to every .kpkg file. Its job:
- Detect the current OS and architecture
- If the Koder Hub is installed → hand off to
koder-hub install "$0" - If not → extract the correct platform payload to a temp dir and run the entry point (effectively a minimal self-installer without the Store)
Reference implementation (produced by kpkg build):
#!/bin/sh
# kpkg bootstrap — generated by kpkg v0.1.0
# Do not edit — regenerated on every `kpkg build`
set -e
SELF="$(cd "$(dirname "$0")"; pwd)/$(basename "$0")"
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
case "$ARCH" in
x86_64|amd64) ARCH="amd64" ;;
aarch64|arm64) ARCH="arm64" ;;
esac
# Try Koder Hub first
if command -v koder-hub >/dev/null 2>&1; then
exec koder-hub install "$SELF"
fi
# Fallback: self-extract and run
TMPDIR="$(mktemp -d)"
trap 'rm -rf "$TMPDIR"' EXIT
unzip -q "$SELF" "${OS}-${ARCH}/*" -d "$TMPDIR" 2>/dev/null || {
echo "Unsupported platform: $OS/$ARCH" >&2
echo "Install Koder Hub from https://hub.koder.dev" >&2
exit 1
}
ENTRY="$(unzip -Z1 "$SELF" "${OS}-${ARCH}/*" 2>/dev/null | head -1 | sed "s|${OS}-${ARCH}/||")"
chmod +x "$TMPDIR/${OS}-${ARCH}/$ENTRY"
exec "$TMPDIR/${OS}-${ARCH}/$ENTRY" "$@"
exit 0
On Windows, the bootstrap is not executed (Windows does not run shell scripts on
double-click). The .kpkg file association registered by the Koder Hub installer
causes Windows to pass the file to koder-hub.exe install <path> automatically.
6. Signature (kpkg.sig)
Every .kpkg submitted to the Koder Hub must be signed with the developer's
ed25519 private key (managed by Koder ID / Koder Keys). The signature covers:
sig = ed25519_sign(private_key, sha256(kpkg.toml) || sha256(payload_1) || ... || sha256(payload_n))
Payloads are included in lexicographic order of their ZIP entry paths. The Koder Store verifies the signature against the developer's public key before installation. Unsigned packages are rejected by default; the user may override in Store settings.
7. Export Formats
The kpkg CLI can export a .kpkg to platform-native formats for distribution
outside the Koder Hub:
| Flag | Output | Tool required | Host |
|---|---|---|---|
--deb |
.deb (amd64, arm64) |
dpkg-deb |
Linux |
--rpm |
.rpm (x86_64, aarch64) |
rpmbuild |
Linux |
--msix |
.msix (x64) |
makemsix |
any |
--pkg |
.pkg + .app (arm64, x64) |
pkgbuild |
macOS only |
--appimage |
.AppImage (x86_64) |
appimagetool |
Linux |
--apk |
.apk (universal) |
Gradle | any |
Signature requirements for macOS (notarization) and Windows (Authenticode) are
the developer's responsibility; kpkg export --pkg produces an unsigned bundle.
8. Versioning
Versions follow SemVer 2.0. The Koder Hub sorts versions numerically.
Pre-release versions (1.2.3-beta.1) are accepted but not shown by default in
the Store's "stable" view.
9. File Size Limits
| Limit | Value |
|---|---|
Total .kpkg file |
4 GB |
| Single payload directory | 2 GB |
kpkg.toml |
64 KB |
icon.png |
2 MB |
| Per screenshot | 10 MB |
10. MIME Type and File Association
- MIME type:
application/vnd.koder.kpkg - File extension:
.kpkg - Magic bytes:
23 21(#!) at offset 0, followed by/bin/shor/bin/env
The Koder Hub registers the .kpkg file association on installation on all
supported desktop platforms (Linux via .desktop + xdg-mime, Windows via
registry, macOS via Info.plist).
References
specs/releases/packaging.kmddev/store