node-app-build 6.5.0

Mini app developer CLI: scaffold, validate, package node-app-* Debian packages
# {{name}}

A **client-node stage app**, scaffolded by `node-app new --profile stage`.
Real, running code — not a stub — so you always have a working stage to
build on top of.

## What is a stage?

A stage is an app whose `manifest.json` declares a `ui` block with
`"kind": "stage"` and `"entry": "ui/dist/main.js"` (see `manifest.json` in
this folder). The host loads that compiled ES module and calls exactly two
exports:

- `mount(ctx: StageContext)` — called when the host navigates to this
  stage. Render into `ctx.host.root` (e.g. via
  `ctx.host.root.replaceChildren(el)`).
- `unmount()` — called before the host tears this stage down (navigation,
  hot-reload, shutdown). Undo everything `mount()` started.

`ctx` is the **only** platform surface a stage sees — no direct imports of
storage, network, or IPC. Its exact shape lives in
`ui/src/stage-context.ts` (re-exported from
`ui/src/vendor-node-client-rpc-stage-context.d.ts`); read that file to see
every member (`ctx.host.root`, `ctx.app.{name,version}`,
`ctx.invokeCapability<T>(name, payload)`, `ctx.query(name, params)`,
`ctx.liveQuery(name, params, listener)`, `ctx.events.subscribe/publish`,
`ctx.navigate(path)`) before you start editing.

## Where to start editing

Everything you need to change lives in **`ui/src/main.ts`**. It is
documentation by example:

1. Renders a titled card using the host shell's *original skin* classes
   (`.ui-card`, `.ui-eyebrow`, `.ui-title`) so it inherits the shell's look
   without shipping its own stylesheet.
2. Calls one capability (`core.metrics.latest`) via `ctx.invokeCapability`
   and renders a single value, with a friendly fallback on failure.
3. Includes a commented-out `ctx.liveQuery(...)` example for keeping a
   value live instead of fetching it once.
4. Cleans everything up in `unmount()`.

The rest of the files are boilerplate that rarely needs to change:

| Path | Purpose |
| --- | --- |
| `manifest.json` | App + stage registration (name, capabilities, UI entry point). |
| `src/index.ts` | Backend process: announces app metadata over the host IPC socket. |
| `ui/src/main.ts` | The stage UI itself — start here. |
| `ui/src/stage-context.ts` | Re-exports the `StageContext` type. |
| `ui/src/vendor-node-client-rpc-stage-context.d.ts` | The full `StageContext` type definition. |
| `ui/src/css-modules.d.ts` | TypeScript ambient type for `import css from "./x.css?raw"`. |
| `ui/scripts/stamp-integrity.mjs` | Writes `manifest.json`'s `ui.integrity` from the built `ui/dist/` after every `vite build`. |
| `ui/public/icon.svg` | Stage icon, copied to `ui/dist/icon.svg` on build. |

## Build

Backend and UI are two independent packages, each with its own
`bun install` and `bun run build`:

```bash
# from the app root
bun install && bun run build
```

The root `build` script chains both halves
(`bun build src/index.ts ... && cd ui && bun install && bun run build`), so
one command is enough. After it finishes:

- `dist/index.js` exists (backend).
- `ui/dist/main.js` (and `ui/dist/icon.svg`) exist (UI).
- `manifest.json`'s `ui.integrity` has been rewritten with the SHA-256 of
  every file in `ui/dist/`, so the manifest is valid and loadable as-is —
  `ui.integrity: {}` in the freshly-scaffolded manifest is a **placeholder**
  the build step above always fills in.

## Renaming this into your own stage

1. Update `name`, `description` in `manifest.json`, `package.json`, and
   `ui/package.json` if you didn't pass them to `node-app new`.
2. Update `ui.title` and `ui.nav.order` in `manifest.json`.
3. Adjust `requires` / `capabilities.requires` in `manifest.json` to match
   the capabilities your stage actually calls.
4. Edit `ui/src/main.ts`.
5. Re-run `bun run build` to re-stamp `ui.integrity`.

## Next steps

```bash
bun run build        # stamps manifest.json's ui.integrity (required first)
node-app audit       # check this app against the blueprint
node-app dev         # hot-reload dev loop
node-app package     # build a .deb (regenerates ui.integrity for the staged copy too)
```

Platform contributors run all published stages automatically from the platform
repository:

```bash
cd /path/to/node
node-app dev
node-app dev --client-node
```

Both commands use the same `platform-depends` source-resolution and staging
pipeline. No manual `make bootstrap-apps` step is required.