diff --git a/packages/video/.gitignore b/packages/video/.gitignore
new file mode 100644
index 0000000..a9a5b50
--- /dev/null
+++ b/packages/video/.gitignore
@@ -0,0 +1,8 @@
+# Rendered video outputs
+out/
+*.mp4
+*.webm
+*.mov
+
+# Remotion cache
+.remotion/
diff --git a/packages/video/package.json b/packages/video/package.json
index 49e111e..d414dfe 100644
--- a/packages/video/package.json
+++ b/packages/video/package.json
@@ -5,7 +5,8 @@
"description": "Marketing videos for TPMJS",
"scripts": {
"dev": "remotion studio",
- "render": "remotion render MarketingVideo out/marketing-video.mp4",
+ "render": "remotion render TPMJSExplainer out/explainer-video.mp4",
+ "render:features": "remotion render TPMJSFeatures out/features-video.mp4",
"upgrade": "remotion upgrade"
},
"dependencies": {
diff --git a/packages/video/src/FeaturesVideo.tsx b/packages/video/src/FeaturesVideo.tsx
new file mode 100644
index 0000000..5d9e938
--- /dev/null
+++ b/packages/video/src/FeaturesVideo.tsx
@@ -0,0 +1,55 @@
+import { AbsoluteFill, Sequence, useVideoConfig } from 'remotion';
+import { colors } from './design-tokens';
+
+// Scene imports
+import { FeaturesOpeningScene } from './scenes/features/FeaturesOpeningScene';
+import { ToolRegistryScene } from './scenes/features/ToolRegistryScene';
+import { OmegaAgentScene } from './scenes/features/OmegaAgentScene';
+import { CollectionsFeatureScene } from './scenes/features/CollectionsFeatureScene';
+import { CustomAgentsScene } from './scenes/features/CustomAgentsScene';
+import { MCPProtocolScene } from './scenes/features/MCPProtocolScene';
+import { SecureExecutionScene } from './scenes/features/SecureExecutionScene';
+import { TestScenariosScene } from './scenes/features/TestScenariosScene';
+import { LivingSkillsScene } from './scenes/features/LivingSkillsScene';
+import { DeveloperSDKScene } from './scenes/features/DeveloperSDKScene';
+import { FeaturesClosingScene } from './scenes/features/FeaturesClosingScene';
+
+/**
+ * TPMJS Features Showcase Video
+ * Total: 2700 frames @ 30fps = 90 seconds
+ *
+ * A punchy showcase of all 9 platform features
+ */
+export const FeaturesVideo = () => {
+ const { fps } = useVideoConfig();
+
+ // Scene timing (in seconds)
+ const scenes = [
+ { component: FeaturesOpeningScene, start: 0, duration: 6 },
+ { component: ToolRegistryScene, start: 6, duration: 9 },
+ { component: OmegaAgentScene, start: 15, duration: 9 },
+ { component: CollectionsFeatureScene, start: 24, duration: 8 },
+ { component: CustomAgentsScene, start: 32, duration: 8 },
+ { component: MCPProtocolScene, start: 40, duration: 9 },
+ { component: SecureExecutionScene, start: 49, duration: 8 },
+ { component: TestScenariosScene, start: 57, duration: 8 },
+ { component: LivingSkillsScene, start: 65, duration: 8 },
+ { component: DeveloperSDKScene, start: 73, duration: 9 },
+ { component: FeaturesClosingScene, start: 82, duration: 8 },
+ ];
+
+ return (
+
+ {scenes.map(({ component: Component, start, duration }, index) => (
+
+
+
+ ))}
+
+ );
+};
diff --git a/packages/video/src/Root.tsx b/packages/video/src/Root.tsx
index 2f1b3df..a7b661d 100644
--- a/packages/video/src/Root.tsx
+++ b/packages/video/src/Root.tsx
@@ -1,15 +1,26 @@
import { Composition } from 'remotion';
import { ExplainerVideo } from './ExplainerVideo';
+import { FeaturesVideo } from './FeaturesVideo';
export const RemotionRoot = () => {
return (
-
+ <>
+
+
+ >
);
};
diff --git a/packages/video/src/scenes/features/CollectionsFeatureScene.tsx b/packages/video/src/scenes/features/CollectionsFeatureScene.tsx
new file mode 100644
index 0000000..33ab429
--- /dev/null
+++ b/packages/video/src/scenes/features/CollectionsFeatureScene.tsx
@@ -0,0 +1,271 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 3: Collections (0:24 - 0:32)
+ * Curate tool sets for specific use cases
+ */
+
+const CollectionCard = ({
+ name,
+ toolCount,
+ category,
+ delay,
+ isActive = false,
+}: {
+ name: string;
+ toolCount: number;
+ category: string;
+ delay: number;
+ isActive?: boolean;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ return (
+
+
+
+ {name}
+
+
+ {category}
+
+
+
+
+ {Array.from({ length: Math.min(toolCount, 5) }).map((_, i) => (
+
+ ))}
+ {toolCount > 5 && (
+
+ +{toolCount - 5}
+
+ )}
+
+
+ {toolCount} tools
+
+
+
+ );
+};
+
+export const CollectionsFeatureScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const collections = [
+ { name: 'data-science-kit', toolCount: 12, category: 'analytics' },
+ { name: 'content-creation', toolCount: 8, category: 'marketing' },
+ { name: 'devops-automation', toolCount: 15, category: 'infra' },
+ ];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 📁
+
+
+
+ Feature 03
+
+
+ Collections
+
+
+
+ shareable
+
+
+
+ {/* Main content */}
+
+ {/* Left - Description */}
+
+
+ Curate tool sets
+
+ for specific{' '}
+ use cases
+
+
+ Add test scenarios to validate behavior.
+
+ Generate living documentation automatically.
+
+
+
+ {/* Right - Collection cards */}
+
+ {collections.map((collection, i) => (
+
+ ))}
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/CustomAgentsScene.tsx b/packages/video/src/scenes/features/CustomAgentsScene.tsx
new file mode 100644
index 0000000..0188e15
--- /dev/null
+++ b/packages/video/src/scenes/features/CustomAgentsScene.tsx
@@ -0,0 +1,268 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 4: Custom Agents (0:32 - 0:40)
+ * Build AI agents with your choice of LLM
+ */
+
+const AgentCard = ({
+ name,
+ model,
+ tools,
+ status,
+ delay,
+}: {
+ name: string;
+ model: string;
+ tools: number;
+ status: 'public' | 'private';
+ delay: number;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ return (
+
+
+
+ {name[0].toUpperCase()}
+
+
+
+ {name}
+
+
+ {model}
+
+
+
+
+
+
+ {tools} tools configured
+
+
+ {status}
+
+
+
+ );
+};
+
+export const CustomAgentsScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const agents = [
+ { name: 'Research Bot', model: 'claude-opus-4', tools: 8, status: 'public' as const },
+ { name: 'Code Review', model: 'gpt-4o', tools: 5, status: 'private' as const },
+ { name: 'Data Analyst', model: 'claude-sonnet-4', tools: 12, status: 'public' as const },
+ ];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 👤
+
+
+
+ Feature 04
+
+
+ Custom Agents
+
+
+
+ unlimited
+
+
+
+ {/* Tagline */}
+
+
+ Your LLM. Your prompts.
+
+ Your tools.
+
+
+
+ {/* Agent cards */}
+
+ {agents.map((agent, i) => (
+
+ ))}
+
+
+ {/* Bottom text */}
+
+
+ Share publicly or keep private — your choice
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/DeveloperSDKScene.tsx b/packages/video/src/scenes/features/DeveloperSDKScene.tsx
new file mode 100644
index 0000000..0aa2cbd
--- /dev/null
+++ b/packages/video/src/scenes/features/DeveloperSDKScene.tsx
@@ -0,0 +1,321 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 9: Developer SDK (1:13 - 1:22)
+ * Publish tools with one keyword, TypeScript support
+ */
+
+const CodeLine = ({
+ content,
+ indent = 0,
+ delay,
+ highlight = false,
+}: {
+ content: string;
+ indent?: number;
+ delay: number;
+ highlight?: boolean;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ return (
+
+ {content}
+
+ );
+};
+
+export const DeveloperSDKScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const codeLines = [
+ { content: '// package.json', indent: 0, highlight: false },
+ { content: '{', indent: 0, highlight: false },
+ { content: '"name": "my-awesome-tool",', indent: 1, highlight: false },
+ { content: '"keywords": ["tpmjs"],', indent: 1, highlight: true },
+ { content: '"tpmjs": {', indent: 1, highlight: true },
+ { content: '"tools": ["./src/tools.ts"]', indent: 2, highlight: true },
+ { content: '}', indent: 1, highlight: false },
+ { content: '}', indent: 0, highlight: false },
+ ];
+
+ const features = [
+ 'TypeScript support',
+ 'Vercel AI SDK integration',
+ 'Auto schema extraction',
+ 'Zero config publish',
+ ];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ {'>'}
+
+
+
+ Feature 09
+
+
+ Developer SDK
+
+
+
+ npm
+
+
+
+ {/* Main content */}
+
+ {/* Left - Code block */}
+
+
+
+ {codeLines.map((line, i) => (
+
+ ))}
+
+
+ {/* npm publish command */}
+
+ $
+
+ npm publish
+
+
+ → auto-discovered in minutes
+
+
+
+
+ {/* Right - Features */}
+
+
+ One keyword.
+
+ Instant discovery.
+
+
+
+ {features.map((feature, i) => {
+ const featureProgress = spring({
+ frame: frame - fps * 2 - i * 8,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ return (
+
+
+ ✓
+
+
+ {feature}
+
+
+ );
+ })}
+
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/FeaturesClosingScene.tsx b/packages/video/src/scenes/features/FeaturesClosingScene.tsx
new file mode 100644
index 0000000..010c2b9
--- /dev/null
+++ b/packages/video/src/scenes/features/FeaturesClosingScene.tsx
@@ -0,0 +1,208 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+ Easing,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Features Closing Scene (1:22 - 1:30)
+ * Call to action with tpmjs.com
+ */
+export const FeaturesClosingScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ // All features revealed
+ const gridProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ // URL animation
+ const urlProgress = spring({
+ frame: frame - fps * 1.5,
+ fps,
+ config: springConfigs.bouncy,
+ });
+
+ // CTA animation
+ const ctaProgress = spring({
+ frame: frame - fps * 3,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ const features = [
+ 'Tool Registry',
+ 'Omega Agent',
+ 'Collections',
+ 'Custom Agents',
+ 'MCP Protocol',
+ 'Secure Execution',
+ 'Test Scenarios',
+ 'Living Skills',
+ 'Developer SDK',
+ ];
+
+ // Pulsing glow
+ const glowIntensity = Math.sin(frame * 0.08) * 0.3 + 0.7;
+
+ return (
+
+ {/* Radial gradient background */}
+
+
+ {/* Features grid (small) */}
+
+ {features.map((feature, i) => (
+
+ {feature}
+
+ ))}
+
+
+ {/* Main CTA */}
+
+
+ Start building with AI tools
+
+
+ {/* URL box */}
+
+
+ {/* Action buttons */}
+
+
+ Try Omega Agent
+
+
+ Read the Docs
+
+
+
+
+ {/* Bottom tagline */}
+
+
+ The Package Manager for AI Tools
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/FeaturesOpeningScene.tsx b/packages/video/src/scenes/features/FeaturesOpeningScene.tsx
new file mode 100644
index 0000000..233fcf1
--- /dev/null
+++ b/packages/video/src/scenes/features/FeaturesOpeningScene.tsx
@@ -0,0 +1,160 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+ Easing,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Features Opening Scene (0:00 - 0:06)
+ * Bold intro with TPMJS branding and tagline
+ */
+export const FeaturesOpeningScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ // Logo animation
+ const logoScale = spring({
+ frame,
+ fps,
+ config: springConfigs.bouncy,
+ });
+
+ const logoRotate = interpolate(frame, [0, fps * 0.5], [-10, 0], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ easing: Easing.out(Easing.back(2)),
+ });
+
+ // Tagline animation
+ const taglineProgress = spring({
+ frame: frame - fps * 1,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ // Feature count animation
+ const countProgress = spring({
+ frame: frame - fps * 2,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ const featureCount = Math.floor(
+ interpolate(frame, [fps * 2, fps * 3.5], [0, 9], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ })
+ );
+
+ // Copper line sweep
+ const lineWidth = interpolate(frame, [fps * 3, fps * 5], [0, 100], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ easing: Easing.out(Easing.cubic),
+ });
+
+ return (
+
+ {/* Gradient overlay */}
+
+
+ {/* Main content */}
+
+ {/* Logo/Brand */}
+
+ tpmjs
+
+
+ {/* Tagline */}
+
+ The Package Manager for AI Tools
+
+
+ {/* Feature count */}
+
+
+ {featureCount}
+
+
+ Core Features
+
+
+
+
+ {/* Bottom copper line */}
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/LivingSkillsScene.tsx b/packages/video/src/scenes/features/LivingSkillsScene.tsx
new file mode 100644
index 0000000..bb82d3c
--- /dev/null
+++ b/packages/video/src/scenes/features/LivingSkillsScene.tsx
@@ -0,0 +1,311 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 8: Living Skills (1:05 - 1:13)
+ * Documentation that evolves from real usage
+ */
+
+const SkillNode = ({
+ label,
+ x,
+ y,
+ delay,
+ size = 'md',
+}: {
+ label: string;
+ x: number;
+ y: number;
+ delay: number;
+ size?: 'sm' | 'md' | 'lg';
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.bouncy,
+ });
+
+ const sizes = {
+ sm: { w: 100, h: 40, font: typography.fontSize.xs },
+ md: { w: 140, h: 50, font: typography.fontSize.sm },
+ lg: { w: 180, h: 60, font: typography.fontSize.base },
+ };
+
+ const s = sizes[size];
+
+ return (
+
+
+ {label}
+
+
+ );
+};
+
+export const LivingSkillsScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ // Skill nodes with positions
+ const skills = [
+ { label: 'API Design', x: 800, y: 300, size: 'lg' as const, delay: fps * 1 },
+ { label: 'Error Handling', x: 600, y: 200, size: 'md' as const, delay: fps * 1.5 },
+ { label: 'Rate Limits', x: 1000, y: 200, size: 'md' as const, delay: fps * 1.8 },
+ { label: 'Caching', x: 550, y: 400, size: 'sm' as const, delay: fps * 2.2 },
+ { label: 'Auth', x: 700, y: 450, size: 'sm' as const, delay: fps * 2.5 },
+ { label: 'Webhooks', x: 950, y: 420, size: 'sm' as const, delay: fps * 2.8 },
+ { label: 'Pagination', x: 1100, y: 350, size: 'sm' as const, delay: fps * 3 },
+ ];
+
+ // Connection lines progress
+ const linesProgress = interpolate(frame, [fps * 3, fps * 5], [0, 1], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ });
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 💬
+
+
+
+ Feature 08
+
+
+ Living Skills
+
+
+
+ NEW
+
+
+
+ {/* Left description */}
+
+
+ Documentation that{' '}
+ evolves
+
+
+ Skills emerge from question patterns
+
+ and proven behaviors in real usage.
+
+
+
+ {/* Skill graph */}
+
+
+ {/* Skill nodes */}
+ {skills.map((skill) => (
+
+ ))}
+
+ {/* Bottom quote */}
+
+
+ "Skills, proven in the wild — not declared on paper"
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/MCPProtocolScene.tsx b/packages/video/src/scenes/features/MCPProtocolScene.tsx
new file mode 100644
index 0000000..53b2b05
--- /dev/null
+++ b/packages/video/src/scenes/features/MCPProtocolScene.tsx
@@ -0,0 +1,298 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 5: MCP Protocol (0:40 - 0:49)
+ * Works with Claude Desktop, Cursor, Windsurf, and any MCP client
+ */
+
+const ClientLogo = ({
+ name,
+ delay,
+ connected,
+}: {
+ name: string;
+ delay: number;
+ connected: boolean;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.bouncy,
+ });
+
+ const connectionProgress = spring({
+ frame: frame - delay - fps * 0.5,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ return (
+
+
+ {name[0]}
+
+
+ {name}
+
+ {connected && (
+
+ connected
+
+ )}
+
+ );
+};
+
+export const MCPProtocolScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const urlProgress = spring({
+ frame: frame - fps * 2,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ const clients = [
+ { name: 'Claude', connected: true },
+ { name: 'Cursor', connected: true },
+ { name: 'Windsurf', connected: true },
+ { name: 'Any MCP', connected: false },
+ ];
+
+ // Connection line animation
+ const lineProgress = interpolate(frame, [fps * 3, fps * 5], [0, 1], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ });
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 🔗
+
+
+
+ Feature 05
+
+
+ MCP Protocol
+
+
+
+ universal
+
+
+
+ {/* Center URL box */}
+
+
+
+ MCP Server URL
+
+
+ tpmjs.com/mcp
+
+
+
+
+ One URL. Instant access to all tools.
+
+
+
+ {/* Client logos */}
+
+ {clients.map((client, i) => (
+
+ ))}
+
+
+ {/* Connection lines */}
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/OmegaAgentScene.tsx b/packages/video/src/scenes/features/OmegaAgentScene.tsx
new file mode 100644
index 0000000..95edafc
--- /dev/null
+++ b/packages/video/src/scenes/features/OmegaAgentScene.tsx
@@ -0,0 +1,265 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 2: Omega Agent (0:15 - 0:24)
+ * AI that dynamically discovers and executes tools
+ */
+
+const Message = ({
+ role,
+ content,
+ delay,
+}: {
+ role: 'user' | 'assistant';
+ content: string;
+ delay: number;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ const isUser = role === 'user';
+
+ return (
+
+ );
+};
+
+const ToolPill = ({ name, delay }: { name: string; delay: number }) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.bouncy,
+ });
+
+ return (
+
+ );
+};
+
+export const OmegaAgentScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const selectedTools = ['web-scraper', 'sentiment', 'chart-gen'];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 🧩
+
+
+
+ Feature 02
+
+
+ Omega Agent
+
+
+
+ LIVE
+
+
+
+ {/* Chat interface */}
+
+
+
+ {/* Tool selection */}
+ {frame > fps * 1.5 && (
+
+
+ Auto-selected tools:
+
+
+ {selectedTools.map((tool, i) => (
+
+ ))}
+
+
+ )}
+
+
+
+
+ {/* Bottom highlight */}
+
+
+ No configuration needed.{' '}
+ Just ask.
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/SecureExecutionScene.tsx b/packages/video/src/scenes/features/SecureExecutionScene.tsx
new file mode 100644
index 0000000..dabadfe
--- /dev/null
+++ b/packages/video/src/scenes/features/SecureExecutionScene.tsx
@@ -0,0 +1,261 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 6: Secure Execution (0:49 - 0:57)
+ * Isolated sandboxes, rate limiting, encrypted credentials
+ */
+
+const SecurityLayer = ({
+ label,
+ icon,
+ delay,
+ index,
+}: {
+ label: string;
+ icon: string;
+ delay: number;
+ index: number;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ const width = 300 - index * 40;
+
+ return (
+
+ {icon}
+
+ {label}
+
+
+ );
+};
+
+export const SecureExecutionScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const shieldPulse = Math.sin(frame * 0.1) * 0.1 + 1;
+
+ const layers = [
+ { label: 'isolated sandbox', icon: '📦' },
+ { label: 'rate limiting', icon: '⏱️' },
+ { label: 'timeout handling', icon: '⚡' },
+ { label: 'encrypted at rest', icon: '🔐' },
+ ];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 🔑
+
+
+
+ Feature 06
+
+
+ Secure Execution
+
+
+
+ sandboxed
+
+
+
+ {/* Main content */}
+
+ {/* Left - Shield visualization */}
+
+
+ {/* Shield shape using CSS */}
+
+
+
+
+ {/* Right - Security layers */}
+
+ {layers.map((layer, i) => (
+
+ ))}
+
+
+
+ {/* Bottom text */}
+
+
+ Every tool runs in{' '}
+ complete isolation
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/TestScenariosScene.tsx b/packages/video/src/scenes/features/TestScenariosScene.tsx
new file mode 100644
index 0000000..73cf518
--- /dev/null
+++ b/packages/video/src/scenes/features/TestScenariosScene.tsx
@@ -0,0 +1,284 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 7: Test Scenarios (0:57 - 1:05)
+ * AI-generated test scenarios, pass rates, execution times
+ */
+
+const TestResult = ({
+ name,
+ status,
+ time,
+ delay,
+}: {
+ name: string;
+ status: 'pass' | 'fail' | 'running';
+ time?: string;
+ delay: number;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ const statusColors = {
+ pass: colors.status.success,
+ fail: colors.status.error,
+ running: colors.status.warning,
+ };
+
+ const statusIcons = {
+ pass: '✓',
+ fail: '✕',
+ running: '○',
+ };
+
+ return (
+
+
+ {statusIcons[status]}
+
+
+ {name}
+
+ {time && (
+
+ {time}
+
+ )}
+
+ );
+};
+
+export const TestScenariosScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ // Animated progress bar
+ const passRate = Math.min(
+ 94,
+ interpolate(frame, [fps * 2, fps * 4], [0, 94], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ })
+ );
+
+ const tests = [
+ { name: 'search_basic_query', status: 'pass' as const, time: '124ms' },
+ { name: 'search_with_filters', status: 'pass' as const, time: '89ms' },
+ { name: 'handle_empty_results', status: 'pass' as const, time: '45ms' },
+ { name: 'validate_api_key', status: 'fail' as const, time: '2.1s' },
+ { name: 'rate_limit_handling', status: 'pass' as const, time: '312ms' },
+ ];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ ✓
+
+
+
+ Feature 07
+
+
+ Test Scenarios
+
+
+
+ automated
+
+
+
+ {/* Main content */}
+
+ {/* Left - Pass rate */}
+
+
+ Pass Rate
+
+
+ {Math.floor(passRate)}%
+
+
+ {/* Progress bar */}
+
+
+
+ AI-generated tests validate
+
+ tool behavior automatically
+
+
+
+ {/* Right - Test results */}
+
+
+ Recent Tests
+
+ {tests.map((test, i) => (
+
+ ))}
+
+
+
+ );
+};
diff --git a/packages/video/src/scenes/features/ToolRegistryScene.tsx b/packages/video/src/scenes/features/ToolRegistryScene.tsx
new file mode 100644
index 0000000..b86e769
--- /dev/null
+++ b/packages/video/src/scenes/features/ToolRegistryScene.tsx
@@ -0,0 +1,286 @@
+import {
+ AbsoluteFill,
+ interpolate,
+ spring,
+ useCurrentFrame,
+ useVideoConfig,
+} from 'remotion';
+import { colors, typography, springConfigs } from '../../design-tokens';
+
+/**
+ * Feature 1: Tool Registry (0:06 - 0:15)
+ * Browse 1M+ AI tools from npm
+ */
+
+const ToolCard = ({
+ name,
+ downloads,
+ score,
+ delay,
+}: {
+ name: string;
+ downloads: string;
+ score: number;
+ delay: number;
+}) => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const progress = spring({
+ frame: frame - delay,
+ fps,
+ config: springConfigs.snappy,
+ });
+
+ return (
+
+
+
+ {name}
+
+
+ {downloads} downloads/mo
+
+
+
+
+ );
+};
+
+export const ToolRegistryScene = () => {
+ const frame = useCurrentFrame();
+ const { fps } = useVideoConfig();
+
+ const headerProgress = spring({
+ frame,
+ fps,
+ config: springConfigs.smooth,
+ });
+
+ const counterValue = Math.floor(
+ interpolate(frame, [fps * 0.5, fps * 3], [0, 1847293], {
+ extrapolateLeft: 'clamp',
+ extrapolateRight: 'clamp',
+ })
+ );
+
+ const tools = [
+ { name: '@anthropic/claude-sdk', downloads: '2.1M', score: 98 },
+ { name: 'firecrawl-aisdk', downloads: '847K', score: 95 },
+ { name: 'openai-tool-kit', downloads: '1.2M', score: 92 },
+ { name: 'langchain-tools', downloads: '654K', score: 89 },
+ ];
+
+ return (
+
+ {/* Feature badge */}
+
+
+ 🔍
+
+
+
+ Feature 01
+
+
+ Tool Registry
+
+
+
+
+ {/* Main content */}
+
+ {/* Left - Stats */}
+
+
+ {counterValue.toLocaleString()}+
+
+
+ AI tools auto-discovered from npm
+
+
+ {/* Badges */}
+
+ {['auto-sync', 'quality scores', 'health monitoring'].map((badge) => (
+
+ {badge}
+
+ ))}
+
+
+
+ {/* Right - Tool list */}
+
+ {tools.map((tool, i) => (
+
+ ))}
+
+
+
+ {/* Bottom tagline */}
+
+
+ Updated within minutes of npm publication
+
+
+
+ );
+};