Pkgs
A pkg (package) is a self-contained directory with a manifest.json plus whatever it contributes — a UI panel, a tool server, an engine adapter, a background worker, or Claude Code skills and commands. Everything in Ikenga beyond the bare window chrome is a pkg.
At boot, the shell’s kernel discovers installed pkgs, validates each manifest against the schema, and registers every block it declares with the matching registry (UI routes, MCP servers, sidecars, cron, settings, and more). The manifest is the contract. The source, build output, and README are yours.
All published pkgs ship Apache-2.0 and live in one canonical monorepo, ikenga-pkgs, under packages/<type>/<slug>/.
Archetypes
Section titled “Archetypes”Pick the smallest archetype that fits what your pkg contributes. A single pkg can combine several — the kernel walks whatever blocks are present and registers each.
| Archetype | What it contributes | Pick it when |
|---|---|---|
| UI iframe | A panel that renders your own HTML/React in the shell, served by the kernel’s in-process content server. | You’re shipping a mini-app, dashboard, form, or panel you control end to end and it’s happy inside an iframe. |
| UI webview | A native child webview (not an iframe). | You need to drive a third-party site that refuses iframe embedding (via CSP frame-ancestors or X-Frame-Options), or you want per-pkg cookie isolation that survives reinstall. |
| MCP server | Tools the AI engine can call, over the Model Context Protocol. | You’re surfacing capabilities for the agent to invoke — read data, hit an API, kick off a workflow. |
| Engine adapter | A new AI backend the shell can use as the chat engine. | You’re integrating a CLI-based AI engine (see Engines). |
| Sidecar | A supervised, long-running bundled binary. | You have a worker that doesn’t fit the MCP shape — a preview server, a render worker, a websocket client — and want explicit lifecycle control. |
| Skill-only | Claude Code skills, slash commands, and/or agents — no UI, no process. | The functionality is pure prompt and workflow. The simplest possible pkg. |
The manifest
Section titled “The manifest”Every pkg has a manifest.json at its root. A minimal UI-iframe manifest:
{ "id": "com.example.dashboard", "name": "Dashboard", "version": "0.1.0", "ikenga_api": "1", "kind": "embedded", "author": { "name": "Example", "key": "example" },
"ui": { "routes": [ { "path": "/", "kind": "iframe", "source": "dist/index.html" } ] }}Beyond ui, a manifest may declare any subset of mcp, sidecars, engine, skills, commands, agents, iyke, cron, settings, capabilities, and permissions. The ikenga_api field is the numeric host-API version your pkg targets (currently "1"); the host supports the current version and the one before it.
UI routes accept three kinds: "iframe", "webview", and "component" (the last is reserved for host-builtin React components — third-party component routes won’t mount).
Capabilities and permissions
Section titled “Capabilities and permissions”A pkg only gets what its manifest asks for.
-
capabilitiesare opt-in, host-resolved features. The two that exist today are Supabase (the shell threads credentials from its encrypted vault through the handshake at mount time, so you never bake keys into a build) and webview child windows (capabilities.webview.child_webviewsplus a declared list of cookie partitions). A"webview"route won’t mount unless the matching capability is declared. -
permissionsare scoped grants the kernel checks:shell.execute(which commands may be spawned),net(URL prefixes),fs.read/fs.write(path globs, which may use$pkg_data,$pkg_install,$home). Asking forfs.writeoutside your own$pkg_datatriggers the trust gate — that pkg won’t auto-trust on install, and the user is prompted to consent (the “share kola” ritual). A pkg with an empty permissions block and no sensitive capabilities auto-trusts.
The AppBridge handshake
Section titled “The AppBridge handshake”A UI-iframe pkg is an MCP App client. When the shell mounts your iframe, it performs an AppBridge handshake and delivers a hostContext — the current theme, host style variables, and (if you declared the capability and the vault is populated) Supabase credentials.
The rules that matter:
- Register your handlers before you connect — the host may emit notifications synchronously right after the initialize response.
- Handle
onhostcontextchangedidempotently: the shell re-emitshostContextwhenever the theme changes. - Because the handshake is async, you can’t construct a Supabase client at module-eval time — use a lazy getter that runs after
hostContextarrives. - Run standalone (outside the shell) and the handshake is skipped, so build a sensible fallback for local dev.
The handshake uses @modelcontextprotocol/ext-apps. The Build your first pkg tutorial walks the whole flow.
Lifecycle
Section titled “Lifecycle”| Phase | What happens |
|---|---|
| Install | ikenga add <pkg> resolves the pkg, validates its manifest, runs the trust check, and registers every declared block with the kernel. Auto-trusts if there are no sensitive permissions; otherwise prompts. |
| Boot | The kernel re-discovers installed pkgs and replays their registrations. Long-lived MCP servers and sidecars spawn here. |
| Update | ikenga update pulls a newer version through the same validate-then-register path. If a pkg gained sensitive permissions since last install, the user is re-prompted to consent. |
| Remove (Retire) | The kernel unregisters every block the pkg contributed. Skill-only pkgs also remove the content they copied into ~/.claude/. |
Long-lived MCP servers and sidecars run under a supervisor with a full state machine — Spawning → Running, auto-restart on crash, a 3-strikes-in-60s circuit breaker that parks a flapping process, and port-in-use detection. The shell can stream lifecycle events to the UI.
The two CLIs
Section titled “The two CLIs”| CLI | Job | Commands |
|---|---|---|
ikenga | Disk-side package manager — mutates what’s installed. | list, add, update, remove, dev <path> |
iyke | Runtime controller — drives a shell that’s already running over its localhost bridge. | navigate panes, switch modes, inspect state |
ikenga dev <path> is the developer loop: it symlinks a pkg into the running shell, auto-trusts the source, and hot-reloads on manifest changes — no shell restart. Iframe code changes flow through your dev server’s HMR; sidecar and MCP source changes restart through the supervisor’s file watcher; Ctrl-C unregisters cleanly. See the Build your first pkg tutorial.
Where to go next
Section titled “Where to go next”- Build your first pkg → — scaffold, run hot-mounted, publish.
- Engines → — the engine-adapter archetype in depth.
- mcp-iyke → — driving a running shell as MCP tools.