From 1274fbc03fc5a48644380595369f28e70c35bd78 Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Tue, 16 Jun 2026 15:33:21 -0700 Subject: [PATCH 1/2] feat: add runway api plugin --- plugins/runway-api/LICENSE.runway-api | 21 + plugins/runway-api/README.md | 36 + plugins/runway-api/assets/logo.png | Bin 0 -> 4846 bytes plugins/runway-api/index.ts | 25 + plugins/runway-api/package.json | 20 + plugins/runway-api/scripts/generate_audio.py | 130 ++++ plugins/runway-api/scripts/generate_image.py | 103 +++ plugins/runway-api/scripts/generate_video.py | 117 ++++ plugins/runway-api/scripts/get_task.py | 35 + plugins/runway-api/scripts/list_models.py | 55 ++ plugins/runway-api/scripts/runway_helpers.py | 396 +++++++++++ .../skills/rw-api-reference/SKILL.md | 423 +++++++++++ .../skills/rw-check-compatibility/SKILL.md | 116 +++ .../skills/rw-check-org-details/SKILL.md | 206 ++++++ .../skills/rw-fetch-api-reference/SKILL.md | 44 ++ .../skills/rw-generate-audio/SKILL.md | 78 +++ .../skills/rw-generate-image/SKILL.md | 90 +++ .../skills/rw-generate-video/SKILL.md | 117 ++++ .../skills/rw-integrate-audio/SKILL.md | 177 +++++ .../rw-integrate-character-embed/SKILL.md | 294 ++++++++ .../skills/rw-integrate-characters/SKILL.md | 466 ++++++++++++ .../skills/rw-integrate-documents/SKILL.md | 220 ++++++ .../skills/rw-integrate-image/SKILL.md | 285 ++++++++ .../skills/rw-integrate-uploads/SKILL.md | 299 ++++++++ .../skills/rw-integrate-video/SKILL.md | 430 ++++++++++++ .../skills/rw-recipe-full-setup/SKILL.md | 103 +++ .../skills/rw-setup-api-key/SKILL.md | 153 ++++ .../runway-api/skills/use-runway-api/AUTH.md | 46 ++ .../runway-api/skills/use-runway-api/SKILL.md | 242 +++++++ .../use-runway-api/scripts/runway-api.mjs | 663 ++++++++++++++++++ 30 files changed, 5390 insertions(+) create mode 100644 plugins/runway-api/LICENSE.runway-api create mode 100644 plugins/runway-api/README.md create mode 100644 plugins/runway-api/assets/logo.png create mode 100644 plugins/runway-api/index.ts create mode 100644 plugins/runway-api/package.json create mode 100644 plugins/runway-api/scripts/generate_audio.py create mode 100644 plugins/runway-api/scripts/generate_image.py create mode 100644 plugins/runway-api/scripts/generate_video.py create mode 100644 plugins/runway-api/scripts/get_task.py create mode 100644 plugins/runway-api/scripts/list_models.py create mode 100644 plugins/runway-api/scripts/runway_helpers.py create mode 100644 plugins/runway-api/skills/rw-api-reference/SKILL.md create mode 100644 plugins/runway-api/skills/rw-check-compatibility/SKILL.md create mode 100644 plugins/runway-api/skills/rw-check-org-details/SKILL.md create mode 100644 plugins/runway-api/skills/rw-fetch-api-reference/SKILL.md create mode 100644 plugins/runway-api/skills/rw-generate-audio/SKILL.md create mode 100644 plugins/runway-api/skills/rw-generate-image/SKILL.md create mode 100644 plugins/runway-api/skills/rw-generate-video/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-audio/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-character-embed/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-characters/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-documents/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-image/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-uploads/SKILL.md create mode 100644 plugins/runway-api/skills/rw-integrate-video/SKILL.md create mode 100644 plugins/runway-api/skills/rw-recipe-full-setup/SKILL.md create mode 100644 plugins/runway-api/skills/rw-setup-api-key/SKILL.md create mode 100644 plugins/runway-api/skills/use-runway-api/AUTH.md create mode 100644 plugins/runway-api/skills/use-runway-api/SKILL.md create mode 100644 plugins/runway-api/skills/use-runway-api/scripts/runway-api.mjs diff --git a/plugins/runway-api/LICENSE.runway-api b/plugins/runway-api/LICENSE.runway-api new file mode 100644 index 00000000..7aa33638 --- /dev/null +++ b/plugins/runway-api/LICENSE.runway-api @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 RunwayML, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/runway-api/README.md b/plugins/runway-api/README.md new file mode 100644 index 00000000..87f6b82b --- /dev/null +++ b/plugins/runway-api/README.md @@ -0,0 +1,36 @@ +# runway-api + +Runway API skills for Cline users building or operating media generation workflows. + +## What It Does + +This plugin bundles skills for two related workflows: + +- Generating media directly with Runway's API, including text/image/video generation, audio generation, uploads, organization details, and general API calls. +- Integrating Runway features into server-side apps, including compatibility checks, API key setup, video/image/audio endpoints, uploads, real-time avatar characters, document knowledge, and React avatar embeds. + +The plugin also includes the Python and Node helper scripts used by the direct-generation skills, plus a safety rule for paid API calls, media uploads, outbound URL fetches, and API-key handling. + +## Install + +```bash +cline plugin install runway-api +``` + +For local development from this repository: + +```bash +cline plugin install ./plugins/runway-api --cwd . +``` + +## Requirements + +- A Runway developer account with available credits. +- `RUNWAYML_API_SECRET` in the environment or a user-created local `.env` file when making API calls. +- `uv` for the bundled Python generation helper scripts. +- Node.js 20 or newer for the general `use-runway-api` helper script. +- A server-side app when using integration skills. API keys must not be exposed in frontend code. + +## Security Notes + +Runway operations can spend credits and may upload or generate sensitive media. Cline should confirm paid generation, uploads, organization/account actions, external media URLs, output locations, and production code changes before acting. diff --git a/plugins/runway-api/assets/logo.png b/plugins/runway-api/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9a4f1f6d306b9dde14193f316d8cfd94d526741e GIT binary patch literal 4846 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 PREREQUISITE: Run `rw-check-compatibility` first to ensure the project has server-side capability. + +Base URL: `https://api.dev.runwayml.com` + +All requests require these headers: +``` +Authorization: Bearer +X-Runway-Version: 2024-11-06 +``` + +--- + +## Models & Endpoints + +### Video Generation + +| Model | Endpoint | Input | Cost (credits/sec) | +|-------|----------|-------|---------------------| +| `gen4.5` | `POST /v1/image_to_video` or `POST /v1/text_to_video` | Text and/or Image | 12 | +| `gen4_turbo` | `POST /v1/image_to_video` | Image required | 5 | +| `gen4_aleph` | `POST /v1/video_to_video` | Video + Text/Image | 15 | +| `act_two` | `POST /v1/character_performance` | Image/Video | 5 | +| `veo3` | `POST /v1/image_to_video` or `POST /v1/text_to_video` | Text/Image | 40 | +| `veo3.1` | `POST /v1/image_to_video` or `POST /v1/text_to_video` | Text/Image | 20-40 | +| `veo3.1_fast` | `POST /v1/image_to_video` or `POST /v1/text_to_video` | Text/Image | 10-15 | +| `seedance2` | `POST /v1/text_to_video`, `POST /v1/image_to_video`, or `POST /v1/video_to_video` | Text, Image, and/or Video | 36 | + +Video duration: 2-15 seconds (model-dependent). Aspect ratios are pixel-based: `1280:720`, `720:1280`, `1104:832`, `960:960`, `832:1104`, `1584:672`, etc. + +Seedance 2 specifics: +- Modes: text-to-video, image-to-video (first/last frame or image reference), video-to-video +- Duration: required for TTV and ITV (in seconds) +- Aspect ratios (pixel-based): `1280:720`, `720:1280`, `960:960`, `1112:834`, `834:1112`, `1470:630`, `992:432`, `864:496`, `752:560`, `640:640`, `560:752`, `496:864` +- ITV supports two mutually exclusive modes: first/last frame (`promptImage` array with `position`) or image reference (`references` array) +- VTV input requirements: max 15 seconds, max 32 MB, min 720p resolution, MP4 recommended + +### Image Generation + +| Model | Endpoint | Cost (credits) | +|-------|----------|----------------| +| `gen4_image` | `POST /v1/text_to_image` | 5 (720p), 8 (1080p) | +| `gen4_image_turbo` | `POST /v1/text_to_image` | 2 | +| `gemini_2.5_flash` | `POST /v1/text_to_image` | 5 | + +### Audio Generation + +| Model | Endpoint | Use Case | Cost | +|-------|----------|----------|------| +| `eleven_multilingual_v2` | `POST /v1/text_to_speech` | Text to speech | 1 credit/50 chars | +| `eleven_text_to_sound_v2` | `POST /v1/sound_effect` | Sound effects | 1-2 credits | +| `eleven_voice_isolation` | `POST /v1/voice_isolation` | Isolate voice from audio | 1 credit/6 sec | +| `eleven_voice_dubbing` | `POST /v1/voice_dubbing` | Dub audio to other languages | 1 credit/2 sec | +| `eleven_multilingual_sts_v2` | `POST /v1/speech_to_speech` | Voice conversion | 1 credit/3 sec | + +### Characters (Real-Time Avatars) + +| Model | Description | Session Max Duration | +|-------|-------------|----------------------| +| `gwm1_avatars` | Real-time conversational avatars powered by GWM-1 | 5 minutes | + +Endpoints: + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `POST` | `/v1/avatars` | Create a new Avatar | +| `GET` | `/v1/avatars/{id}` | Retrieve an Avatar | +| `PATCH` | `/v1/avatars/{id}` | Update an Avatar (name, voice, personality, documentIds) | +| `DELETE` | `/v1/avatars/{id}` | Delete an Avatar | +| `POST` | `/v1/realtime_sessions` | Create a new real-time session | +| `GET` | `/v1/realtime_sessions/{id}` | Retrieve session status (poll until `READY`) | +| `POST` | `/v1/realtime_sessions/{id}/consume` | Consume session credentials for WebRTC (one-time use) | + +Avatar creation parameters: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `name` | string | Display name for the avatar | +| `referenceImage` | string | URL or `runway://` URI of the character image | +| `voice` | object | `{ type: 'runway-live-preset', presetId: 'clara' }` | +| `personality` | string | System prompt / personality instructions | +| `documentIds` | string[] | Optional. IDs of knowledge base documents to attach | + +Voice presets: `clara` (soft), `victoria` (firm), `vincent` (authoritative). Preview all at [dev.runwayml.com](https://dev.runwayml.com/). + +Session statuses: `NOT_READY` -> `READY` -> `RUNNING` -> `COMPLETED` (or `FAILED` / `CANCELLED`) + +### Documents (Knowledge Base) + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `POST` | `/v1/documents` | Create a document (plain text or Markdown) | +| `GET` | `/v1/documents/{id}` | Retrieve a document | +| `DELETE` | `/v1/documents/{id}` | Delete a document | + +Each Avatar supports up to 50,000 tokens of knowledge. Link documents to an Avatar via `client.avatars.update(id, { documentIds: [...] })`. + +--- + +## Request Body Reference (raw JSON) + +Use these when calling the API directly (e.g. through `use-runway-api`'s `request` command) rather than via an SDK. Only required + common fields shown - consult `rw-fetch-api-reference` for the full schema. + +### `POST /v1/text_to_image` + +```json +{ + "model": "gen4_image", + "promptText": "A serene Japanese garden with cherry blossoms", + "ratio": "1920:1080" +} +``` + +- `model`: `gen4_image` | `gen4_image_turbo` | `gemini_2.5_flash` (required) +- `promptText`: string, up to ~1000 chars (required) +- `ratio`: one of `1920:1080`, `1080:1920`, `1024:1024`, `1360:768`, `1080:1080`, `1168:880`, `1440:1080`, `1080:1440`, `1808:768`, `2112:912` (required; 720p or 1080p variants depending on model) +- `referenceImages`: optional `[{ "uri": "https://...", "tag": "MyTag" }]` - reference by `@MyTag` in `promptText` +- `seed`: optional integer for reproducibility + +### `POST /v1/text_to_video` + +```json +{ + "model": "gen4.5", + "promptText": "A golden retriever running through wildflowers at sunset", + "ratio": "1280:720", + "duration": 5 +} +``` + +- `model`: `gen4.5` | `veo3` | `veo3.1` | `veo3.1_fast` | `seedance2` (required) +- `duration`: integer seconds, 2-10 (required; model-specific valid values - e.g. veo3 only accepts 8) +- `ratio`: e.g. `1280:720`, `720:1280`, `1104:832`, `832:1104`, `960:960` (required) + +### `POST /v1/image_to_video` + +```json +{ + "model": "gen4.5", + "promptImage": "https://example.com/cover.jpg", + "promptText": "A slow dolly-in shot", + "ratio": "1280:720", + "duration": 5 +} +``` + +- `model`: `gen4.5` | `gen4_turbo` | `veo3` | `veo3.1` | `veo3.1_fast` | `seedance2` (required) +- `promptImage`: HTTPS URL, data URI, or `runway://` URI (required). Can also be `[{ "uri": "...", "position": "first" | "last" }]` for keyframes. +- `promptText`: optional for most models, required for `gen4_turbo` when no image motion is obvious + +### `POST /v1/video_to_video` + +```json +{ + "model": "gen4_aleph", + "videoUri": "https://example.com/source.mp4", + "promptText": "Change the season to winter with snowfall", + "ratio": "1280:720" +} +``` + +### `POST /v1/text_to_speech` + +```json +{ + "model": "eleven_multilingual_v2", + "promptText": "Hello, welcome to Runway.", + "voice": { "type": "runway-preset", "presetId": "Maya" } +} +``` + +- `voice`: `{ type: "runway-preset", presetId: "Maya" | "Noah" | "Leslie" | ... }` or a provider-specific voice object +- `languageCode`: optional ISO code (auto-detected by default) + +### `POST /v1/sound_effect` + +```json +{ + "model": "eleven_text_to_sound_v2", + "promptText": "Thunderclap followed by heavy rain", + "duration": 5 +} +``` + +### `POST /v1/voice_isolation` + +```json +{ + "model": "eleven_voice_isolation", + "audioUri": "https://example.com/noisy.mp3" +} +``` + +### `POST /v1/voice_dubbing` + +```json +{ + "model": "eleven_voice_dubbing", + "audioUri": "https://example.com/english.mp3", + "targetLang": "es" +} +``` + +### `POST /v1/speech_to_speech` + +```json +{ + "model": "eleven_multilingual_sts_v2", + "media": { "type": "audio", "uri": "https://example.com/source.mp3" }, + "voice": { "type": "runway-preset", "presetId": "Maya" } +} +``` + +### `POST /v1/avatars` + +```json +{ + "name": "Support Agent", + "referenceImage": "https://example.com/portrait.jpg", + "voice": { "type": "runway-live-preset", "presetId": "clara" }, + "personality": "You are a friendly support agent.", + "documentIds": [] +} +``` + +### `POST /v1/documents` + +```json +{ + "avatarId": "", + "name": "FAQ", + "content": "Q: What is your return policy?\nA: 30 days, no questions asked." +} +``` + +### `POST /v1/realtime_sessions` + +```json +{ + "avatarId": "" +} +``` + +--- + +### Management Endpoints + +| Method | Endpoint | Description | +|--------|----------|-------------| +| `GET` | `/v1/tasks/{id}` | Get task status and output | +| `DELETE` | `/v1/tasks/{id}` | Cancel/delete a task | +| `POST` | `/v1/uploads` | Create ephemeral upload | +| `GET` | `/v1/organization` | Organization info & credit balance | +| `POST` | `/v1/organization/usage` | Credit usage history (up to 90 days) | + +--- + +## Task Lifecycle + +All generation endpoints return a task object. The flow is: + +1. Submit - `POST /v1/` -> returns `{ "id": "task_xxx" }` +2. Poll - `GET /v1/tasks/{id}` -> returns task with `status` +3. Retrieve output - When `status === "SUCCEEDED"`, the `output` array contains signed URLs + +### Task Statuses + +| Status | Meaning | +|--------|---------| +| `PENDING` | Queued, waiting to start | +| `RUNNING` | Currently generating | +| `SUCCEEDED` | Complete - output URLs available | +| `FAILED` | Generation failed - check `failure` field | +| `THROTTLED` | Concurrency limit hit - auto-queued | + +### SDK Polling (Recommended) + +The SDKs provide a `waitForTaskOutput()` method that handles polling automatically: + +```javascript +// Node.js - polls until complete (default 10 min timeout) +const task = await client.imageToVideo.create({ + model: 'gen4.5', + promptImage: 'https://example.com/image.jpg', + promptText: 'A sunset timelapse', + ratio: '1280:720', + duration: 5 +}).waitForTaskOutput(); + +console.log(task.output); // Array of signed URLs +``` + +```python +# Python +task = client.image_to_video.create( + model='gen4.5', + prompt_image='https://example.com/image.jpg', + prompt_text='A sunset timelapse', + ratio='1280:720', + duration=5 +).wait_for_task_output() + +print(task.output) +``` + +### Manual Polling (REST) + +```javascript +async function pollTask(taskId) { + while (true) { + const response = await fetch(`https://api.dev.runwayml.com/v1/tasks/${taskId}`, { + headers: { + 'Authorization': `Bearer ${process.env.RUNWAYML_API_SECRET}`, + 'X-Runway-Version': '2024-11-06' + } + }); + const task = await response.json(); + + if (task.status === 'SUCCEEDED') return task; + if (task.status === 'FAILED') throw new Error(task.failure); + + await new Promise(r => setTimeout(r, 5000)); // poll every 5 seconds + } +} +``` + +--- + +## Output Handling + +- Successful tasks return an `output` array with signed URLs to generated content +- Output URLs expire within 24-48 hours +- Download and store outputs in your own storage - do not serve signed URLs to end users +- Video outputs are MP4, image outputs are PNG/JPEG + +--- + +## Input Requirements + +### Size Limits + +| Type | Via URL | Via Data URI | Via Upload | +|------|---------|-------------|------------| +| Image | 16 MB | 5 MB | 200 MB | +| Video | 32 MB | 16 MB | 200 MB | +| Audio | 32 MB | 16 MB | 200 MB | + +### Supported Formats + +- Images: JPEG, PNG, WebP (no GIF) +- Video codecs: H.264, H.265/HEVC, AV1, VP8/VP9, Apple ProRes, Theora +- Audio: MP3, AAC, FLAC, PCM, ALAC + +### URL Requirements + +If providing assets via URL: +- HTTPS only (no HTTP) +- Domain names only (no IP addresses) +- No redirects +- Must support HTTP HEAD requests +- Must return valid `Content-Type` and `Content-Length` headers +- Max URL length: 2,048 characters + +--- + +## Rate Limits & Tiers + +| Tier | Concurrency | Daily Gens | Monthly Cap | Unlock | +|------|-------------|------------|-------------|--------| +| 1 (default) | 1-2 | 50-200 | $100 | - | +| 2 | 3 | 500-1,000 | $500 | 1 day + $50 | +| 3 | 5 | 1,000-2,000 | $2,000 | 7 days + $100 | +| 4 | 10 | 5,000-10,000 | $20,000 | 14 days + $1,000 | +| 5 | 20 | 25,000-30,000 | $100,000 | 7 days + $5,000 | + +- No requests-per-minute limit - only daily generation quotas +- Exceeding concurrency -> `THROTTLED` status (auto-queued, not rejected) +- Exceeding daily limit -> `429 Too Many Requests` +- Daily limits use a rolling 24-hour window + +--- + +## Error Handling + +### HTTP Errors + +| Code | Meaning | Action | +|------|---------|--------| +| 400 | Input validation failure | Fix input, do not retry | +| 401 | Invalid API key | Check key, do not retry | +| 429 | Rate limited | Retry with exponential backoff + jitter | +| 502/503/504 | Server overload | Retry with exponential backoff + jitter | + +### Task Failure Codes + +| Code | Meaning | Retry? | +|------|---------|--------| +| `SAFETY.INPUT.*` | Input content moderation | No - not refundable | +| `SAFETY.OUTPUT.*` | Output content moderation | Yes - try different prompt | +| `INTERNAL.BAD_OUTPUT` | Quality issue | Yes | +| `ASSET.INVALID` | Bad input format | Fix input | +| `INTERNAL` | Server error | Yes | + +The SDKs handle retries for transient errors automatically. + +--- + +## Data URI Support + +Base64-encoded images can be passed instead of URLs: + +``` +data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA... +``` + +Useful for small images or when you don't want to host the file. Subject to the data URI size limits above. diff --git a/plugins/runway-api/skills/rw-check-compatibility/SKILL.md b/plugins/runway-api/skills/rw-check-compatibility/SKILL.md new file mode 100644 index 00000000..a613c4e0 --- /dev/null +++ b/plugins/runway-api/skills/rw-check-compatibility/SKILL.md @@ -0,0 +1,116 @@ +--- +name: rw-check-compatibility +description: "Analyze a user's codebase to verify it can use Runway's public API (server-side requirement)" +user-invocable: false +--- + +# Check Compatibility + +Analyze the user's project to determine whether it is compatible with Runway's public API. + +## Why This Matters + +Runway's public API requires server-side invocation. The API key must never be exposed in client-side code. Projects that are purely frontend (static HTML/JS, client-only SPAs without a backend) cannot safely call the API. + +## Analysis Steps + +### Step 1: Identify the Project Type + +Search the project root for these files to determine the stack: + +| File | Indicates | +|------|-----------| +| `package.json` | Node.js project | +| `requirements.txt`, `pyproject.toml`, `Pipfile`, `setup.py` | Python project | +| `go.mod` | Go project | +| `Cargo.toml` | Rust project | +| `pom.xml`, `build.gradle` | Java/Kotlin project | +| `Gemfile` | Ruby project | +| `composer.json` | PHP project | + +If none of these exist, flag the project as unknown and ask the user what language/runtime they're using. + +### Step 2: Check for Server-Side Capability + +Look for indicators of a server/backend: + +Node.js projects - check `package.json` dependencies for: +- `express`, `fastify`, `koa`, `hapi`, `nest`, `hono` -> HTTP server framework +- `next` -> Next.js (has API routes - compatible) +- `nuxt` -> Nuxt.js (has server routes - compatible) +- `remix` -> Remix (has loaders/actions - compatible) +- `@sveltejs/kit` -> SvelteKit (has server routes - compatible) +- `astro` -> Astro (has API endpoints if SSR enabled) + +Python projects - check for: +- `flask`, `django`, `fastapi`, `starlette`, `tornado`, `aiohttp`, `sanic` -> web server framework +- `streamlit`, `gradio` -> can make server-side calls + +Red flags (frontend-only): +- `package.json` with only `react`, `vue`, `svelte`, `angular` and NO server framework +- `vite.config.ts` or `webpack.config.js` with no server/SSR configuration +- Static site generators without server routes (e.g., plain Gatsby, plain Eleventy) +- `index.html` as the only entry point with inline `