---
name: hub-custom-apps
description: Build, package and publish custom apps for HUB.KI — single-file HTML apps that run in a sandboxed iframe inside the platform and talk to it through the @hub-ki/app-sdk bridge. Use when the user wants to create, extend, debug, package or publish a HUB.KI custom app, write or fix its manifest.json, or asks what such an app can and cannot do. Works from the live documentation at docs.hub.ki rather than from memory.
---

# HUB.KI custom apps

A custom app is one self-contained HTML file plus a `manifest.json`. HUB.KI serves it in a
sandboxed iframe; the app reaches the platform only through a message bridge, wrapped by the
`@hub-ki/app-sdk` package, and only within the scopes its manifest declares.

**The documentation at https://docs.hub.ki is the source of truth, and it changes.** This skill
deliberately contains no API details. Read the relevant page before you write code, and again
whenever you are unsure. Never invent SDK methods, manifest fields, scopes, limits or CLI flags:
if a page does not say it, it does not exist.

## 1. Read the docs first

1. Fetch the index: https://docs.hub.ki/llms.txt. It lists every page with a one-line summary
   and links to the **Markdown** version of each. The index is authoritative; if it lists pages
   that the table below does not, read those too.
2. Fetch the pages you need. For a new app that is at least Introduction, Quick start, SDK
   reference, Manifest and Publishing — Publishing holds the folder layout and what a version
   bump does to stored data, which shapes the design from day one. If you would rather load
   everything at once: https://docs.hub.ki/llms-full.txt.

| When you need to…                                                  | Read                                                                   |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| Understand what an app is, the sandbox, the Content Security Policy | https://docs.hub.ki/llms.mdx/custom-apps/content.md                    |
| Scaffold, run locally, build and package an app                    | https://docs.hub.ki/llms.mdx/custom-apps/quick-start/content.md        |
| Call the platform: storage, identity, events, AI, UI, the mock host | https://docs.hub.ki/llms.mdx/custom-apps/sdk/content.md                |
| Write or fix `manifest.json`, pick scopes, pass validation         | https://docs.hub.ki/llms.mdx/custom-apps/manifest/content.md           |
| Let the app talk to the user's own backend                         | https://docs.hub.ki/llms.mdx/custom-apps/backend/content.md            |
| Work without the SDK, or debug the raw message protocol            | https://docs.hub.ki/llms.mdx/custom-apps/bridge/content.md             |
| Upload to a source, understand syncing, ship an update             | https://docs.hub.ki/llms.mdx/custom-apps/publishing/content.md         |
| Explain what an administrator has to do                            | https://docs.hub.ki/llms.mdx/custom-apps/administration/content.md     |

If a fetch fails, say so and stop; do not fall back to guessing. Human-readable pages live at
the same paths without the `/llms.mdx` prefix and the `/content.md` suffix, for example
https://docs.hub.ki/custom-apps/manifest/ — link those when you point the user somewhere.

## 2. Work in this order

1. **Pin down the app.** What does it do, what data does it keep, does it need the user's
   identity, shared documents, AI, or a backend of its own? Each of those maps to a scope or a
   manifest field. Request the minimum; most scopes need an organization admin's approval
   before they work (Manifest). Settle two things with the user now, because they are painful
   to change later:
   - the **`appId` namespace**. Ask for it; the identifiers in the docs' examples are
     placeholders and must not be shipped.
   - **where data lives**. The docs describe more than one kind of storage with different
     lifetimes across app versions (SDK reference, Publishing). Pick deliberately and tell the
     user what survives an update and what does not.
2. **Check the sandbox before choosing libraries or assets.** The Introduction lists exactly
   what the Content Security Policy allows. Decide up front how you handle fonts, images, media,
   network calls, workers, WebAssembly and anything that relies on `eval`.
3. **Scaffold exactly as the Quick start describes**, including the registry setup for the SDK.
   The SDK install needs a GitHub token in the environment; never write a token into a file,
   and never print one. When you run scaffolding commands unattended, use the tool's
   non-interactive mode rather than answering prompts.
4. **Develop against the SDK's mock host** so the app runs outside HUB.KI (Quick start, SDK
   reference). Keep the mock limited to development builds, as the Quick start shows.
5. **Build to a single HTML file** and confirm nothing is loaded by URL. Search the built file
   for `src=`, `href=`, `url(`, `@import`, `import(` and `fetch(`, and account for every hit:
   each one is either inline data, a call the manifest covers, or something to remove. Build
   tools add helpers of their own; configure those away rather than explaining them.
6. **Package the folder and write the manifest.** Then check the manifest against every rule in
   the Manifest page's validation section, line by line. A manifest that fails validation is
   skipped at sync time without telling the developer why.
7. **Hand over publishing.** Uploading to a source is the developer's job (Publishing);
   registering the source, syncing, granting it to organizations and setting availability are
   an administrator's (Administration). Tell the user precisely what to ask for, and what the
   app will look like in the Marketplace at each stage.

## 3. Before you call it done

- The production build passes, and the artifact is one HTML file within the documented size limit.
- You have been honest about what was tested. The SDK's mock host covers development builds
  only. Unless the docs describe a way to run a production artifact outside HUB.KI, say plainly
  that it has not run against a real host, and list what the user should check after the first
  sync: that it loads, that each scope works once approved, that the theme follows the host.
- `artifactPath` names the file that is actually in the folder; `appId`, `slug`, `version` and
  `sdkVersion` follow the documented formats; an icon is set.
- Every scope and every `connectOrigins` entry is used by the code, and nothing the code calls
  is missing from the manifest.
- The app handles the host theme and locale if the docs describe how, and degrades sensibly
  when a scope has not been approved yet.
- For an update to an existing app: you have read what a version bump does to stored data and
  to organizations pinned to a version (Publishing), and told the user.
- You have told the user which docs pages you relied on.
