---
name: notis-apps
description: Design and package Notis apps. Use when users want an app that groups databases, routes, documents, automations, and skills into one installable Notis product.
---

# Notis Apps Skill

Use this skill when the user wants to create, edit, debug, or package a Notis app. Notis apps are Vite + React projects that deploy into the Notis Portal as installed apps for the current user or team.

Run the Notis CLI through NPX, for example `npx --package @notis_ai/cli@latest -- notis apps list`. Notis Desktop keeps the CLI auth profile current. This `notis-apps` skill is delivered through normal Notis skill sync for the signed-in user, alongside other curated skills.

## Platform Model

A Notis app is:

- a Vite + React project
- built with `@notis/sdk`
- configured through `notis.config.ts`
- packaged as an ES module bundle with `app.js`, `app.css`, and `manifest.json`
- rendered by the Notis Portal as a React component, not an iframe
- connected to Notis data and tools through the Portal-provided runtime and SDK hooks

Use the Notis CLI for the app lifecycle:

```bash
npx --package @notis_ai/cli@latest -- notis apps init
npx --package @notis_ai/cli@latest -- notis apps dev
npx --package @notis_ai/cli@latest -- notis apps build
npx --package @notis_ai/cli@latest -- notis apps screenshot
npx --package @notis_ai/cli@latest -- notis apps verify
npx --package @notis_ai/cli@latest -- notis apps create
npx --package @notis_ai/cli@latest -- notis apps link
npx --package @notis_ai/cli@latest -- notis apps pull
npx --package @notis_ai/cli@latest -- notis apps deploy
npx --package @notis_ai/cli@latest -- notis apps doctor
```

Use this command form everywhere:

```bash
npx --package @notis_ai/cli@latest -- notis apps ...
```

## Hard Rules

- Use React + Vite only. Do not use Next.js or a custom server for app projects.
- Build standard pages in `app/`. Do not write raw `views/<slug>/index.js` files.
- Keep navigation in `notis.config.ts` `routes`; each route needs a stable `slug`.
- Reference existing databases by slug in `notis.config.ts`; do not assume deploy creates databases automatically.
- Declare runtime tool access in `notis.config.ts` `tools`.
- Use `@notis/sdk` hooks instead of direct runtime access.
- Do not rely on `window.__NOTIS_RUNTIME__` or portal-owned DOM hooks.
- `npx --package @notis_ai/cli@latest -- notis apps deploy` updates an installed app. It does not publish to the public App Store.
- **Local development first; deploy is user-gated.** Iterate with `apps dev` and hand off for the **user** to test in the desktop **Local development** sidebar group. Do not run `apps create` / `apps deploy` on your own — a clean build/verify is not permission to deploy. Deploy only when the user has tested the local build and explicitly asks. Finishing a build without deploying is the expected outcome.
- **Installed app links are explicit.** A mounted dev session updates an installed app only when the checkout is linked by app id in `.notis/state.json` and the active dev-session registry mirrors that id. Name or slug matches may be suggestions, never update targets.
- Public or team App Store publishing is a Portal review flow.
- Use Phosphor icon names with the `phosphor:` prefix. Do not use emoji icons.
- Prefer scaffolded shadcn components and portal theme tokens over custom visual systems.

## App Workflow

1. Discover existing apps if needed:

```bash
npx --package @notis_ai/cli@latest -- notis apps list
```

2. Start from a scaffold or pull an existing app:

```bash
npx --package @notis_ai/cli@latest -- notis apps scaffolds list
npx --package @notis_ai/cli@latest -- notis apps init "My App"
npx --package @notis_ai/cli@latest -- notis apps pull <app-id> ./my-app
```

3. Install dependencies and develop. Keep `apps dev` running and **hand off to the user** — it is what surfaces the app in the desktop **Local development** sidebar group, and letting the user test there is the finish line for a build request:

```bash
npm install
npx --package @notis_ai/cli@latest -- notis apps dev
```

The desktop lists a dev app only if its session is in the per-workspace registry it polls: `<workspace>/.context/app-dev-sessions.json`. A current CLI auto-resolves the nearest `.context` registry; on older CLIs (or when launched outside the workspace), pass `NOTIS_APP_DEV_SESSIONS_FILE="$CONDUCTOR_WORKSPACE_PATH/.context/app-dev-sessions.json"`. After starting, confirm your app's `devSlug` is in that file with a fresh `lastHeartbeatAt` — if it isn't, the session landed in the global `~/.notis` registry and the app won't appear in the sidebar.

4. Build, capture listing screenshots, and verify (still local — this does not deploy):

```bash
npx --package @notis_ai/cli@latest -- notis apps build
npx --package @notis_ai/cli@latest -- notis apps screenshot
npx --package @notis_ai/cli@latest -- notis apps verify
```

`notis apps screenshot` renders each route in a headless harness and writes
`metadata/screenshot-N.png` (2000x1250, 16:10). Apps are icon-led like Raycast:
the app icon represents the app everywhere, so there is no cover image — only
these screenshots. Re-run after changing routes or UI; it overwrites the set and
drops stale files. Use `--routes home,history` to capture a subset.

5. **Only after the user has tested the local build and explicitly asks to deploy**, create or link the remote app, then deploy (this installs or updates the app on the user's account, where it appears under **Workspace** rather than Local development). After first install, keep `.notis/state.json` linked to that installed app id so future dev-session actions become **Update** instead of another **Install**:

```bash
npx --package @notis_ai/cli@latest -- notis apps create "My App" .
npx --package @notis_ai/cli@latest -- notis apps deploy
```

or:

```bash
npx --package @notis_ai/cli@latest -- notis apps link <app-id>
npx --package @notis_ai/cli@latest -- notis apps deploy
```

## App Structure

Expected project shape:

```text
notis.config.ts
vite.config.ts
app/
components/
metadata/          # screenshot-N.png only — generated by `notis apps screenshot`
.notis/output/
```

`metadata/` holds listing screenshots (`screenshot-1.png`, `screenshot-2.png`,
…). There is no `cover.png`: apps are icon-led like Raycast and the icon set in
`notis.config.ts` represents the app in the Store. Generate screenshots with
`notis apps screenshot` rather than authoring PNGs by hand.

`notis.config.ts` owns:

- app metadata: name, title, description, icon, accent, categories, tagline
- database slug references
- route definitions
- tool access

**Icon & accent.** Set `icon` to a `phosphor:<name>` value (e.g. `phosphor:dice-five`) or `metadata/icon.png`. When `icon` is unset, the app shows its **two-letter initials** everywhere (store, sidebar, app details). `accent` optionally pins the avatar color to one of `blue | violet | emerald | amber | rose | sky | fuchsia | teal`; when unset a stable color is derived automatically from the app id. Both flow from `notis.config.ts` through deploy onto the app row and listing, and can also be changed later with the `update_app` tool (`{ "icon": "phosphor:...", "accent": "emerald" }`).

Example:

```ts
import { defineNotisApp } from '@notis/sdk/config';

export default defineNotisApp({
  name: 'my-app',
  title: 'My App',
  description: 'A focused Notis app.',
  icon: 'phosphor:squares-four',
  accent: 'blue',
  databases: ['tasks'],
  routes: [
    {
      path: '/',
      slug: 'tasks',
      name: 'Tasks',
      icon: 'phosphor:check-square',
      default: true,
    },
  ],
  tools: ['LOCAL_NOTIS_DATABASE_QUERY', 'LOCAL_NOTIS_DATABASE_UPSERT_TASKS'],
});
```

## Runtime Usage

Use SDK hooks for data and tool access:

```tsx
import { useTool } from '@notis/sdk';

const query = useTool('LOCAL_NOTIS_DATABASE_QUERY');
```

Do not fetch Notis backend endpoints directly from app code unless the SDK explicitly requires it. The Portal provides authentication, runtime context, and route rendering.

## Troubleshooting

- If deploy fails with backend connectivity errors, run `npx --package @notis_ai/cli@latest -- notis apps doctor` and check the configured API base.
- If editing an existing app, use `npx --package @notis_ai/cli@latest -- notis apps pull <app-id>` when source snapshots are available.
- If the Portal shows a stale bundle, hard refresh the Portal or deploy a new version.
- If an app route fails to load, run `npx --package @notis_ai/cli@latest -- notis apps verify` and inspect `.notis/output/manifest.json`.
