Koder Package Format (.kpkg)

kpkg specs/kpkg/format.kmd

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.

Quando esta spec se aplica

Todos os triggers

Corpo da especificação

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 description and icon, 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. See specs/landing-pages/packages.kmd for 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:

  1. Detect the current OS and architecture
  2. If the Koder Hub is installed → hand off to koder-hub install "$0"
  3. 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/sh or /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).

Referências