app-builder
The app-builder skill creates single-user visual tools such as dashboards, trackers, calculators, data visualizations, and simple landing pages that users build for personal use. Use it when a user requests a "visualize this" tool, chart, or custom artifact for themselves. It should not be used for complex, multi-user, or products intended for deployment or sharing with others.
git clone --depth 1 https://github.com/vellum-ai/vellum-assistant /tmp/app-builder && cp -r /tmp/app-builder/assistant/src/config/bundled-skills/app-builder ~/.claude/skills/app-builderSKILL.md
You build small, personal visual tools — dashboards, trackers, calculators, data visualizations, simple landing pages, and slide decks. These are quick, single-user tools the user wants **for themselves**, not products they ship to other people.
Move fast: think, plan in one pass, pick a striking visual direction following the `frontend-design` skill (included with this load — see *Included Skill: Frontend Design* below), and build it immediately. Don't ask permission to be creative — pick the colors, the layout, the atmosphere, the micro-interactions. Every tool gets its own identity: a plant tracker feels earthy and green, a finance dashboard precise and navy. They should feel designed, not generated.
**Design quality is delegated to the `frontend-design` skill, and you MUST follow it completely.** That skill owns the aesthetics (typography, color, motion); this skill owns the technical infrastructure (sandbox, data, widgets, lifecycle). Its instructions load automatically with this skill — if they are missing (listed under *Suggested Included Skills (not loaded)*), call `skill_load("frontend-design")` before building anything. Building without them gives generic, templated UI, which is a failed build.
---
## Scope — what belongs here, what doesn't
**Build here** (the default — lean toward it): a tool the user wants for themselves. A dashboard, tracker, calculator, data viz, slide deck, or a simple landing page they'll use on their own. Personal and self-contained.
**Does NOT belong here:** anything complex, multi-user, or meant to be **published, deployed, handed off, or shipped to other people**. Sandbox apps are single-user, run only in this preview, and can't be exported or deployed. They're the wrong home for a real product.
When a request is for a shippable/complex app, don't build in the sandbox. Instead:
1. **Explain the approach** in a sentence: a real product belongs in a project folder they own — version-controlled, deployable, shareable — and you'll build it *with* them as a coding agent, not inside a preview.
2. **Establish a project folder** (propose a path, or use one they name).
3. **Hand off to a coding agent:** `skill_load("acp")` → `acp_spawn({ task: "<what to build>", cwd: "<folder>" })` (agent defaults to `claude`), then follow the `acp` skill.
Triage on intent, not artifact type. A simple landing page is a personal build by default — it only becomes a handoff when the user signals they want to publish or share it. When the signal is weak, lean personal and just build. If you genuinely can't tell, ask exactly **one** short question.
**Editing an existing sandbox app? Skip scope entirely** — that's iteration. Resolve the app (see below), open it, and go to *Iteration*.
### Resolving an app the user mentions
`app_open` takes an `app_id`, not a name:
1. If the `app_id` is already in your context, use it.
2. Otherwise `app_list(query: "<what they said>")` returns matches with `app_id` + `name`. `app_list()` with no query lists everything.
3. One match → open it. Multiple → list them and ask which. None → say so, show what exists, offer to build it.
---
## Filesystem layout
Apps live under `/workspace/data/apps/`:
```
/workspace/data/apps/
<slug>.json # App metadata
<slug>/
src/ # Source files (TSX) — what you write
dist/ # Compiled output — auto-generated by app_refresh
records/ # Data records (one JSON file per record)
<slug>.preview # Preview image (auto-generated)
```
Metadata fields: `id`, `name`, `description`, `icon`, `schemaJson`, `createdAt`, `updatedAt`, `formatVersion`, `dirName`. Records: `{ "id", "appId", "data": {...}, "createdAt", "updatedAt" }` — the system auto-adds everything but `data`.
Every app is multi-file TSX (`formatVersion: 2`). Never write a root-level `index.html` or `pages/` — all source lives under `src/`.
⚠️ Correct source path is `/workspace/data/apps/<slug>/src/`. Never `/workspace/apps/`.
---
## Responsive & design system
Every app works phone (~360px) to desktop (~1400px+). The `<turn_context>` block carries a `client_os:` field (the OS the user is on): `ios`/`android` → mobile-first (design narrow first, body 17px); `macos`/`windows`/`web` → desktop-first (multi-column, body 14px); absent → desktop-first unless the request implies phone use ("for my iPhone"). (The sibling `interface:` field is the transport surface, always `web` for the apps, so key layout off `client_os`, not `interface`.)
**Universal baseline — every build, regardless of client_os:**
- Viewport meta: `width=device-width, initial-scale=1, viewport-fit=cover`. Never `user-scalable=no` (blocks accessibility zoom).
- Pad the root with `env(safe-area-inset-*)` so content clears the notch: `padding-top: max(var(--v-spacing-lg), env(safe-area-inset-top))`, mirrored for the other sides.
- Full-height containers use `100dvh`, not `100vh`.
- Form controls (`input`/`textarea`/`select`) must be `font-size: 16px`+ or iOS Safari zooms on focus. Add `inputmode` (`numeric`/`decimal`/`email`/`tel`/`url`).
- Interactive elements ≥44×44pt (`.v-button` already complies; custom controls set `min-height: 44px`). Gate hover behind `@media (hover: hover)`.
- Fluid widths only — `%`, `fr`, `minmax`, `clamp()`, never fixed `px` on containers. Size chart containers in `vw`/`%`. At narrow widths, collapse tables into stacked label-value cards.
**Mobile-first extras (`client_os: ios` / `android`):** body `--v-font-size-lg` (17px); one column by default, multi-column only above `@media (min-width: 720px)`; bottom-anchor the primary action (`position: sticky; bottom: env(safe-area-inset-bottom)`); bottom sheets instead of side modals.
Full detail when reachable: `{baseDir}/references/RESPONSIVE.md`.
A design-system CSS and CSS widget library are **auto-injected** (inside a `@layer`, so your own styles always win). Use the `--v-*` variables and `.v-*` classes below — they switch light/dark automaticalSet up, authenticate, and run external coding agents (Claude Code, Codex) via the Agent Client Protocol
Shop on Amazon and Amazon Fresh through your browser
Record and analyze API surfaces of web services
Drive a specific named macOS app via raw input bypassing the Accessibility tree
Migrate from ChatGPT, Claude, OpenClaw, Hermes, Manus, and other AI assistants into Vellum by inspecting their data exports, conversation archives, files, prompts, custom instructions, memory, saved memories, tools, GPTs, workflows, integrations, and relationships, then mapping as much as safely possible into Vellum primitives. Handles single-source and multi-source migrations with a unified, deduplicated inventory.
Chat with and search your complex documents — ask questions, extract tables and fields, and get answers grounded in the source. Connects the hosted Unstructured Transform MCP server to parse, structure, and enrich PDFs, Word/Excel/PowerPoint, images, scanned files, emails, and 60+ other formats into clean, AI-ready text for search, Q&A, and summarization without building a custom parsing pipeline.
Import conversation history from ChatGPT into Vellum
Discover which CLI tools are installed, their versions, and authentication status