feat: seo optimization p2

This commit is contained in:
Nik L
2026-03-19 15:59:41 -04:00
parent 0ee456ad58
commit bc21fa97ad
15 changed files with 160 additions and 13 deletions

View File

@@ -11,6 +11,7 @@ import { Observability } from '@/components/observability'
import { Control } from '@/components/control' import { Control } from '@/components/control'
import { Comparison } from '@/components/comparison' import { Comparison } from '@/components/comparison'
import { About } from '@/components/about' import { About } from '@/components/about'
import { FAQ } from '@/components/faq'
import { Footer } from '@/components/footer' import { Footer } from '@/components/footer'
export default function Home() { export default function Home() {
@@ -27,6 +28,7 @@ export default function Home() {
<Comparison /> <Comparison />
<GettingStarted /> <GettingStarted />
<About /> <About />
<FAQ />
<Footer /> <Footer />
</main> </main>
</PlatformProvider> </PlatformProvider>

View File

@@ -2,16 +2,16 @@ import Image from 'next/image'
import { CheckCircle2 } from 'lucide-react' import { CheckCircle2 } from 'lucide-react'
const agents = [ const agents = [
{ name: 'Claude Code', org: 'anthropics', url: 'https://docs.anthropic.com/en/docs/claude-code' }, { name: 'Claude Code', icon: '/agents/anthropics.png', url: 'https://docs.anthropic.com/en/docs/claude-code' },
{ name: 'Codex', org: 'openai', url: 'https://github.com/openai/codex' }, { name: 'Codex', icon: '/agents/openai.png', url: 'https://github.com/openai/codex' },
{ name: 'Cursor', org: 'getcursor', url: 'https://cursor.com' }, { name: 'Cursor', icon: '/agents/getcursor.png', url: 'https://cursor.com' },
{ name: 'Aider', org: 'Aider-AI', url: 'https://aider.chat' }, { name: 'Aider', icon: '/agents/aider-ai.png', url: 'https://aider.chat' },
{ name: 'Goose', org: 'block', url: 'https://github.com/block/goose' }, { name: 'Goose', icon: '/agents/block.png', url: 'https://github.com/block/goose' },
{ name: 'Amp', org: 'sourcegraph', url: 'https://ampcode.com' }, { name: 'Amp', icon: '/agents/sourcegraph.png', url: 'https://ampcode.com' },
{ name: 'Gemini CLI', org: 'google-gemini', url: 'https://github.com/google-gemini/gemini-cli' }, { name: 'Gemini CLI', icon: '/agents/google-gemini.png', url: 'https://github.com/google-gemini/gemini-cli' },
{ name: 'Cline', org: 'cline', url: 'https://cline.bot' }, { name: 'Cline', icon: '/agents/cline.png', url: 'https://cline.bot' },
{ name: 'OpenCode', org: 'nicepkg', url: 'https://opencode.ai/' }, { name: 'OpenCode', icon: '/agents/nicepkg.png', url: 'https://opencode.ai/' },
{ name: 'Copilot', org: 'github', url: 'https://github.com/features/copilot' }, { name: 'Copilot', icon: '/agents/github.png', url: 'https://github.com/features/copilot' },
] ]
export function Agents() { export function Agents() {
@@ -44,7 +44,7 @@ export function Agents() {
className="group flex items-center gap-2.5 sm:gap-3 p-3 sm:p-4 rounded-lg border border-border/40 bg-card/30 hover:border-primary/20 hover:bg-card/50 transition-all cursor-pointer" className="group flex items-center gap-2.5 sm:gap-3 p-3 sm:p-4 rounded-lg border border-border/40 bg-card/30 hover:border-primary/20 hover:bg-card/50 transition-all cursor-pointer"
> >
<Image <Image
src={`https://github.com/${agent.org}.png?size=64`} src={agent.icon}
alt={agent.name} alt={agent.name}
width={28} width={28}
height={28} height={28}

120
components/faq.tsx Normal file
View File

@@ -0,0 +1,120 @@
'use client'
import { useState } from 'react'
import { HelpCircle, ChevronDown } from 'lucide-react'
const faqs = [
{
question: 'What is Greywall?',
answer:
'Greywall is a command-line tool that sandboxes AI coding agents. You wrap your agent in it — <code>greywall -- claude</code> — and it enforces a default-deny security policy at the kernel level. The agent can read and write your project files, but it cannot touch your SSH keys, read your .env, or make network calls you haven\'t approved. It works on Linux and macOS, requires no containers, and is open source under the Apache 2.0 license. The basic promise is modest: your AI assistant should not have more access to your computer than you would give a stranger at a coffee shop.',
},
{
question: 'How do I sandbox my AI coding agent?',
answer:
'Install Greywall, then prefix your command: <code>greywall -- claude</code>, <code>greywall -- opencode</code>, or any other CLI agent. That is the whole process. Greywall operates at the OS level, so it does not need plugins, extensions, or agent-specific configuration. The agent launches inside a kernel-enforced sandbox and runs normally — it just cannot reach things you have not explicitly allowed. If you want to see what the agent is trying to access, open the GreyProxy dashboard.',
},
{
question: 'How is Greywall different from running agents in Docker?',
answer:
'Containers were designed to ship software, not to babysit it. When you run an AI agent inside Docker, you get isolation, but you lose access to your local tools, editor integrations, and filesystem. Every dependency change means rebuilding an image. Greywall takes a different approach: the agent runs natively on your machine with full access to your toolchain, but the kernel enforces boundaries around what it can reach. Think of it as the difference between locking someone in a room versus letting them walk around the house with certain doors locked. You also get real-time visibility into what the agent is doing, which Docker does not offer.',
},
{
question: 'Does Greywall work on macOS?',
answer:
'Yes. On macOS, Greywall uses Seatbelt — Apple\'s built-in kernel sandbox, the same one that constrains App Store applications. It generates a deny-by-default sandbox profile for each session, covering filesystem access, network connections, and IPC. Network traffic is routed through GreyProxy via environment variables. On Linux, there are more layers available (Bubblewrap, Landlock, Seccomp BPF, eBPF, and a TUN device for network capture), but the macOS implementation provides strong isolation using only built-in OS capabilities. No additional packages required.',
},
{
question: 'Is Greywall open source?',
answer:
'Yes. Apache 2.0 license, source code on <a href="https://github.com/GreyhavenHQ/greywall" target="_blank" rel="noopener noreferrer">GitHub</a>. For a security tool, this is not a philosophical position so much as a practical necessity. You should be able to read the code that stands between an AI agent and your production credentials. Greywall is built by <a href="https://greyhaven.co" target="_blank" rel="noopener noreferrer">Greyhaven</a>, who use it in their own production deployments. As the saying goes — never trust a lock you cannot pick apart.',
},
{
question: 'What kernel version does Linux require?',
answer:
'The minimum is Linux 3.8 for namespace isolation via Bubblewrap. Landlock filesystem controls need 5.13. Seccomp BPF needs 3.5. eBPF monitoring needs 4.15. The network proxy works on any kernel. Greywall detects what your system supports at runtime and activates every available layer. If you are on a reasonably modern distribution — anything from the last few years — you will get all five layers. Run <code>greywall --linux-features</code> to see what is available. The tool degrades gracefully rather than refusing to start, which is a courtesy more software should extend.',
},
{
question: 'Which AI agents does Greywall support?',
answer:
'All of them. Claude Code, Codex, Cursor, Aider, Goose, Amp, Gemini CLI, Cline, OpenCode, Copilot — anything that runs as a process on your machine. Greywall does not need agent-specific configuration because it operates at the OS level, below the agent. The agent does not know it is sandboxed, which is, in a way, the whole point. It simply discovers that certain operations fail, adapts, and carries on with its work. Most of the time, this is exactly what you wanted it to do in the first place.',
},
]
const faqJsonLd = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: faqs.map((faq) => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer.replace(/<[^>]*>/g, ''),
},
})),
}
function FAQItem({ question, answer }: { question: string; answer: string }) {
const [open, setOpen] = useState(false)
return (
<div className="border-b border-border/30">
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between gap-4 py-5 text-left cursor-pointer"
>
<h3 className="font-serif text-base sm:text-lg font-semibold text-foreground">
{question}
</h3>
<ChevronDown
className={`h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200 ${
open ? 'rotate-180' : ''
}`}
/>
</button>
<div
className={`grid transition-[grid-template-rows] duration-200 ${
open ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'
}`}
>
<div className="overflow-hidden">
<p
className="pb-5 text-muted-foreground font-serif text-base leading-relaxed [&_code]:font-mono [&_code]:text-xs [&_code]:text-foreground [&_code]:bg-card/50 [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_a]:text-primary [&_a]:hover:text-primary/80 [&_a]:transition-colors"
dangerouslySetInnerHTML={{ __html: answer }}
/>
</div>
</div>
</div>
)
}
export function FAQ() {
return (
<section className="py-24 px-4 sm:px-6 border-t border-border/30">
<div className="mx-auto max-w-5xl">
<div className="max-w-2xl mb-12">
<div className="flex items-center gap-2 mb-4">
<HelpCircle className="h-4 w-4 text-primary" />
<span className="text-xs font-sans uppercase tracking-wider text-primary font-medium">
Questions
</span>
</div>
<h2 className="font-serif text-3xl sm:text-4xl font-semibold tracking-tight mb-4">
Frequently asked.
</h2>
</div>
<div className="max-w-3xl">
{faqs.map((faq) => (
<FAQItem key={faq.question} question={faq.question} answer={faq.answer} />
))}
</div>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqJsonLd) }}
/>
</div>
</section>
)
}

View File

@@ -17,9 +17,23 @@ export function Hero() {
<h1 className="font-serif text-4xl sm:text-5xl md:text-6xl font-semibold tracking-tight leading-[1.1] mb-6"> <h1 className="font-serif text-4xl sm:text-5xl md:text-6xl font-semibold tracking-tight leading-[1.1] mb-6">
<em className="italic text-primary">Greywall</em> your agent &amp; let it cook. <em className="italic text-primary">Greywall</em> your agent &amp; let it cook.
</h1> </h1>
<p className="text-lg text-muted-foreground leading-relaxed max-w-2xl mx-auto font-serif"> <p className="text-lg text-muted-foreground leading-relaxed max-w-2xl mx-auto font-serif mb-6">
Container-free sandboxing with real-time observability & dynamic controls, for Linux & MacOS. Container-free sandboxing with real-time observability & dynamic controls, for Linux & MacOS.
</p> </p>
<div className="inline-flex items-center gap-2 flex-wrap justify-center">
<a href="https://github.com/GreyhavenHQ/greywall" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/github/stars/GreyhavenHQ/greywall?style=flat&color=D95E2A&labelColor=161614&logo=github&logoColor=white" alt="GitHub stars" className="h-5" />
</a>
<a href="https://github.com/GreyhavenHQ/greywall/blob/main/LICENSE" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/github/license/GreyhavenHQ/greywall?style=flat&color=D95E2A&labelColor=161614" alt="License" className="h-5" />
</a>
<a href="https://github.com/GreyhavenHQ/greywall/releases" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/github/v/release/GreyhavenHQ/greywall?style=flat&color=D95E2A&labelColor=161614" alt="Latest release" className="h-5" />
</a>
<a href="https://github.com/GreyhavenHQ/greywall" target="_blank" rel="noopener noreferrer">
<img src="https://img.shields.io/github/go-mod/go-version/GreyhavenHQ/greywall?style=flat&color=D95E2A&labelColor=161614" alt="Go version" className="h-5" />
</a>
</div>
</div> </div>
</section> </section>
) )

View File

@@ -122,11 +122,22 @@ export function Problem() {
<blockquote className="font-serif text-xl sm:text-2xl md:text-3xl font-semibold tracking-tight leading-snug mb-6"> <blockquote className="font-serif text-xl sm:text-2xl md:text-3xl font-semibold tracking-tight leading-snug mb-6">
<span className="text-primary">&ldquo;</span>The act of verification creates trust.<span className="text-primary">&rdquo;</span> <span className="text-primary">&ldquo;</span>The act of verification creates trust.<span className="text-primary">&rdquo;</span>
</blockquote> </blockquote>
<p className="text-muted-foreground font-serif text-base sm:text-lg leading-relaxed max-w-2xl mx-auto"> <p className="text-muted-foreground font-serif text-base sm:text-lg leading-relaxed max-w-2xl mx-auto mb-10">
Greywall gives you two pillars: <span className="text-foreground font-medium">control</span> over 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 what agents can reach, and <span className="text-foreground font-medium">clarity</span> into
every operation they perform. every operation they perform.
</p> </p>
<div className="mx-auto max-w-3xl rounded-lg border border-border/40 overflow-hidden">
<div className="relative w-full" style={{ paddingBottom: '56.25%' }}>
<iframe
src="https://www.youtube.com/embed/u7YFVGGpPRI"
title="Greywall Demo"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
className="absolute inset-0 w-full h-full"
/>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>

BIN
public/agents/aider-ai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/agents/block.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/agents/cline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/agents/getcursor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
public/agents/github.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
public/agents/nicepkg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/agents/openai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB