Koder Package Format (.kpkg)

mandatory

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.

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:

  • *pp developers*— produce one artifact per release, submitted to the Koder Hub
  • *nd 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 *IP 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 *equired*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 *G share preview* Hub catalog search snippet
install.icon resolves to PNG/SVG ≥256×256 launcher icon, Hub catalog tile, *G image composition*

*hy 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 WhatsAppTwitteretc., 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}

Source: ../home/koder/dev/koder/meta/docs/stack/specs/kpkg/format.kmd