mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-17 05:00:20 +00:00
chore(site): updated graph and wording
This commit is contained in:
parent
f79019e786
commit
65513f9086
9 changed files with 274 additions and 451 deletions
|
|
@ -21,7 +21,7 @@
|
||||||
{
|
{
|
||||||
"label": "Discord",
|
"label": "Discord",
|
||||||
"icon": "discord",
|
"icon": "discord",
|
||||||
"href": "https://rivet.dev/discord"
|
"href": "https://discord.gg/auCecybynK"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "GitHub",
|
"label": "GitHub",
|
||||||
|
|
|
||||||
BIN
frontend/packages/website/public/og.png
Normal file
BIN
frontend/packages/website/public/og.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 272 KiB |
|
|
@ -5,14 +5,13 @@ import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { ArrowRight, Terminal, Check } from 'lucide-react';
|
import { ArrowRight, Terminal, Check } from 'lucide-react';
|
||||||
|
|
||||||
const CTA_TITLES = [
|
const CTA_TITLES = [
|
||||||
'Control any coding agent with one SDK.',
|
'Run coding agents in sandboxes. Control them over HTTP.',
|
||||||
'Claude Code, Codex, OpenCode, Amp — unified.',
|
'A server inside your sandbox. An API for your app.',
|
||||||
'Swap agents without refactoring.',
|
'Claude Code, Codex, OpenCode, Amp — one HTTP API.',
|
||||||
'Universal events. Universal sessions.',
|
'Your app connects remotely. The coding agent runs isolated.',
|
||||||
'Stream, store, and replay agent transcripts.',
|
'Streaming events. Handling permissions. Managing sessions.',
|
||||||
'Human-in-the-loop, built in.',
|
'Install with curl. Connect over HTTP. Control any coding agent.',
|
||||||
'One SDK. Every coding agent.',
|
'The bridge between your app and sandboxed coding agents.',
|
||||||
'Deploy anywhere. Same API everywhere.',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function AnimatedCTATitle() {
|
function AnimatedCTATitle() {
|
||||||
|
|
@ -72,7 +71,6 @@ const CopyInstallButton = () => {
|
||||||
export function CTASection() {
|
export function CTASection() {
|
||||||
return (
|
return (
|
||||||
<section className='relative overflow-hidden border-t border-white/10 px-6 py-32 text-center'>
|
<section className='relative overflow-hidden border-t border-white/10 px-6 py-32 text-center'>
|
||||||
<div className='absolute inset-0 z-0 bg-gradient-to-b from-black to-zinc-900/50' />
|
|
||||||
<motion.div
|
<motion.div
|
||||||
animate={{ opacity: [0.3, 0.5, 0.3] }}
|
animate={{ opacity: [0.3, 0.5, 0.3] }}
|
||||||
transition={{ duration: 4, repeat: Infinity }}
|
transition={{ duration: 4, repeat: Infinity }}
|
||||||
|
|
@ -89,8 +87,8 @@ export function CTASection() {
|
||||||
transition={{ duration: 0.5, delay: 0.1 }}
|
transition={{ duration: 0.5, delay: 0.1 }}
|
||||||
className='mb-10 text-lg leading-relaxed text-zinc-400'
|
className='mb-10 text-lg leading-relaxed text-zinc-400'
|
||||||
>
|
>
|
||||||
Universal SDK for coding agents. <br className='hidden md:block' />
|
A server that runs inside isolated environments. <br className='hidden md:block' />
|
||||||
Control Claude Code, Codex, OpenCode, and Amp with one API.
|
Your app connects remotely to control any coding agent.
|
||||||
</motion.p>
|
</motion.p>
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, y: 20 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const faqs = [
|
||||||
{
|
{
|
||||||
question: 'Does this replace the Vercel AI SDK?',
|
question: 'Does this replace the Vercel AI SDK?',
|
||||||
answer:
|
answer:
|
||||||
"No, they're complementary. AI SDK is for building chat interfaces and calling LLMs. This SDK is for controlling autonomous coding agents that write code and run commands. Use AI SDK for your UI, use this when you need an agent to actually code.",
|
"No, they're complementary. AI SDK is for building chat interfaces and calling LLMs. This SDK is for controlling autonomous coding agents that write code and run commands. Use AI SDK for your UI, use this when you need a coding agent to actually code.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
question: 'Which coding agents are supported?',
|
question: 'Which coding agents are supported?',
|
||||||
|
|
@ -23,7 +23,7 @@ const faqs = [
|
||||||
{
|
{
|
||||||
question: 'Can I run this locally or does it require a sandbox provider?',
|
question: 'Can I run this locally or does it require a sandbox provider?',
|
||||||
answer:
|
answer:
|
||||||
"Both. Run locally for development, deploy to E2B, Daytona, or Vercel Sandboxes for production.",
|
'Both. Run locally for development, deploy to E2B, Daytona, or Vercel Sandboxes for production.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
question: 'Does it support [platform]?',
|
question: 'Does it support [platform]?',
|
||||||
|
|
@ -40,6 +40,21 @@ const faqs = [
|
||||||
answer:
|
answer:
|
||||||
"Rust gives us a single static binary, fast startup, and predictable memory usage. That makes it easy to run inside sandboxes or in CI without shipping a large runtime, such as Node.js.",
|
"Rust gives us a single static binary, fast startup, and predictable memory usage. That makes it easy to run inside sandboxes or in CI without shipping a large runtime, such as Node.js.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
question: "Why can't I just run coding agents locally?",
|
||||||
|
answer:
|
||||||
|
"You can for development. But in production, you need isolation. Coding agents execute arbitrary code — that can't happen on your servers. Sandboxes provide the isolation; this SDK provides the HTTP API to control coding agents remotely.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "How is this different from the agent's official SDK?",
|
||||||
|
answer:
|
||||||
|
"Official SDKs assume local execution. They spawn processes and expect interactive terminals. This SDK runs a server inside a sandbox that you connect to over HTTP — designed for remote control from the start.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Why not just SSH into the sandbox?',
|
||||||
|
answer:
|
||||||
|
"Coding agents expect interactive terminals with proper TTY handling. SSH with piped commands breaks tool confirmations, streaming output, and human-in-the-loop flows. The SDK handles all of this over a clean HTTP API.",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function FAQItem({ question, answer }: { question: string; answer: string }) {
|
function FAQItem({ question, answer }: { question: string; answer: string }) {
|
||||||
|
|
@ -84,7 +99,7 @@ export function FAQ() {
|
||||||
Frequently Asked Questions
|
Frequently Asked Questions
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-zinc-400">
|
<p className="text-zinc-400">
|
||||||
Common questions about the Coding Agent SDK.
|
Common questions about running agents in sandboxes.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,40 +2,6 @@
|
||||||
|
|
||||||
import { Workflow, Server, Database, Download, Globe } from 'lucide-react';
|
import { Workflow, Server, Database, Download, Globe } from 'lucide-react';
|
||||||
import { FeatureIcon } from './ui/FeatureIcon';
|
import { FeatureIcon } from './ui/FeatureIcon';
|
||||||
import { CopyButton } from './ui/CopyButton';
|
|
||||||
|
|
||||||
function AgentLogo({ name, color, src }: { name: string; color: string; src?: string }) {
|
|
||||||
return (
|
|
||||||
<div className="flex items-center gap-2 px-2 py-1 rounded bg-zinc-800/50 border border-white/5">
|
|
||||||
{src ? (
|
|
||||||
<img src={src} alt={name} className="w-4 h-4" style={{ filter: 'brightness(0) invert(1)' }} />
|
|
||||||
) : (
|
|
||||||
<div
|
|
||||||
className="w-4 h-4 rounded-sm flex items-center justify-center text-[8px] font-bold"
|
|
||||||
style={{ backgroundColor: `${color}20`, color }}
|
|
||||||
>
|
|
||||||
{name[0]}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<span className="text-[10px] text-zinc-400">{name}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ProviderLogo({ name, src }: { name: string; src?: string }) {
|
|
||||||
return (
|
|
||||||
<div className="flex items-center gap-2 px-2 py-1 rounded bg-zinc-800/50 border border-white/5">
|
|
||||||
{src ? (
|
|
||||||
<img src={src} alt={name} className="h-3 w-auto" style={{ filter: 'brightness(0) invert(1)' }} />
|
|
||||||
) : (
|
|
||||||
<div className="w-4 h-4 rounded-sm flex items-center justify-center text-[8px] font-bold bg-blue-500/20 text-blue-400">
|
|
||||||
D
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<span className="text-[10px] text-zinc-400">{name}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function FeatureGrid() {
|
export function FeatureGrid() {
|
||||||
return (
|
return (
|
||||||
|
|
@ -43,216 +9,90 @@ export function FeatureGrid() {
|
||||||
<div className="relative z-10 mx-auto max-w-7xl px-6">
|
<div className="relative z-10 mx-auto max-w-7xl px-6">
|
||||||
<div className="mb-16">
|
<div className="mb-16">
|
||||||
<h2 className="mb-4 text-3xl font-medium tracking-tight text-white md:text-5xl">
|
<h2 className="mb-4 text-3xl font-medium tracking-tight text-white md:text-5xl">
|
||||||
Full feature coverage.
|
How it works.
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-lg leading-relaxed text-zinc-400">
|
<p className="text-lg leading-relaxed text-zinc-400">
|
||||||
Available as an HTTP API or TypeScript SDK.
|
A server runs inside your sandbox. Your app connects over HTTP to control any coding agent.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-12 gap-4">
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||||
{/* Universal Agent API - Span 7 cols */}
|
{/* Universal Agent API - Span full width */}
|
||||||
<div className="col-span-12 lg:col-span-7 row-span-2 group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50 min-h-[400px]">
|
<div className="col-span-full group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
||||||
{/* Top Shine Highlight */}
|
{/* Top Shine Highlight */}
|
||||||
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
||||||
{/* Top Left Reflection/Glow */}
|
{/* Top Left Reflection/Glow */}
|
||||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,79,0,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,79,0,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
||||||
{/* Sharp Edge Highlight */}
|
{/* Sharp Edge Highlight */}
|
||||||
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-orange-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-orange-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
||||||
|
|
||||||
<div className="relative z-10 flex flex-col gap-4">
|
<div className="relative z-10 flex flex-col gap-4">
|
||||||
<div className="relative z-10 mb-2 flex items-center gap-3">
|
<div className="relative z-10 mb-2 flex items-center gap-3">
|
||||||
<FeatureIcon
|
<FeatureIcon
|
||||||
icon={Workflow}
|
icon={Workflow}
|
||||||
color="text-orange-400"
|
color="text-orange-400"
|
||||||
bgColor="bg-orange-500/10"
|
bgColor="bg-orange-500/10"
|
||||||
hoverBgColor="group-hover:bg-orange-500/20"
|
hoverBgColor="group-hover:bg-orange-500/20"
|
||||||
glowShadow="group-hover:shadow-[0_0_15px_rgba(255,79,0,0.5)]"
|
glowShadow="group-hover:shadow-[0_0_15px_rgba(255,79,0,0.5)]"
|
||||||
/>
|
/>
|
||||||
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Universal Agent API</h4>
|
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Universal Agent API</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-zinc-400 leading-relaxed text-lg max-w-md">
|
<p className="text-zinc-400 leading-relaxed text-lg max-w-2xl">
|
||||||
Claude Code, Codex, OpenCode, and Amp each have different APIs. We provide a single,
|
Claude Code, Codex, OpenCode, and Amp each have different APIs. We provide a single,
|
||||||
unified interface to control them all.
|
unified interface to control them all.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-auto relative z-10 bg-black/50 rounded-xl border border-white/5 p-5 overflow-hidden">
|
|
||||||
<div className="relative w-full aspect-[16/9] bg-[#050505] rounded-xl border border-white/10 overflow-hidden flex items-center justify-center">
|
|
||||||
{/* Subtle Background Grid */}
|
|
||||||
<div className="absolute inset-0 opacity-[0.03] pointer-events-none"
|
|
||||||
style={{ backgroundImage: 'linear-gradient(#fff 1px, transparent 1px), linear-gradient(90deg, #fff 1px, transparent 1px)', backgroundSize: '40px 40px' }} />
|
|
||||||
|
|
||||||
<svg viewBox="0 0 800 450" className="w-full h-full relative z-10">
|
|
||||||
<defs>
|
|
||||||
{/* Glow effect for active lines */}
|
|
||||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
|
||||||
<feGaussianBlur stdDeviation="2.5" result="blur" />
|
|
||||||
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
|
||||||
</filter>
|
|
||||||
</defs>
|
|
||||||
|
|
||||||
{/* Define curved paths with their respective brand colors */}
|
|
||||||
{(() => {
|
|
||||||
const curvedPaths = [
|
|
||||||
{ d: "M480 225 C540 225, 560 90, 620 90", label: "Claude", color: "#d97757" },
|
|
||||||
{ d: "M480 225 C540 225, 560 180, 620 180", label: "OpenAI", color: "#ffffff" },
|
|
||||||
{ d: "M480 225 C540 225, 560 270, 620 270", label: "OpenCode", color: "#10B981" },
|
|
||||||
{ d: "M480 225 C540 225, 560 360, 620 360", label: "Amp", color: "#F59E0B" }
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* Connection Lines */}
|
|
||||||
<g className="stroke-zinc-800" fill="none" strokeWidth="1.5">
|
|
||||||
{/* App -> Agent (Straight) */}
|
|
||||||
<path d="M180 225 L320 225" strokeDasharray="4 4" />
|
|
||||||
|
|
||||||
{/* Agent -> Providers (Curved) */}
|
|
||||||
{curvedPaths.map((path, i) => (
|
|
||||||
<path key={i} d={path.d} strokeDasharray="4 4" />
|
|
||||||
))}
|
|
||||||
</g>
|
|
||||||
|
|
||||||
{/* High-Performance Tracers */}
|
|
||||||
{/* Blue Tracer: App to SDK */}
|
|
||||||
<circle r="2.5" fill="#3B82F6" filter="url(#glow)">
|
|
||||||
<animateMotion path="M180 225 L320 225" dur="1.2s" repeatCount="indefinite" />
|
|
||||||
<animate attributeName="opacity" values="0;1;0" dur="1.2s" repeatCount="indefinite" />
|
|
||||||
</circle>
|
|
||||||
|
|
||||||
{/* Colored Tracers: SDK to Providers (following curves and matching brand colors) */}
|
|
||||||
{curvedPaths.map((path, i) => (
|
|
||||||
<circle key={i} r="2.5" fill={path.color} filter="url(#glow)">
|
|
||||||
<animateMotion path={path.d} dur="2s" begin={`${i * 0.4}s`} repeatCount="indefinite" />
|
|
||||||
<animate attributeName="opacity" values="0;1;0" dur="2s" begin={`${i * 0.4}s`} repeatCount="indefinite" />
|
|
||||||
</circle>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
})()}
|
|
||||||
|
|
||||||
{/* Nodes */}
|
|
||||||
{/* App Node */}
|
|
||||||
<g transform="translate(80, 190)">
|
|
||||||
<rect width="100" height="70" rx="12" fill="#111" stroke="#333" strokeWidth="1" />
|
|
||||||
<text x="50" y="42" fill="#999" textAnchor="middle" fontSize="14" fontWeight="600" className="uppercase tracking-tighter">Client App</text>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
{/* Central SDK Node */}
|
|
||||||
<g transform="translate(320, 180)">
|
|
||||||
<rect width="160" height="90" rx="14" fill="#18181B" stroke="#3B82F6" strokeWidth="2" />
|
|
||||||
<text x="80" y="52" fill="white" textAnchor="middle" fontSize="14" fontWeight="800">Sandbox Agent SDK</text>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
{/* Provider Nodes with Logos - Vertical Layout (centered) */}
|
|
||||||
{/* Claude */}
|
|
||||||
<g transform="translate(620, 50)">
|
|
||||||
<rect width="140" height="80" rx="10" fill="#111" stroke="#222" strokeWidth="1" />
|
|
||||||
<foreignObject x="0" y="10" width="140" height="32">
|
|
||||||
<div className="flex justify-center">
|
|
||||||
<img src="/logos/claude.svg" alt="Claude" className="h-8 w-8" />
|
|
||||||
</div>
|
|
||||||
</foreignObject>
|
|
||||||
<text x="70" y="62" fill="#999" textAnchor="middle" fontSize="11" fontWeight="600">Claude Code</text>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
{/* Codex */}
|
|
||||||
<g transform="translate(620, 140)">
|
|
||||||
<rect width="140" height="80" rx="10" fill="#111" stroke="#222" strokeWidth="1" />
|
|
||||||
<foreignObject x="0" y="10" width="140" height="32">
|
|
||||||
<div className="flex justify-center">
|
|
||||||
<svg className="h-8 w-8" viewBox="0 0 24 24" fill="none">
|
|
||||||
<path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" fill="#ffffff" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</foreignObject>
|
|
||||||
<text x="70" y="62" fill="#999" textAnchor="middle" fontSize="11" fontWeight="600">Codex</text>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
{/* OpenCode */}
|
|
||||||
<g transform="translate(620, 230)">
|
|
||||||
<rect width="140" height="80" rx="10" fill="#111" stroke="#222" strokeWidth="1" />
|
|
||||||
<foreignObject x="0" y="10" width="140" height="32">
|
|
||||||
<div className="flex justify-center">
|
|
||||||
<svg className="h-8 w-auto" viewBox="0 0 32 40" fill="none">
|
|
||||||
<path d="M24 32H8V16H24V32Z" fill="#4B4646"/>
|
|
||||||
<path d="M24 8H8V32H24V8ZM32 40H0V0H32V40Z" fill="#F1ECEC"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</foreignObject>
|
|
||||||
<text x="70" y="62" fill="#999" textAnchor="middle" fontSize="11" fontWeight="600">OpenCode</text>
|
|
||||||
</g>
|
|
||||||
|
|
||||||
{/* Amp */}
|
|
||||||
<g transform="translate(620, 320)">
|
|
||||||
<rect width="140" height="80" rx="10" fill="#111" stroke="#222" strokeWidth="1" />
|
|
||||||
<foreignObject x="0" y="12" width="140" height="28">
|
|
||||||
<div className="flex justify-center">
|
|
||||||
<img src="/logos/amp.svg" alt="Amp" className="h-6 w-auto" style={{ filter: 'brightness(0) invert(1)' }} />
|
|
||||||
</div>
|
|
||||||
</foreignObject>
|
|
||||||
<text x="70" y="62" fill="#999" textAnchor="middle" fontSize="11" fontWeight="600">Amp</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
{/* Streaming Events */}
|
||||||
{/* Server Mode - Span 5 cols */}
|
<div className="group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
||||||
<div className="col-span-12 lg:col-span-5 group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
|
||||||
{/* Top Shine Highlight */}
|
{/* Top Shine Highlight */}
|
||||||
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
||||||
{/* Top Left Reflection/Glow */}
|
{/* Top Left Reflection/Glow */}
|
||||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(34,197,94,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(34,197,94,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
||||||
{/* Sharp Edge Highlight */}
|
{/* Sharp Edge Highlight */}
|
||||||
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-green-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-green-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
||||||
|
|
||||||
<div className="relative z-10 mb-2 flex items-center gap-3">
|
<div className="relative z-10 mb-2 flex items-center gap-3">
|
||||||
<FeatureIcon
|
<FeatureIcon
|
||||||
icon={Server}
|
icon={Server}
|
||||||
color="text-green-400"
|
color="text-green-400"
|
||||||
bgColor="bg-green-500/10"
|
bgColor="bg-green-500/10"
|
||||||
hoverBgColor="group-hover:bg-green-500/20"
|
hoverBgColor="group-hover:bg-green-500/20"
|
||||||
glowShadow="group-hover:shadow-[0_0_15px_rgba(34,197,94,0.5)]"
|
glowShadow="group-hover:shadow-[0_0_15px_rgba(34,197,94,0.5)]"
|
||||||
/>
|
/>
|
||||||
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Server Mode</h4>
|
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Streaming Events</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-zinc-400 text-sm leading-relaxed">
|
<p className="text-zinc-400 text-sm leading-relaxed">
|
||||||
Run as an HTTP server anywhere. One command to bridge coding agents to your
|
Real-time SSE stream of everything the agent does. Persist to your storage, replay sessions, audit everything.
|
||||||
application.
|
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-auto relative z-10 p-3 bg-black/40 rounded-lg border border-white/5 font-mono text-xs text-green-400">
|
|
||||||
$ sandbox-agent server
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Universal Schema - Span 5 cols */}
|
{/* Handling Permissions */}
|
||||||
<div className="col-span-12 lg:col-span-5 group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
<div className="group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
||||||
{/* Top Shine Highlight */}
|
{/* Top Shine Highlight */}
|
||||||
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
||||||
{/* Top Left Reflection/Glow */}
|
{/* Top Left Reflection/Glow */}
|
||||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(168,85,247,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(168,85,247,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
||||||
{/* Sharp Edge Highlight */}
|
{/* Sharp Edge Highlight */}
|
||||||
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-purple-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-purple-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
||||||
|
|
||||||
<div className="relative z-10 mb-2 flex items-center gap-3">
|
<div className="relative z-10 mb-2 flex items-center gap-3">
|
||||||
<FeatureIcon
|
<FeatureIcon
|
||||||
icon={Database}
|
icon={Database}
|
||||||
color="text-purple-400"
|
color="text-purple-400"
|
||||||
bgColor="bg-purple-500/10"
|
bgColor="bg-purple-500/10"
|
||||||
hoverBgColor="group-hover:bg-purple-500/20"
|
hoverBgColor="group-hover:bg-purple-500/20"
|
||||||
glowShadow="group-hover:shadow-[0_0_15px_rgba(168,85,247,0.5)]"
|
glowShadow="group-hover:shadow-[0_0_15px_rgba(168,85,247,0.5)]"
|
||||||
/>
|
/>
|
||||||
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Universal Schema</h4>
|
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Handling Permissions</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-zinc-400 text-sm leading-relaxed">
|
<p className="text-zinc-400 text-sm leading-relaxed">
|
||||||
Standardized session schema that covers all features of all agents. Includes tool calls, permission requests, file edits, etc.
|
Approve or deny tool executions remotely over HTTP. Human-in-the-loop flows work seamlessly across the network.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Automatic Agent Installation - Span 8 cols */}
|
{/* Managing Sessions */}
|
||||||
<div className="col-span-12 md:col-span-8 group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
<div className="group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
||||||
{/* Top Shine Highlight */}
|
{/* Top Shine Highlight */}
|
||||||
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
||||||
{/* Top Left Reflection/Glow */}
|
{/* Top Left Reflection/Glow */}
|
||||||
|
|
@ -260,67 +100,43 @@ export function FeatureGrid() {
|
||||||
{/* Sharp Edge Highlight */}
|
{/* Sharp Edge Highlight */}
|
||||||
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-amber-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-amber-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
||||||
|
|
||||||
<div className="flex flex-col gap-4 relative z-10">
|
<div className="relative z-10 mb-2 flex items-center gap-3">
|
||||||
<div className="relative z-10 mb-2 flex items-center gap-3">
|
<FeatureIcon
|
||||||
<FeatureIcon
|
icon={Download}
|
||||||
icon={Download}
|
color="text-amber-400"
|
||||||
color="text-amber-400"
|
bgColor="bg-amber-500/10"
|
||||||
bgColor="bg-amber-500/10"
|
hoverBgColor="group-hover:bg-amber-500/20"
|
||||||
hoverBgColor="group-hover:bg-amber-500/20"
|
glowShadow="group-hover:shadow-[0_0_15px_rgba(245,158,11,0.5)]"
|
||||||
glowShadow="group-hover:shadow-[0_0_15px_rgba(245,158,11,0.5)]"
|
/>
|
||||||
/>
|
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Managing Sessions</h4>
|
||||||
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Automatic Agent Installation</h4>
|
|
||||||
</div>
|
|
||||||
<p className="text-zinc-400 text-sm leading-relaxed">
|
|
||||||
Agents are automatically installed on first use. No manual setup required.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-auto w-full relative z-10">
|
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
{['Claude Code', 'Codex', 'OpenCode', 'Amp'].map((agent) => (
|
|
||||||
<span
|
|
||||||
key={agent}
|
|
||||||
className="px-3 py-1.5 rounded-md bg-zinc-800/50 border border-white/5 text-xs font-mono text-zinc-400"
|
|
||||||
>
|
|
||||||
{agent}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text-zinc-400 text-sm leading-relaxed">
|
||||||
|
Create sessions, send messages, persist transcripts. Full session lifecycle management over HTTP.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Provider Agnostic - Span 4 cols */}
|
{/* Runs Inside Any Sandbox */}
|
||||||
<div className="col-span-12 md:col-span-4 group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
<div className="group relative flex flex-col gap-4 overflow-hidden rounded-2xl border border-white/5 bg-zinc-900/30 p-6 backdrop-blur-sm transition-colors duration-500 hover:bg-zinc-900/50">
|
||||||
{/* Top Shine Highlight */}
|
{/* Top Shine Highlight */}
|
||||||
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
<div className="absolute left-0 right-0 top-0 z-10 h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
|
||||||
{/* Top Left Reflection/Glow */}
|
{/* Top Left Reflection/Glow */}
|
||||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(59,130,246,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(59,130,246,0.15)_0%,transparent_50%)] opacity-0 transition-opacity duration-500 group-hover:opacity-100" />
|
||||||
{/* Sharp Edge Highlight */}
|
{/* Sharp Edge Highlight */}
|
||||||
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-blue-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
<div className="pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t border-blue-500 opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100" />
|
||||||
|
|
||||||
<div className="relative z-10 mb-2 flex items-center gap-3">
|
<div className="relative z-10 mb-2 flex items-center gap-3">
|
||||||
<FeatureIcon
|
<FeatureIcon
|
||||||
icon={Globe}
|
icon={Globe}
|
||||||
color="text-blue-400"
|
color="text-blue-400"
|
||||||
bgColor="bg-blue-500/10"
|
bgColor="bg-blue-500/10"
|
||||||
hoverBgColor="group-hover:bg-blue-500/20"
|
hoverBgColor="group-hover:bg-blue-500/20"
|
||||||
glowShadow="group-hover:shadow-[0_0_15px_rgba(59,130,246,0.5)]"
|
glowShadow="group-hover:shadow-[0_0_15px_rgba(59,130,246,0.5)]"
|
||||||
/>
|
/>
|
||||||
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Provider Agnostic</h4>
|
<h4 className="text-sm font-medium uppercase tracking-wider text-white">Runs Inside Any Sandbox</h4>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-zinc-500 text-sm leading-relaxed">
|
<p className="text-zinc-500 text-sm leading-relaxed">
|
||||||
Run locally, in Docker, or deploy to E2B, Daytona, and Vercel. Same SDK everywhere.
|
Lightweight static binary. One curl command to install inside E2B, Daytona, Vercel Sandboxes, or Docker.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-auto flex flex-wrap gap-2">
|
|
||||||
{['Local', 'Docker', 'E2B', 'Daytona', 'Vercel', 'Netlify'].map((provider) => (
|
|
||||||
<span
|
|
||||||
key={provider}
|
|
||||||
className="px-2 py-1 rounded-md bg-zinc-800/50 border border-white/5 text-[10px] font-mono text-zinc-400"
|
|
||||||
>
|
|
||||||
{provider}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,158 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { Terminal, Check, ArrowRight } from 'lucide-react';
|
import { Terminal, Check, ArrowRight } from 'lucide-react';
|
||||||
|
|
||||||
|
const ADAPTERS = [
|
||||||
|
{ label: 'Claude Code', color: '#D97757', x: 35, y: 70, logo: '/logos/claude.svg' },
|
||||||
|
{ label: 'Codex', color: '#10A37F', x: 185, y: 70, logo: 'openai' },
|
||||||
|
{ label: 'Amp', color: '#F59E0B', x: 35, y: 155, logo: '/logos/amp.svg' },
|
||||||
|
{ label: 'OpenCode', color: '#8B5CF6', x: 185, y: 155, logo: 'opencode' },
|
||||||
|
];
|
||||||
|
|
||||||
|
function UniversalAPIDiagram() {
|
||||||
|
const [activeIndex, setActiveIndex] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setActiveIndex((prev) => (prev + 1) % ADAPTERS.length);
|
||||||
|
}, 2000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative w-full aspect-[16/9] bg-[#050505] rounded-xl border border-white/10 overflow-hidden flex items-center justify-center">
|
||||||
|
{/* Background Grid */}
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 opacity-[0.03] pointer-events-none"
|
||||||
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
'linear-gradient(#fff 1px, transparent 1px), linear-gradient(90deg, #fff 1px, transparent 1px)',
|
||||||
|
backgroundSize: '40px 40px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Dynamic Background Glow */}
|
||||||
|
<div
|
||||||
|
className="absolute top-1/2 right-1/4 -translate-y-1/2 w-64 h-64 blur-[100px] rounded-full transition-colors duration-1000 opacity-20"
|
||||||
|
style={{ backgroundColor: ADAPTERS[activeIndex].color }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<svg viewBox="0 0 800 450" className="w-full h-full relative z-10">
|
||||||
|
<defs>
|
||||||
|
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||||
|
<feGaussianBlur stdDeviation="3" result="blur" />
|
||||||
|
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
{/* YOUR APP NODE */}
|
||||||
|
<g transform="translate(60, 175)">
|
||||||
|
<rect width="180" height="100" rx="16" fill="#0A0A0A" stroke="#333" strokeWidth="2" />
|
||||||
|
<text x="90" y="55" fill="#FFFFFF" textAnchor="middle" fontSize="20" fontWeight="700">
|
||||||
|
Your App
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
{/* HTTP/SSE LINE */}
|
||||||
|
<g>
|
||||||
|
<path d="M240 225 L360 225" stroke="#3B82F6" strokeWidth="2" strokeDasharray="6 4" fill="none" opacity="0.6" />
|
||||||
|
<circle r="4" fill="#3B82F6" filter="url(#glow)">
|
||||||
|
<animateMotion path="M240 225 L360 225" dur="2s" repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
<circle r="4" fill="#3B82F6" filter="url(#glow)">
|
||||||
|
<animateMotion path="M360 225 L240 225" dur="2s" repeatCount="indefinite" />
|
||||||
|
</circle>
|
||||||
|
|
||||||
|
<rect x="255" y="195" width="90" height="22" rx="11" fill="#111" stroke="#333" strokeWidth="1" />
|
||||||
|
<text x="300" y="210" fill="#60A5FA" textAnchor="middle" fontSize="11" fontWeight="800" fontFamily="monospace">
|
||||||
|
HTTP / SSE
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
{/* SANDBOX BOUNDARY */}
|
||||||
|
<g transform="translate(360, 45)">
|
||||||
|
<rect width="380" height="360" rx="24" fill="#080808" stroke="#333" strokeWidth="1.5" />
|
||||||
|
<rect width="380" height="45" rx="12" fill="rgba(255,255,255,0.02)" />
|
||||||
|
<text x="190" y="28" fill="#FFFFFF" textAnchor="middle" fontSize="14" fontWeight="800" letterSpacing="0.2em">
|
||||||
|
SANDBOX
|
||||||
|
</text>
|
||||||
|
|
||||||
|
{/* SANDBOX AGENT SDK */}
|
||||||
|
<g transform="translate(25, 65)">
|
||||||
|
<rect width="330" height="270" rx="20" fill="#0D0D0F" stroke="#3B82F6" strokeWidth="2" />
|
||||||
|
<text x="165" y="35" fill="#FFFFFF" textAnchor="middle" fontSize="18" fontWeight="800">
|
||||||
|
Sandbox Agent Server
|
||||||
|
</text>
|
||||||
|
<line x1="40" y1="50" x2="290" y2="50" stroke="#333" strokeWidth="1" />
|
||||||
|
|
||||||
|
{/* PROVIDER ADAPTERS */}
|
||||||
|
{ADAPTERS.map((p, i) => {
|
||||||
|
const isActive = i === activeIndex;
|
||||||
|
return (
|
||||||
|
<g key={i} transform={`translate(${p.x}, ${p.y})`}>
|
||||||
|
<rect
|
||||||
|
width="110"
|
||||||
|
height="65"
|
||||||
|
rx="12"
|
||||||
|
fill={isActive ? '#1A1A1E' : '#111'}
|
||||||
|
stroke={isActive ? p.color : '#333'}
|
||||||
|
strokeWidth={isActive ? 2 : 1.5}
|
||||||
|
/>
|
||||||
|
<foreignObject x="0" y="8" width="110" height="28">
|
||||||
|
<div className="flex justify-center" style={{ opacity: isActive ? 1 : 0.4 }}>
|
||||||
|
{p.logo === 'openai' ? (
|
||||||
|
<svg className="h-6 w-6" viewBox="0 0 24 24" fill="none">
|
||||||
|
<path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" fill="#ffffff" />
|
||||||
|
</svg>
|
||||||
|
) : p.logo === 'opencode' ? (
|
||||||
|
<svg className="h-6 w-auto" viewBox="0 0 32 40" fill="none">
|
||||||
|
<path d="M24 32H8V16H24V32Z" fill="#4B4646"/>
|
||||||
|
<path d="M24 8H8V32H24V8ZM32 40H0V0H32V40Z" fill="#F1ECEC"/>
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<img src={p.logo} alt={p.label} className="h-6 w-6" style={{ filter: 'brightness(0) invert(1)' }} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
<text
|
||||||
|
x="55"
|
||||||
|
y="52"
|
||||||
|
fill="#FFFFFF"
|
||||||
|
textAnchor="middle"
|
||||||
|
fontSize="11"
|
||||||
|
fontWeight="600"
|
||||||
|
opacity={isActive ? 1 : 0.4}
|
||||||
|
>
|
||||||
|
{p.label}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* Active Agent Label */}
|
||||||
|
<text
|
||||||
|
x="165"
|
||||||
|
y="250"
|
||||||
|
fill={ADAPTERS[activeIndex].color}
|
||||||
|
textAnchor="middle"
|
||||||
|
fontSize="10"
|
||||||
|
fontWeight="800"
|
||||||
|
fontFamily="monospace"
|
||||||
|
letterSpacing="0.1em"
|
||||||
|
>
|
||||||
|
CONNECTED TO {ADAPTERS[activeIndex].label.toUpperCase()}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CopyInstallButton = () => {
|
const CopyInstallButton = () => {
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
const installCommand = 'npx skills add https://sandboxagent.dev/docs';
|
const installCommand = 'SandboxAgent.connect({ endpoint: "..." })';
|
||||||
|
|
||||||
const handleCopy = async () => {
|
const handleCopy = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -35,11 +182,11 @@ export function Hero() {
|
||||||
<div className="flex flex-col lg:flex-row items-center gap-16">
|
<div className="flex flex-col lg:flex-row items-center gap-16">
|
||||||
<div className="flex-1 text-center lg:text-left">
|
<div className="flex-1 text-center lg:text-left">
|
||||||
<h1 className="mb-6 text-5xl font-medium leading-[1.1] tracking-tighter text-white md:text-7xl">
|
<h1 className="mb-6 text-5xl font-medium leading-[1.1] tracking-tighter text-white md:text-7xl">
|
||||||
Universal API for <br />
|
Run Coding Agents in Sandboxes.<br />
|
||||||
Coding Agents
|
Control Them Over HTTP.
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-8 text-xl text-zinc-400 leading-relaxed max-w-2xl mx-auto lg:mx-0">
|
<p className="mt-8 text-xl text-zinc-400 leading-relaxed max-w-2xl mx-auto lg:mx-0">
|
||||||
One SDK to control Claude Code, Codex, OpenCode, and Amp. Unified events, session management, and human-in-the-loop. Swap agents with zero refactoring.
|
The Sandbox Agent SDK is a server that runs inside your sandbox. Your app connects remotely to control Claude Code, Codex, OpenCode, or Amp — streaming events, handling permissions, managing sessions.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="mt-10 flex flex-col items-center gap-4 sm:flex-row sm:justify-center lg:justify-start">
|
<div className="mt-10 flex flex-col items-center gap-4 sm:flex-row sm:justify-center lg:justify-start">
|
||||||
|
|
@ -54,83 +201,11 @@ export function Hero() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1 w-full max-w-xl">
|
<div className="flex-1 w-full max-w-2xl">
|
||||||
<div className="relative group">
|
<UniversalAPIDiagram />
|
||||||
<div className="absolute -inset-1 rounded-xl bg-gradient-to-r from-zinc-700 to-zinc-800 opacity-20 blur" />
|
|
||||||
<div className="group relative overflow-hidden rounded-xl border border-white/10 bg-zinc-900/50 shadow-2xl backdrop-blur-xl">
|
|
||||||
<div className="flex items-center justify-between border-b border-white/5 bg-white/5 px-4 py-3">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<div className="h-3 w-3 rounded-full border border-zinc-500/50 bg-zinc-500/20" />
|
|
||||||
<div className="h-3 w-3 rounded-full border border-zinc-500/50 bg-zinc-500/20" />
|
|
||||||
<div className="h-3 w-3 rounded-full border border-zinc-500/50 bg-zinc-500/20" />
|
|
||||||
</div>
|
|
||||||
<div className="font-mono text-xs text-zinc-500">example_agent.ts</div>
|
|
||||||
</div>
|
|
||||||
<pre className="overflow-x-auto p-6 font-mono text-sm leading-relaxed">
|
|
||||||
<code>
|
|
||||||
<span className="text-purple-400">const</span>
|
|
||||||
<span className="text-zinc-300"> agents = </span>
|
|
||||||
<span className="text-purple-400">await</span>
|
|
||||||
<span className="text-zinc-300"> client.</span>
|
|
||||||
<span className="text-blue-400">listAgents</span>
|
|
||||||
<span className="text-zinc-300">();</span>
|
|
||||||
{"\n\n"}
|
|
||||||
<span className="text-purple-400">await</span>
|
|
||||||
<span className="text-zinc-300"> client.</span>
|
|
||||||
<span className="text-blue-400">createSession</span>
|
|
||||||
<span className="text-zinc-300">(</span>
|
|
||||||
<span className="text-green-400">"demo"</span>
|
|
||||||
<span className="text-zinc-300">{", {"}</span>
|
|
||||||
{"\n"}
|
|
||||||
<span className="text-zinc-300">{" agent: "}</span>
|
|
||||||
<span className="text-green-400">"codex"</span>
|
|
||||||
<span className="text-zinc-300">,</span>
|
|
||||||
{"\n"}
|
|
||||||
<span className="text-zinc-300">{" agentMode: "}</span>
|
|
||||||
<span className="text-green-400">"default"</span>
|
|
||||||
<span className="text-zinc-300">,</span>
|
|
||||||
{"\n"}
|
|
||||||
<span className="text-zinc-300">{" permissionMode: "}</span>
|
|
||||||
<span className="text-green-400">"plan"</span>
|
|
||||||
<span className="text-zinc-300">,</span>
|
|
||||||
{"\n"}
|
|
||||||
<span className="text-zinc-300">{"});"}</span>
|
|
||||||
{"\n\n"}
|
|
||||||
<span className="text-purple-400">await</span>
|
|
||||||
<span className="text-zinc-300"> client.</span>
|
|
||||||
<span className="text-blue-400">postMessage</span>
|
|
||||||
<span className="text-zinc-300">(</span>
|
|
||||||
<span className="text-green-400">"demo"</span>
|
|
||||||
<span className="text-zinc-300">{", { message: "}</span>
|
|
||||||
<span className="text-green-400">"Hello from the SDK."</span>
|
|
||||||
<span className="text-zinc-300">{" });"}</span>
|
|
||||||
{"\n\n"}
|
|
||||||
<span className="text-purple-400">for await</span>
|
|
||||||
<span className="text-zinc-300"> (</span>
|
|
||||||
<span className="text-purple-400">const</span>
|
|
||||||
<span className="text-zinc-300"> event </span>
|
|
||||||
<span className="text-purple-400">of</span>
|
|
||||||
<span className="text-zinc-300"> client.</span>
|
|
||||||
<span className="text-blue-400">streamEvents</span>
|
|
||||||
<span className="text-zinc-300">(</span>
|
|
||||||
<span className="text-green-400">"demo"</span>
|
|
||||||
<span className="text-zinc-300">{", { offset: "}</span>
|
|
||||||
<span className="text-amber-400">0</span>
|
|
||||||
<span className="text-zinc-300">{" })) {"}</span>
|
|
||||||
{"\n"}
|
|
||||||
<span className="text-zinc-300">{" console."}</span>
|
|
||||||
<span className="text-blue-400">log</span>
|
|
||||||
<span className="text-zinc-300">(event.type, event.data);</span>
|
|
||||||
{"\n"}
|
|
||||||
<span className="text-zinc-300">{"}"}</span>
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,124 +1,31 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
import { X, Check } from 'lucide-react';
|
||||||
|
|
||||||
const frictions = [
|
const frictions = [
|
||||||
{
|
{
|
||||||
number: '01',
|
number: '01',
|
||||||
title: 'Fragmented Agent Scaffolds',
|
title: 'Coding Agents Need Sandboxes',
|
||||||
description:
|
problem:
|
||||||
'Claude Code, Codex, OpenCode, and Amp each have proprietary APIs. Swapping agents means rewriting your entire integration.',
|
"You can't let AI execute arbitrary code on your production servers. Coding agents need isolated environments, but existing SDKs assume local execution.",
|
||||||
solution: 'Unified control plane for all agent engines.',
|
solution: 'A server that runs inside the sandbox and exposes HTTP/SSE.',
|
||||||
visual: (
|
|
||||||
<div className="mt-6 space-y-3">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<div className="h-px flex-1 bg-gradient-to-r from-red-500/50 to-transparent" />
|
|
||||||
<span className="text-xs text-zinc-500">Claude Bridge</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<div className="h-px flex-1 bg-gradient-to-r from-red-500/50 to-transparent" />
|
|
||||||
<span className="text-xs text-zinc-500">Amp Bridge</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3 mt-4">
|
|
||||||
<div className="h-px flex-1 bg-gradient-to-r from-green-500 to-green-500/20" />
|
|
||||||
<span className="text-xs text-green-400 font-medium">API</span>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 bg-black/60 rounded-lg border border-white/5 p-3 font-mono text-xs">
|
|
||||||
<div className="text-zinc-500">
|
|
||||||
<span className="text-zinc-600">01</span>{' '}
|
|
||||||
<span className="text-purple-400">agent</span>
|
|
||||||
<span className="text-zinc-400">.</span>
|
|
||||||
<span className="text-blue-400">spawn</span>
|
|
||||||
<span className="text-zinc-400">(</span>
|
|
||||||
<span className="text-green-400">"claude-code"</span>
|
|
||||||
<span className="text-zinc-400">)</span>
|
|
||||||
</div>
|
|
||||||
<div className="text-zinc-500">
|
|
||||||
<span className="text-zinc-600">02</span>{' '}
|
|
||||||
<span className="text-purple-400">agent</span>
|
|
||||||
<span className="text-zinc-400">.</span>
|
|
||||||
<span className="text-blue-400">spawn</span>
|
|
||||||
<span className="text-zinc-400">(</span>
|
|
||||||
<span className="text-green-400">"amp"</span>
|
|
||||||
<span className="text-zinc-400">)</span>
|
|
||||||
</div>
|
|
||||||
<div className="text-zinc-600 mt-2">// Exactly same methods</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
accentColor: 'orange',
|
accentColor: 'orange',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: '02',
|
number: '02',
|
||||||
title: 'Deploy Anywhere',
|
title: 'Every Coding Agent is Different',
|
||||||
description:
|
problem:
|
||||||
"Whether you're running locally, in Docker, or with E2B, Daytona, and Vercel — you shouldn't need different integration code for each.",
|
'Claude Code, Codex, OpenCode, and Amp each have proprietary APIs, event formats, and behaviors. Swapping coding agents means rewriting your entire integration.',
|
||||||
solution: 'One SDK, any environment. Deploy locally or to any cloud provider with a single config change.',
|
solution: 'One HTTP API. Write your code once, swap coding agents with a config change.',
|
||||||
visual: (
|
|
||||||
<div className="mt-6">
|
|
||||||
<div className="flex items-center justify-between gap-2 text-xs">
|
|
||||||
<div className="flex-1 text-center py-2 px-3 rounded-lg bg-zinc-800/50 border border-white/5 text-zinc-400">
|
|
||||||
E2B
|
|
||||||
</div>
|
|
||||||
<div className="text-zinc-500">+</div>
|
|
||||||
<div className="flex-1 text-center py-2 px-3 rounded-lg bg-zinc-800/50 border border-white/5 text-zinc-400">
|
|
||||||
Daytona
|
|
||||||
</div>
|
|
||||||
<div className="text-zinc-500">+</div>
|
|
||||||
<div className="flex-1 text-center py-2 px-3 rounded-lg bg-zinc-800/50 border border-white/5 text-zinc-400">
|
|
||||||
Vercel
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 bg-black/60 rounded-lg border border-white/5 p-3 font-mono text-xs">
|
|
||||||
<div className="text-zinc-500 mb-1"># Works with all providers</div>
|
|
||||||
<div>
|
|
||||||
<span className="text-green-400">SANDBOX_PROVIDER</span>
|
|
||||||
<span className="text-zinc-400">=</span>
|
|
||||||
<span className="text-amber-400">"daytona"</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
accentColor: 'purple',
|
accentColor: 'purple',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: '03',
|
number: '03',
|
||||||
title: 'Transient State',
|
title: 'Sessions Are Ephemeral',
|
||||||
description:
|
problem:
|
||||||
'Transcripts and session data are usually lost when the agent process ends. Debugging and replay become impossible.',
|
'Coding agent transcripts live in the sandbox. When the process ends, you lose everything. Debugging and replay become impossible.',
|
||||||
solution: 'Standardized session JSON. Stream events to your own storage in real-time.',
|
solution: 'Universal event schema streams to your storage. Persist to Postgres or Rivet, replay later, audit everything.',
|
||||||
visual: (
|
|
||||||
<div className="mt-6">
|
|
||||||
<div className="bg-black/60 rounded-lg border border-white/5 p-3 font-mono text-xs overflow-hidden">
|
|
||||||
<div className="text-zinc-500 mb-2"># Session persisted automatically</div>
|
|
||||||
<div className="space-y-1">
|
|
||||||
<div>
|
|
||||||
<span className="text-blue-400">"events"</span>
|
|
||||||
<span className="text-zinc-400">: [</span>
|
|
||||||
</div>
|
|
||||||
<div className="pl-4">
|
|
||||||
<span className="text-zinc-400">{'{ '}</span>
|
|
||||||
<span className="text-blue-400">"type"</span>
|
|
||||||
<span className="text-zinc-400">: </span>
|
|
||||||
<span className="text-green-400">"tool_call"</span>
|
|
||||||
<span className="text-zinc-400">{' }'}</span>
|
|
||||||
</div>
|
|
||||||
<div className="pl-4">
|
|
||||||
<span className="text-zinc-400">{'{ '}</span>
|
|
||||||
<span className="text-blue-400">"type"</span>
|
|
||||||
<span className="text-zinc-400">: </span>
|
|
||||||
<span className="text-green-400">"message"</span>
|
|
||||||
<span className="text-zinc-400">{' }'}</span>
|
|
||||||
</div>
|
|
||||||
<div className="text-zinc-400">]</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-3 flex items-center gap-2 text-zinc-500">
|
|
||||||
<span className="w-1.5 h-1.5 rounded-full bg-green-500 animate-pulse" />
|
|
||||||
<span>Streaming to Rivet Actors</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
accentColor: 'blue',
|
accentColor: 'blue',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -156,11 +63,10 @@ export function PainPoints() {
|
||||||
className="mb-16"
|
className="mb-16"
|
||||||
>
|
>
|
||||||
<h2 className="mb-6 text-3xl font-medium tracking-tight text-white md:text-5xl">
|
<h2 className="mb-6 text-3xl font-medium tracking-tight text-white md:text-5xl">
|
||||||
Integrating coding agents is hard.
|
Running coding agents remotely is hard.
|
||||||
</h2>
|
</h2>
|
||||||
<p className="max-w-2xl text-lg leading-relaxed text-zinc-400">
|
<p className="max-w-2xl text-lg leading-relaxed text-zinc-400">
|
||||||
Every agent has its own API, event format, and session model. Swapping agents means
|
Coding agents need sandboxes, but existing SDKs assume local execution. SSH breaks, CLI wrappers are fragile, and building from scratch means reimplementing everything for each coding agent.
|
||||||
rewriting your entire integration.
|
|
||||||
</p>
|
</p>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
|
|
@ -192,20 +98,31 @@ export function PainPoints() {
|
||||||
className={`pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t ${styles.border} opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100`}
|
className={`pointer-events-none absolute left-0 top-0 z-20 h-24 w-24 rounded-tl-2xl border-l border-t ${styles.border} opacity-0 transition-opacity duration-500 [mask-image:linear-gradient(135deg,black_0%,transparent_50%)] group-hover:opacity-100`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="relative z-10">
|
<div className="relative z-10 flex flex-col h-full">
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<h3 className="mb-3 text-xl font-medium text-white">{friction.title}</h3>
|
<h3 className="mb-4 text-xl font-medium text-white">{friction.title}</h3>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Problem */}
|
||||||
<p className="text-sm leading-relaxed text-zinc-500">{friction.description}</p>
|
<div className="mb-4">
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
{/* Solution */}
|
<div className="flex items-center justify-center w-5 h-5 rounded-full bg-red-500/20">
|
||||||
<div className="mt-4 border-t border-white/5 pt-4">
|
<X className="w-3 h-3 text-red-400" />
|
||||||
<p className="text-sm font-medium text-zinc-300">{friction.solution}</p>
|
</div>
|
||||||
|
<span className="text-xs font-semibold uppercase tracking-wider text-red-400">Problem</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm leading-relaxed text-zinc-500">{friction.problem}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Visual */}
|
{/* Solution */}
|
||||||
{friction.visual}
|
<div className="mt-auto pt-4 border-t border-white/5">
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
<div className="flex items-center justify-center w-5 h-5 rounded-full bg-green-500/20">
|
||||||
|
<Check className="w-3 h-3 text-green-400" />
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-semibold uppercase tracking-wider text-green-400">Solution</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-medium leading-relaxed text-zinc-300">{friction.solution}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,12 @@ const { title, description = "Universal SDK for coding agents. Control Claude Co
|
||||||
<meta property="og:title" content={title} />
|
<meta property="og:title" content={title} />
|
||||||
<meta property="og:description" content={description} />
|
<meta property="og:description" content={description} />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:image" content="/logos/sanboxagent.svg" />
|
<meta property="og:image" content="/og.png" />
|
||||||
<meta property="og:image:width" content="570" />
|
<meta property="og:image:width" content="2400" />
|
||||||
<meta property="og:image:height" content="98" />
|
<meta property="og:image:height" content="1260" />
|
||||||
<meta property="og:image:alt" content="Sandbox Agent SDK Logo" />
|
<meta property="og:image:alt" content="Sandbox Agent SDK - Run Coding Agents in Sandboxes. Control Them Over HTTP." />
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta name="twitter:image" content="/logos/sanboxagent.svg" />
|
<meta name="twitter:image" content="/og.png" />
|
||||||
</head>
|
</head>
|
||||||
<body class="min-h-screen">
|
<body class="min-h-screen">
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import Layout from '../layouts/Layout.astro';
|
import Layout from '../layouts/Layout.astro';
|
||||||
import { Navigation } from '../components/Navigation';
|
import { Navigation } from '../components/Navigation';
|
||||||
import { Hero } from '../components/Hero';
|
import { Hero } from '../components/Hero';
|
||||||
|
import { PainPoints } from '../components/PainPoints';
|
||||||
import { FeatureGrid } from '../components/FeatureGrid';
|
import { FeatureGrid } from '../components/FeatureGrid';
|
||||||
import { GetStarted } from '../components/GetStarted';
|
import { GetStarted } from '../components/GetStarted';
|
||||||
import { Inspector } from '../components/Inspector';
|
import { Inspector } from '../components/Inspector';
|
||||||
|
|
@ -9,11 +10,12 @@ import { FAQ } from '../components/FAQ';
|
||||||
import { Footer } from '../components/Footer';
|
import { Footer } from '../components/Footer';
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Coding Agent SDK - Universal SDK for Coding Agents">
|
<Layout title="Sandbox Agent SDK - Run Coding Agents in Sandboxes. Control Them Over HTTP.">
|
||||||
<div class="min-h-screen bg-black text-white selection:bg-accent/30">
|
<div class="min-h-screen bg-black text-white selection:bg-accent/30">
|
||||||
<Navigation client:load />
|
<Navigation client:load />
|
||||||
<main>
|
<main>
|
||||||
<Hero client:load />
|
<Hero client:load />
|
||||||
|
<PainPoints client:visible />
|
||||||
<FeatureGrid client:visible />
|
<FeatureGrid client:visible />
|
||||||
<GetStarted client:visible />
|
<GetStarted client:visible />
|
||||||
<Inspector client:visible />
|
<Inspector client:visible />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue