[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83945":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":14,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":30,"readmeContent":31,"aiSummary":10,"trendingCount":15,"starSnapshotCount":15,"syncStatus":16,"lastSyncTime":32,"discoverSource":33},83945,"framedeck","kevinrss01\u002Fframedeck","kevinrss01","AI-powered video editor for natural-language timeline editing, captions, footage analysis, and cloud rendering.","https:\u002F\u002Fframedeck.ai",null,"TypeScript",53,17,1,0,2,4,3.77,false,"main",true,[23,24,25,26,27,28,29],"ai","nestjs","nextjs","rust","turborepo","typescript","video-editor","2026-06-12 02:04:36","\u003Cp align=\"center\">\n  \u003Cimg src=\".\u002Fapps\u002Ffrontend\u002Fpublic\u002Ficon.png\" alt=\"Framedeck icon\" width=\"96\" \u002F>\n\u003C\u002Fp>\n\n# Framedeck\n\nAI video editing software that turns natural language prompts into timeline edits: remove silences, add captions, analyze footage, prepare voiceovers, and render finished videos.\n\n![PNPM](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fpnpm-10.22.0-f69220?style=flat-square&logo=pnpm&logoColor=white)\n![TypeScript](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTypeScript-5.9-blue?style=flat-square&logo=typescript&logoColor=white)\n![Next.js](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNext.js-16-black?style=flat-square&logo=nextdotjs)\n![NestJS](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNestJS-11-e0234e?style=flat-square&logo=nestjs)\n![Rust](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FRust-Axum-b7410e?style=flat-square&logo=rust)\n\n[Apps](#apps) - [How it works](#how-it-works) - [Getting started](#getting-started) - [Development](#development) - [Project structure](#project-structure) - [Contributing](#contributing)\n\n## Overview\n\nFramedeck is a Turborepo monorepo for an AI-assisted video editor. The frontend hosts the editor and video compositions, the Nest server owns the typed API and AI tool orchestration, and the Rust media processor handles fast FFmpeg audio extraction for transcription.\n\nThe shared API contract lives in `packages\u002Fapi-types` and is the source of truth for both frontend hooks and server handlers through `ts-rest`.\n\n## Apps\n\n| App                                              | Purpose                                                                               | Local URL                                     |\n| ------------------------------------------------ | ------------------------------------------------------------------------------------- | --------------------------------------------- |\n| [`apps\u002Ffrontend`](.\u002Fapps\u002Ffrontend)               | Next.js editor UI, chat assistant, uploads, preview, and render client                | `http:\u002F\u002Fai-video-editor.localhost:1355`       |\n| [`apps\u002Fserver`](.\u002Fapps\u002Fserver)                   | Nest API, WebSocket gateway, AI Gateway tools, uploads, transcription, video analysis | `http:\u002F\u002Fapi-ai-video-editor.localhost:1355`   |\n| [`apps\u002Fmedia-processor`](.\u002Fapps\u002Fmedia-processor) | Rust\u002FAxum internal service for FFmpeg audio extraction from video files               | `http:\u002F\u002Fmedia-ai-video-editor.localhost:1355` |\n| [`packages\u002Fapi-types`](.\u002Fpackages\u002Fapi-types)     | Shared `ts-rest` contracts, Zod schemas, realtime constants, chat types               | n\u002Fa                                           |\n\n## How it works\n\n```mermaid\nflowchart LR\n  User[\"Editor user\"] --> Frontend[\"Next.js frontend\"]\n  Frontend --> Api[\"Nest API\"]\n  Frontend --> S3[\"S3 multipart upload\"]\n  Api --> ElevenLabs[\"ElevenLabs Scribe v2\"]\n  Api --> TwelveLabs[\"TwelveLabs\"]\n  Api --> Media[\"Rust media processor\"]\n  Media --> Api\n  Api --> Realtime[\"Socket.IO events\"]\n  Realtime --> Frontend\n  Frontend --> Render[\"Cloud video render\"]\n```\n\n### Upload and processing pipeline\n\n1. Frontend calls `POST \u002Fuploads\u002Finit` to create a multipart upload.\n2. Frontend calls `POST \u002Fuploads\u002F:uploadId\u002Fsign-parts` to sign upload chunks.\n3. Browser uploads directly to S3 with `directS3Upload()`.\n4. Frontend calls `POST \u002Fuploads\u002F:uploadId\u002Fcomplete`.\n5. Server starts ElevenLabs Scribe v2 transcription and TwelveLabs video analysis in the background.\n6. WebSocket events update the editor when transcription or video analysis finishes.\n\nAsset status flows through `pending-upload`, `uploading`, `transcribing`, `ready`, and `error`.\n\n### Agent-driven editor\n\nThe chat assistant streams through the server-side AI Gateway. Tools from `ToolsService` emit realtime start\u002Fprogress\u002Fresult events, and frontend editor bridge handlers apply validated edits back to the timeline.\n\n## Getting started\n\n### Prerequisites\n\n- Node.js LTS\n- PNPM `10.22.0`\n- Rust toolchain and Cargo\n- FFmpeg\n- AWS S3 credentials for uploads and cloud renders\n- API keys for the AI\u002Fmedia providers you use: OpenAI or compatible API, ElevenLabs, TwelveLabs, Deepgram\n\n> [!IMPORTANT]\n> Copy each app's `.env.example` into a local `.env` before running the full stack. The root does not own a single combined env file.\n\n### Install\n\n```bash\npnpm install\n```\n\n### Run everything\n\n```bash\npnpm dev\n```\n\nWith portless enabled, the public dev URLs are stable:\n\n- Frontend: `http:\u002F\u002Fai-video-editor.localhost:1355`\n- Backend: `http:\u002F\u002Fapi-ai-video-editor.localhost:1355`\n- Media processor: `http:\u002F\u002Fmedia-ai-video-editor.localhost:1355`\n\nTo use direct app ports from local env files instead:\n\n```bash\npnpm dev:direct\n```\n\n## Development\n\n| Command                             | Description                                 |\n| ----------------------------------- | ------------------------------------------- |\n| `pnpm dev`                          | Run all apps through Turborepo and portless |\n| `pnpm dev:direct`                   | Run all apps without portless               |\n| `pnpm --filter frontend dev`        | Run only the Next.js app                    |\n| `pnpm --filter server dev`          | Run only the Nest API                       |\n| `pnpm --filter media-processor dev` | Run only the Rust media processor           |\n| `pnpm --filter frontend exec tsc`   | Typecheck frontend                          |\n| `pnpm --filter server exec tsc`     | Typecheck server                            |\n| `pnpm --filter api-types build`     | Build shared API types                      |\n| `pnpm build`                        | Build all apps and packages                 |\n| `pnpm portless:list`                | Show active portless routes                 |\n\n## Project structure\n\n```text\napps\u002F\n├── frontend\u002F          # Next.js 16, React 19, Tailwind, shadcn, Zustand, video UI\n├── server\u002F            # NestJS 11, AI SDK, Socket.IO, S3, ElevenLabs Scribe v2, TwelveLabs\n└── media-processor\u002F   # Rust\u002FAxum, FFmpeg extraction service\npackages\u002F\n└── api-types\u002F         # Shared ts-rest contracts, Zod schemas, realtime constants\n```\n\n## API contract workflow\n\nWhen adding or changing a route:\n\n1. Update `packages\u002Fapi-types\u002Fsrc\u002Findex.ts`.\n2. Bind the route in the server with `@TsRestHandler(apiContracts.\u003Crouter>.\u003Cendpoint>)`.\n3. Consume it in the frontend with the generated `api` client.\n\n> [!NOTE]\n> Avoid hardcoded backend URLs in the frontend. Use the shared `api` object and env-driven base URLs.\n\n## Useful docs\n\n- [`apps\u002Ffrontend\u002FREADME.md`](.\u002Fapps\u002Ffrontend\u002FREADME.md)\n- [`apps\u002Fserver\u002FREADME.md`](.\u002Fapps\u002Fserver\u002FREADME.md)\n- [`apps\u002Fmedia-processor\u002FREADME.md`](.\u002Fapps\u002Fmedia-processor\u002FREADME.md)\n- [`docs\u002Fsupabase`](.\u002Fdocs\u002Fsupabase)\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](.\u002FCONTRIBUTING.md) and [`SECURITY.md`](.\u002FSECURITY.md).\n","2026-06-11 04:11:53","CREATED_QUERY"]