vapi-bootstrap-framework
Scaffold a complete Vapi voice-agent project from a ROUGH_DRAFT.md spec. Generates package.json, .env.example, .gitignore, and the full TypeScript framework — scenario registry, per-language voice/transcriber stack, prompt composer, assistant builder, and an idempotent bootstrap script — plus one rough first-draft body.md per scenario. Drop this skill in any project's .cursor/skills/ folder (or ~/.cursor/skills/ for global use), write a ROUGH_DRAFT.md at the project root, name the skill, and `bun run bootstrap` puts the entire fleet live in dashboard.vapi.ai. Use when the user asks to scaffold or bootstrap Vapi voice agents from a rough draft, build a Vapi assistant fleet, or invokes this skill by name. Targets Bun + TypeScript + @vapi-ai/server-sdk.
What this skill does
# Vapi bootstrap framework
Scaffold an entire Vapi voice-agent project from a single `ROUGH_DRAFT.md` spec. Works in an empty folder or alongside an existing Bun + TypeScript project. One `bun run bootstrap` after this skill finishes puts the whole fleet live in `dashboard.vapi.ai`.
## What this skill produces
**Project scaffolding** (only created if absent — never overwritten):
- `package.json` — Bun + `@vapi-ai/server-sdk` + a `bootstrap` script
- `.env.example` — `VAPI_PRIVATE_KEY` placeholder + one slot per `(scenario × language)` tuple
- `.gitignore` — `node_modules`, `.env*.local`, OS junk
**Framework spine** (always created — architectural; every later change extends a slot here, never the spine itself):
- `src/assistants/languages.ts` — per-language voice + transcriber stack
- `src/assistants/loadPrompt.ts` — `loadPrompt(scenarioId, languageId)` composer
- `src/assistants/scenarios/index.ts` — the scenario registry
- `src/assistants/buildAssistant.ts` — composes a full Vapi assistant body for any `(scenarioId, languageId)` tuple
- `src/assistants/prompts/shared/preambles/es.md` — Spanish language preamble (extend with more languages later)
**Content** (always created — one set per scenario detected in the rough draft):
- `src/assistants/scenarios/<scenarioId>.ts` — id, name, language-keyed first message
- `src/assistants/prompts/<scenarioId>/body.md` — rough first-draft system prompt
- `src/assistants/prompts/<scenarioId>/off-topic-es.md` — Spanish redirect lines
**Entry point** (always created):
- `src/bootstrap.ts` — idempotent double loop over scenarios × languages
Defaults: languages `en` + `es`. Model `openai gpt-4.1` temperature `0.5`. Voices ElevenLabs `eleven_turbo_v2` (EN) / `eleven_multilingual_v2` (ES). Transcriber Deepgram `nova-3` (EN) / Soniox `stt-rt-v4` (ES). Override these only if the user explicitly asks.
## Workflow
1. **Check for `ROUGH_DRAFT.md`** at the project root.
- If present → continue with step 2.
- If missing → tell the user the skill needs a rough draft to work from. Offer the template under "ROUGH_DRAFT.md template" below; either paste it in for them to fill out, or wait for them to provide their own. Don't proceed past this step without one.
2. **Detect scenarios** — every `## N. <scenario name>` heading is one scenario. Derive a snake_case `scenarioId` from the name (e.g. "Lead Qualification & Screening" → `qualification`; "Appointment Scheduling" → `appointment`). When in doubt, pick the shortest unambiguous noun. Keep ids short — they become env var names.
3. **Extract the opening line** — under each scenario, look for `**On the page**`, `**Opening**`, `**Greeting**`, or the first quoted string in the section. That's `firstMessage.en` verbatim.
4. **Distill the flow** — `**What happens**` (or equivalent prose) becomes a rough first-draft `body.md`. Persona-driven, not a contract — no failure rules, no exact wordings, no scripted off-ramps yet. Keep it short.
5. **Scaffold the project root** — for each of `package.json`, `.env.example`, `.gitignore`: if the file is absent, create it from the template below. If `.env.example` already exists, append any missing `VAPI_ASSISTANT_<SCENARIO>_<LANG>` slots; never reorder or remove existing lines. If `package.json` exists, leave it alone but verify it has `@vapi-ai/server-sdk` in deps and a `bootstrap` script — tell the user if either is missing instead of editing.
6. **Generate the framework spine** — copy the five spine files verbatim from the templates below. They don't change between projects; only the scenario registry's imports do.
7. **Generate per-scenario files** — one `scenarios/<id>.ts`, one `prompts/<id>/body.md`, one `prompts/<id>/off-topic-es.md` per detected scenario.
8. **Wire up the registry** — `scenarios/index.ts` imports every scenario and exports the `SCENARIOS` const, `ScenarioId`, `SCENARIO_IDS`, `scenarioFor`.
9. **Write `src/bootstrap.ts`** with the double-loop template below.
10. **Translate first messages to Spanish** — natural Latin American Spanish, brand names untranslated.
11. **Tell the user how to run it** (see "Verification" below).
Do **not** add `clientTools` to scenarios in this skill — capture tools land in a follow-up step. Do **not** rewrite `body.md` as a contract here either — that's a separate step.
## File templates
Templates use these placeholders that you substitute per project:
- `<PROJECT_NAME>` — slug from the rough draft title (`# Rough draft — <X>` → snake/kebab-case of X). Fallback: `vapi-voice-agents`.
- `<SCENARIO_ID>` — snake_case scenario id (e.g. `qualification`)
- `<SCENARIO_NAME>` — human-readable name (e.g. `Lead Qualification`)
- `<FIRST_MESSAGE_EN>` — verbatim opening line from the rough draft
- `<FIRST_MESSAGE_ES>` — natural Spanish translation
- `<BODY_DRAFT>` — distilled rough first-draft prompt
- `<SCENARIO_IMPORTS>` — one `import { <id> } from "./<id>.ts";` per scenario, alphabetized
- `<SCENARIO_KEYS>` — comma-separated scenario ids inside `SCENARIOS = { ... }`
- `<ENV_ASSISTANT_SLOTS>` — one commented line per `(scenario × language)`: `# VAPI_ASSISTANT_<SCENARIO>_<LANG>=`
### `package.json` (only if absent)
```json
{
"name": "<PROJECT_NAME>",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"bootstrap": "bun run src/bootstrap.ts"
},
"dependencies": {
"@vapi-ai/server-sdk": "^0.5.2"
},
"devDependencies": {
"@types/bun": "^1.3.13",
"typescript": "^5.9.3"
},
"packageManager": "[email protected]"
}
```
### `.env.example` (create if absent; extend if present)
```dotenv
# Get this from https://dashboard.vapi.ai/keys
VAPI_PRIVATE_KEY=
# One slot per (scenario × language). First `bun run bootstrap` prints the
# ids; paste them here, then re-run for idempotent updates.
<ENV_ASSISTANT_SLOTS>
```
### `.gitignore` (only if absent)
```gitignore
# dependencies
node_modules
# env (local-only secrets)
.env*.local
# os junk
.DS_Store
# bun
*.tsbuildinfo
```
### `src/assistants/languages.ts`
```ts
/**
* Per-language voice + transcriber stack. Adding a 3rd language is one
* entry in each record below.
*/
import type { LanguageId } from "./loadPrompt.ts";
export type { LanguageId };
interface VoiceConfig {
provider: "11labs";
model: string;
voiceId: string;
}
interface TranscriberConfig {
provider: "deepgram" | "soniox";
model: string;
language: string;
}
const VOICE_BY_LANGUAGE: Record<LanguageId, VoiceConfig> = {
en: {
provider: "11labs",
model: "eleven_turbo_v2",
voiceId: "ZoiZ8fuDWInAcwPXaVeq",
},
es: {
provider: "11labs",
model: "eleven_multilingual_v2",
voiceId: "JYyJjNPfmNJdaby8LdZs",
},
};
const TRANSCRIBER_BY_LANGUAGE: Record<LanguageId, TranscriberConfig> = {
en: { provider: "deepgram", model: "nova-3", language: "en" },
es: { provider: "soniox", model: "stt-rt-v4", language: "es" },
};
export const voiceFor = (languageId: LanguageId): VoiceConfig =>
VOICE_BY_LANGUAGE[languageId];
export const transcriberFor = (languageId: LanguageId): TranscriberConfig =>
TRANSCRIBER_BY_LANGUAGE[languageId];
```
### `src/assistants/loadPrompt.ts`
```ts
/**
* EN returns body.md unchanged. ES prepends a Spanish preamble with the
* scenario's off-topic redirects spliced into {{OFF_TOPIC_LINES}}.
* One body.md per scenario drives every language variant.
*/
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
export type LanguageId = "en" | "es";
const PROMPT_DIR = resolve(import.meta.dir, "prompts");
const read = (relativePath: string): string =>
readFileSync(resolve(PROMPT_DIR, relativePath), "utf8");
export const loadPrompt = (
scenarioId: string,
languageId: LanguageId,
): string => {
const body = read(`${scenarioId}/body.md`);
if (languageId === "en") return body;
const offTopic = read(`${scenarioId}/off-topic-${languageId}.md`).trim();
const preamble = read(`shared/preambles/${languageId}.md`).replace(
"{{OFF_TOPIC_LINES}}",
oRelated in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.