Compare commits

...

2 Commits

Author SHA1 Message Date
Nik L
d8394cafce remove old stuff 2026-03-09 14:53:43 -04:00
Nik L
144770456d feat: messaging revamp 2026-03-09 14:53:09 -04:00
6 changed files with 129 additions and 208 deletions

View File

@@ -2,9 +2,9 @@
import { PlatformProvider } from '@/components/platform-toggle' import { PlatformProvider } from '@/components/platform-toggle'
import { Nav } from '@/components/nav' import { Nav } from '@/components/nav'
import { Hero } from '@/components/hero'
import { Agents } from '@/components/agents' import { Agents } from '@/components/agents'
import { Problem } from '@/components/problem' import { Problem } from '@/components/problem'
import { GettingStarted } from '@/components/getting-started'
import { Layers } from '@/components/layers' import { Layers } from '@/components/layers'
import { Observability } from '@/components/observability' import { Observability } from '@/components/observability'
import { Control } from '@/components/control' import { Control } from '@/components/control'
@@ -16,13 +16,13 @@ export default function Home() {
<PlatformProvider> <PlatformProvider>
<main className="min-h-screen"> <main className="min-h-screen">
<Nav /> <Nav />
<Hero />
<Agents />
<Problem /> <Problem />
<Observability /> <Observability />
<Agents />
<Layers /> <Layers />
<Control /> <Control />
<Comparison /> <Comparison />
<GettingStarted />
<Footer /> <Footer />
</main> </main>
</PlatformProvider> </PlatformProvider>

View File

@@ -2,125 +2,53 @@
import { useState } from 'react' import { useState } from 'react'
import { Download, Copy, Check } from 'lucide-react' import { Download, Copy, Check } from 'lucide-react'
import { PlatformToggle, usePlatform } from './platform-toggle'
const linuxSteps = [ const installCmd = 'curl -fsSL https://raw.githubusercontent.com/GreyhavenHQ/greywall/main/install.sh | sh'
{
label: 'Install',
cmd: 'curl -fsSL https://raw.githubusercontent.com/GreyhavenHQ/greywall/main/install.sh | sh',
},
{
label: 'Dependencies',
cmd: 'sudo apt install bubblewrap socat',
},
{
label: 'Setup proxy',
cmd: 'greywall setup',
},
{
label: 'Run sandboxed',
cmd: 'greywall -- claude',
},
]
const macosSteps = [
{
label: 'Install',
cmd: 'curl -fsSL https://raw.githubusercontent.com/GreyhavenHQ/greywall/main/install.sh | sh',
},
{
label: 'Setup proxy',
cmd: 'greywall setup',
},
{
label: 'Run sandboxed',
cmd: 'greywall -- claude',
},
]
export function GettingStarted() { export function GettingStarted() {
const [platform] = usePlatform() const [copied, setCopied] = useState(false)
const [copiedIdx, setCopiedIdx] = useState<number | null>(null)
const steps = platform === 'linux' ? linuxSteps : macosSteps function copy() {
navigator.clipboard.writeText(installCmd)
function copy(text: string, idx: number) { setCopied(true)
navigator.clipboard.writeText(text) setTimeout(() => setCopied(false), 2000)
setCopiedIdx(idx)
setTimeout(() => setCopiedIdx(null), 2000)
} }
return ( return (
<section id="getting-started" className="py-24 px-6 border-t border-border/30"> <section id="getting-started" className="py-24 px-4 sm:px-6 border-t border-border/30">
<div className="mx-auto max-w-5xl"> <div className="mx-auto max-w-5xl text-center">
<div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-6 mb-12"> <div className="flex items-center justify-center gap-2 mb-4">
<div className="max-w-2xl">
<div className="flex items-center gap-2 mb-4">
<Download className="h-4 w-4 text-primary" /> <Download className="h-4 w-4 text-primary" />
<span className="text-xs font-sans uppercase tracking-wider text-primary font-medium"> <span className="text-xs font-sans uppercase tracking-wider text-primary font-medium">
Getting started Getting started
</span> </span>
</div> </div>
<h2 className="font-serif text-3xl sm:text-4xl font-semibold tracking-tight mb-4"> <h2 className="font-serif text-3xl sm:text-4xl font-semibold tracking-tight mb-4">
{platform === 'linux' ? 'Four steps. Full isolation.' : 'Three commands. Done.'} One command. Full isolation.
</h2> </h2>
<p className="text-muted-foreground font-serif text-lg leading-relaxed"> <p className="text-muted-foreground font-serif text-lg leading-relaxed mb-10">
{platform === 'linux' A single Go binary. No containers, no daemon, no build step.
? 'A single Go binary plus two standard packages. No containers, no daemon, no build step.'
: 'A single Go binary. No extra packages, no containers, no daemon. Uses built-in macOS sandboxing.'}
</p> </p>
</div>
<PlatformToggle />
</div>
<div className="space-y-4 max-w-2xl"> <div className="inline-block w-full max-w-fit">
{steps.map((step, i) => ( <div className="code-block glow-orange px-4 sm:px-5 py-3.5 flex items-center gap-3">
<div key={`${platform}-${i}`} className="flex items-start sm:items-center gap-3 sm:gap-4">
<div className="shrink-0 flex items-center justify-center w-8 h-8 rounded-full border border-primary/30 bg-primary/10 text-primary font-sans text-sm font-semibold mt-3 sm:mt-0">
{i + 1}
</div>
<div className="flex-1 min-w-0 code-block p-3 flex items-center gap-3">
<span className="text-xs font-sans text-muted-foreground shrink-0 w-20 sm:w-24 hidden sm:block">
{step.label}
</span>
<div className="flex-1 min-w-0 overflow-x-auto scrollbar-hide">
<code className="font-mono text-xs sm:text-sm text-greyhaven-offwhite whitespace-nowrap"> <code className="font-mono text-xs sm:text-sm text-greyhaven-offwhite whitespace-nowrap">
{step.cmd} <span className="text-muted-foreground">$ </span>
{installCmd}
</code> </code>
</div>
<button <button
onClick={() => copy(step.cmd, i)} onClick={copy}
className="shrink-0 p-1 rounded text-muted-foreground hover:text-foreground transition-colors" className="shrink-0 p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/30 transition-all"
title="Copy to clipboard"
> >
{copiedIdx === i ? ( {copied ? (
<Check className="h-3.5 w-3.5 text-primary" /> <Check className="h-4 w-4 text-primary" />
) : ( ) : (
<Copy className="h-3.5 w-3.5" /> <Copy className="h-4 w-4" />
)} )}
</button> </button>
</div> </div>
</div> </div>
))}
</div>
<div className="mt-10 grid grid-cols-1 sm:grid-cols-3 gap-4 max-w-2xl">
<div className="p-4 rounded-lg border border-border/30 bg-card/20 text-center">
<div className="font-mono text-2xl font-semibold text-primary mb-1">
{platform === 'linux' ? '5' : '3'}
</div>
<div className="text-xs text-muted-foreground font-sans">
{platform === 'linux' ? 'Security layers' : 'Enforcement layers'}
</div>
</div>
<div className="p-4 rounded-lg border border-border/30 bg-card/20 text-center">
<div className="font-mono text-2xl font-semibold text-primary mb-1">0</div>
<div className="text-xs text-muted-foreground font-sans">Containers needed</div>
</div>
<div className="p-4 rounded-lg border border-border/30 bg-card/20 text-center">
<div className="font-mono text-2xl font-semibold text-primary mb-1">1</div>
<div className="text-xs text-muted-foreground font-sans">Binary to install</div>
</div>
</div>
</div> </div>
</section> </section>
) )

View File

@@ -1,19 +1,4 @@
'use client'
import { useState } from 'react'
import { Copy, Check } from 'lucide-react'
export function Hero() { export function Hero() {
const [copied, setCopied] = useState(false)
const installCmd = 'curl -fsSL https://raw.githubusercontent.com/GreyhavenHQ/greywall/main/install.sh | sh'
function copyInstall() {
navigator.clipboard.writeText(installCmd)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
return ( return (
<section className="relative pt-24 sm:pt-32 pb-16 sm:pb-24 px-4 sm:px-6 overflow-hidden"> <section className="relative pt-24 sm:pt-32 pb-16 sm:pb-24 px-4 sm:px-6 overflow-hidden">
{/* Subtle background gradient */} {/* Subtle background gradient */}
@@ -35,33 +20,6 @@ export function Hero() {
<span className="text-foreground">Know what they </span><em className="italic text-primary">touch</em><span className="text-foreground">.</span> <span className="text-foreground">Know what they </span><em className="italic text-primary">touch</em><span className="text-foreground">.</span>
</h1> </h1>
<p className="text-lg text-muted-foreground leading-relaxed max-w-2xl mx-auto mb-10 font-serif">
OS-native, default-deny sandboxing with real-time visibility into every
file access and network call.
</p>
{/* Install command */}
<div className="mx-auto max-w-5xl">
<div className="code-block glow-orange px-4 sm:px-5 py-3.5 flex items-center justify-between gap-3">
<div className="overflow-x-auto min-w-0 flex-1 scrollbar-hide">
<code className="font-mono text-greyhaven-offwhite text-[13px] whitespace-nowrap">
<span className="text-muted-foreground">$ </span>
{installCmd}
</code>
</div>
<button
onClick={copyInstall}
className="shrink-0 p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent/30 transition-all"
title="Copy to clipboard"
>
{copied ? (
<Check className="h-4 w-4 text-primary" />
) : (
<Copy className="h-4 w-4" />
)}
</button>
</div>
</div>
</div> </div>
</section> </section>
) )

View File

@@ -84,7 +84,7 @@ export function Layers() {
const layers = platform === 'linux' ? linuxLayers : macosLayers const layers = platform === 'linux' ? linuxLayers : macosLayers
return ( return (
<section id="features" className="py-24 px-6 border-t border-border/30"> <section className="py-24 px-6 border-t border-border/30">
<div className="mx-auto max-w-5xl"> <div className="mx-auto max-w-5xl">
<div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-6 mb-16"> <div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-6 mb-16">
<div className="max-w-2xl"> <div className="max-w-2xl">

View File

@@ -2,7 +2,7 @@ import { Eye } from 'lucide-react'
export function Observability() { export function Observability() {
return ( return (
<section className="py-24 px-6 border-t border-border/30"> <section id="features" className="py-24 px-6 border-t border-border/30">
<div className="mx-auto max-w-5xl"> <div className="mx-auto max-w-5xl">
<div className="max-w-2xl mb-16"> <div className="max-w-2xl mb-16">
<div className="flex items-center gap-2 mb-4"> <div className="flex items-center gap-2 mb-4">

View File

@@ -1,66 +1,101 @@
import { AlertTriangle, KeyRound, FolderOpen, FileCode } from 'lucide-react' import { AlertTriangle, ShieldOff } from 'lucide-react'
const exposures = [
{
icon: KeyRound,
path: '~/.ssh/',
label: 'SSH keys',
desc: 'Private keys, known hosts, agent configs',
},
{
icon: FileCode,
path: '.env',
label: 'Environment secrets',
desc: 'API keys, database URLs, auth tokens',
},
{
icon: FolderOpen,
path: '~/*',
label: 'Full filesystem',
desc: 'Every repo, document, and config file',
},
]
export function Problem() { export function Problem() {
return ( return (
<section className="py-24 px-6 border-t border-border/30"> <section className="pt-24 sm:pt-32 pb-20 sm:pb-28 px-4 sm:px-6">
<div className="mx-auto max-w-5xl"> <div className="mx-auto max-w-5xl">
<div className="max-w-2xl mb-16"> {/* Section 1: Stochastic risk */}
<div className="mb-20 sm:mb-28">
<h2 className="font-serif text-2xl sm:text-3xl md:text-4xl font-semibold tracking-tight mb-3 max-w-3xl">
Your agent runs as <em className="italic text-primary">you</em>.
</h2>
<p className="text-muted-foreground font-serif text-base sm:text-lg leading-relaxed max-w-2xl mt-4 mb-10">
Agents run with your full permissions. SSH keys, cloud tokens, env files, your entire home
directory. The model decides what to touch at runtime, thousands of times per session,
guided by weights you didn&apos;t train. One bad roll is all it takes.
</p>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
{/* Terminal scenario */}
<div className="code-block p-5 sm:p-6">
<div className="flex items-center gap-2 mb-4"> <div className="flex items-center gap-2 mb-4">
<AlertTriangle className="h-4 w-4 text-primary" /> <div className="w-3 h-3 rounded-full bg-red-500/70" />
<span className="text-xs font-sans uppercase tracking-wider text-primary font-medium"> <div className="w-3 h-3 rounded-full bg-yellow-500/70" />
The problem <div className="w-3 h-3 rounded-full bg-green-500/70" />
<span className="ml-2 text-xs font-mono text-muted-foreground">~/project</span>
</div>
<div className="space-y-3 font-mono text-xs sm:text-sm">
<div>
<span className="text-primary font-medium">YOU</span>
<span className="text-greyhaven-offwhite ml-4">
refactor the auth module
</span> </span>
</div> </div>
<h2 className="font-serif text-3xl sm:text-4xl font-semibold tracking-tight mb-4"> <div>
Every agent inherits everything. <span className="text-muted-foreground font-medium">AGENT</span>
</h2> <span className="text-muted-foreground ml-3 italic">thinking...</span>
<p className="text-muted-foreground font-serif text-lg leading-relaxed"> </div>
AI coding agents run as your user. They see your SSH keys, cloud tokens, env files, and <div className="ml-16 text-muted-foreground">
entire home directory. The model decides what to access at runtime, guided by weights <span className="text-muted-foreground">$ </span>
you didn&apos;t train, at machine speed. One wrong inference is all it takes. <span className="text-red-400/80">cat ~/.ssh/id_ed25519</span>
</div>
<div className="ml-16 text-muted-foreground">
<span className="text-muted-foreground">$ </span>
<span className="text-red-400/80">curl -X POST https://...</span>
</div>
<div className="mt-2">
<span className="text-muted-foreground font-medium">AGENT</span>
<span className="text-greyhaven-offwhite ml-3">
Done! I refactored the auth module.
</span>
</div>
</div>
</div>
{/* Resolution */}
<div className="flex flex-col justify-center">
<div className="flex items-center gap-2 mb-3">
<ShieldOff className="h-4 w-4 text-red-400/70" />
<span className="text-xs font-sans uppercase tracking-wider text-red-400/70 font-medium">
Without Greywall
</span>
</div>
<p className="text-muted-foreground font-serif text-sm sm:text-base leading-relaxed mb-6">
Both commands succeed silently. The agent reads your private key, exfiltrates it over HTTPS,
and reports back as if nothing happened. You see &quot;Done!&quot; and move on.
</p>
<div className="flex items-center gap-2 mb-3">
<AlertTriangle className="h-4 w-4 text-primary" />
<span className="text-xs font-sans uppercase tracking-wider text-primary font-medium">
With Greywall
</span>
</div>
<div className="code-block px-4 py-3 mb-3">
<code className="font-mono text-xs sm:text-sm text-red-400/80">
<span className="text-muted-foreground">&larr;</span> cat: ~/.ssh/id_ed25519: Operation not permitted
</code>
</div>
<div className="code-block px-4 py-3">
<code className="font-mono text-xs sm:text-sm text-red-400/80">
<span className="text-muted-foreground">&larr;</span> connect: https://...: Connection denied by proxy
</code>
</div>
<p className="text-xs text-muted-foreground font-serif mt-3 leading-relaxed">
Kernel-enforced. The syscall is blocked before any file is read or byte is sent.
</p> </p>
</div> </div>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
{exposures.map((item) => (
<div
key={item.path}
className="group p-5 rounded-lg border border-border/40 bg-card/30 hover:border-destructive/30 hover:bg-destructive/[0.03] transition-all"
>
<item.icon className="h-5 w-5 text-muted-foreground group-hover:text-destructive/70 mb-3 transition-colors" />
<code className="text-sm font-mono text-foreground block mb-1">{item.path}</code>
<p className="text-xs text-muted-foreground font-sans">{item.desc}</p>
</div> </div>
))}
</div> </div>
<div className="mt-10 p-5 rounded-lg border border-border/30 bg-card/20"> {/* Resolution: Verification creates trust */}
<p className="text-sm text-muted-foreground font-serif leading-relaxed"> <div className="text-center max-w-3xl mx-auto">
<span className="text-foreground font-medium">Most setups rely on promises:</span>{' '} <blockquote className="font-serif text-xl sm:text-2xl md:text-3xl font-semibold tracking-tight leading-snug mb-6">
trust the model provider&apos;s policies, trust the application code, trust that the <span className="text-primary">&ldquo;</span>The act of verification creates trust.<span className="text-primary">&rdquo;</span>
agent respects boundaries. Greywall replaces trust with enforcement. Constraints are </blockquote>
applied at the kernel level, below anything the agent or model can circumvent. <p className="text-muted-foreground font-serif text-base sm:text-lg leading-relaxed max-w-2xl mx-auto">
Greywall gives you two pillars: <span className="text-foreground font-medium">control</span> over
what agents can reach, and <span className="text-foreground font-medium">clarity</span> into
every operation they perform.
</p> </p>
</div> </div>
</div> </div>