docs: rework homepage and add aaif migration blog post (#8356)

Signed-off-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
Michael Neale
2026-04-07 17:18:04 +10:00
committed by GitHub
parent 583acd4335
commit 7449a96664
15 changed files with 822 additions and 115 deletions
@@ -2,7 +2,7 @@ import Link from "@docusaurus/Link";
import { IconDownload } from "@site/src/components/icons/download";
import { useState, useEffect } from "react";
const FALLBACK_URL = "https://github.com/block/goose/releases/latest";
const FALLBACK_URL = "https://github.com/aaif-goose/goose/releases/latest";
const LinuxDesktopInstallButtons = () => {
const [downloadUrls, setDownloadUrls] = useState({
@@ -26,7 +26,7 @@ const LinuxDesktopInstallButtons = () => {
}
// Fetch latest release from GitHub API
const response = await fetch('https://api.github.com/repos/block/goose/releases/latest');
const response = await fetch('https://api.github.com/repos/aaif-goose/goose/releases/latest');
if (!response.ok) throw new Error('API request failed');
const release = await response.json();
@@ -8,13 +8,13 @@ const DesktopInstallButtons = () => {
<div className="pill-button" style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
<Link
className="button button--primary button--lg"
to="https://github.com/block/goose/releases/download/stable/Goose.zip"
to="https://github.com/aaif-goose/goose/releases/download/stable/Goose.zip"
>
<IconDownload /> macOS Silicon
</Link>
<Link
className="button button--primary button--lg"
to="https://github.com/block/goose/releases/download/stable/Goose_intel_mac.zip"
to="https://github.com/aaif-goose/goose/releases/download/stable/Goose_intel_mac.zip"
>
<IconDownload /> macOS Intel
</Link>
@@ -7,7 +7,7 @@ const SupportedEnvironments = () => {
The goose CLI currently works on <strong>macOS</strong> and <strong>Linux</strong> systems and supports both <strong>ARM</strong> and <strong>x86</strong> architectures.
On <strong>Windows</strong>, goose CLI can run via WSL, and goose Desktop is natively supported. If you'd like to request support for additional operating systems, please{" "}
<a
href="https://github.com/block/goose/discussions/867"
href="https://github.com/aaif-goose/goose/discussions/867"
target="_blank"
rel="noopener noreferrer"
>
@@ -8,7 +8,7 @@ const WindowsDesktopInstallButtons = () => {
<div className="pill-button">
<Link
className="button button--primary button--lg"
to="https://github.com/block/goose/releases/download/stable/Goose-win32-x64.zip"
to="https://github.com/aaif-goose/goose/releases/download/stable/Goose-win32-x64.zip"
>
<IconDownload /> Windows
</Link>
+377 -64
View File
@@ -1,98 +1,411 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
* Homepage styles
*/
.header {
padding: 4rem 2rem;
}
.wrapper {
max-width: 1200px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
gap: 3rem;
justify-content: center;
align-items: center;
min-height: 400px;
}
.textColumn {
flex: 1 1 300px;
max-width: 500px;
/* Hero */
.hero {
padding: 5rem 2rem 3rem;
text-align: center;
}
.heroInner {
max-width: 800px;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
margin-top: -40px;
}
.logo {
.heroBadge {
display: inline-block;
padding: 0.35rem 1rem;
border-radius: 999px;
border: 1px solid var(--border-subtle);
font-size: 0.8rem;
color: var(--text-subtle);
margin-bottom: 2rem;
letter-spacing: 0.02em;
}
.heroLogo {
max-width: 300px;
margin-bottom: 1.5rem;
}
.heroSubtitle {
font-size: 1.35rem;
line-height: 1.6;
color: var(--text-standard);
max-width: 600px;
margin-bottom: 2rem;
}
.heroActions {
display: flex;
gap: 1rem;
margin-bottom: 3rem;
flex-wrap: wrap;
justify-content: center;
}
.secondaryButton {
border-color: var(--border-standard);
color: var(--text-standard);
}
.heroStats {
display: flex;
gap: 2rem;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}
.stat {
display: flex;
flex-direction: column;
align-items: center;
}
.subtitle {
.statNumber {
font-size: 1.5rem;
font-weight: 700;
color: var(--text-prominent);
}
.statLabel {
font-size: 0.85rem;
color: var(--text-subtle);
}
.statDivider {
width: 1px;
height: 2.5rem;
background: var(--border-subtle);
}
/* Sections */
.section {
padding: 4rem 2rem;
}
.sectionAlt {
background: var(--background-subtle);
}
.container {
max-width: 1100px;
margin: 0 auto;
}
.sectionTitle {
font-size: 1.75rem;
font-weight: 600;
text-align: center;
margin-bottom: 0.75rem;
color: var(--text-prominent);
}
.sectionSubtitle {
text-align: center;
max-width: 700px;
margin: 0 auto 2.5rem;
color: var(--text-subtle);
font-size: 1.05rem;
line-height: 1.6;
}
/* Features — top row (3 big cards) */
.featuresGridTop {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
margin-bottom: 2rem;
}
.featureCard {
padding: 1.75rem;
border-radius: 12px;
border: 1px solid var(--border-subtle);
background: var(--background-app);
transition: border-color 0.2s ease;
}
.featureCard:hover {
border-color: var(--border-standard);
}
.featureIcon {
font-size: 1.5rem;
margin-bottom: 0.75rem;
}
.featureTitle {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--text-prominent);
}
.featureDescription {
font-size: 0.9rem;
color: var(--text-subtle);
line-height: 1.6;
}
.featureDescription p {
margin: 0;
}
.featureDescription a {
font-weight: 500;
}
/* Features — bottom row (4 smaller cards) */
.featuresGridBottom {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1.5rem;
}
.smallCard {
padding: 1.25rem;
border-radius: 12px;
border: 1px solid var(--border-subtle);
background: var(--background-app);
transition: border-color 0.2s ease;
}
.smallCard:hover {
border-color: var(--border-standard);
}
.smallCardIcon {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.smallCardTitle {
font-size: 0.95rem;
font-weight: 600;
margin-bottom: 0.4rem;
color: var(--text-prominent);
}
.smallCardDescription {
font-size: 0.85rem;
color: var(--text-subtle);
line-height: 1.55;
}
.smallCardDescription p {
margin: 0;
}
.smallCardDescription a {
font-weight: 500;
}
/* Standards Grid */
.standardsGrid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
margin-top: 2rem;
}
.standardCard {
padding: 1.5rem;
border-radius: 12px;
border: 1px solid var(--border-subtle);
background: var(--background-app);
}
.standardCard h3 {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.75rem;
color: var(--text-prominent);
}
.standardCard p {
font-size: 0.9rem;
color: var(--text-subtle);
line-height: 1.6;
margin-bottom: 0.75rem;
}
.standardCard a {
font-size: 0.9rem;
font-weight: 500;
}
/* Community Grid */
.communityGrid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1.5rem;
}
.communityCard {
padding: 1.5rem;
border-radius: 12px;
border: 1px solid var(--border-subtle);
background: var(--background-app);
text-decoration: none;
color: inherit;
transition: border-color 0.2s ease, transform 0.2s ease;
}
.communityCard:hover {
border-color: var(--border-standard);
transform: translateY(-2px);
text-decoration: none;
color: inherit;
}
.communityCard h3 {
font-size: 1rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--text-prominent);
}
.communityCard p {
font-size: 0.85rem;
color: var(--text-subtle);
line-height: 1.5;
margin: 0;
}
/* Install */
.installBlock {
max-width: 700px;
margin: 0 auto;
}
.installDesktop {
text-align: center;
margin-bottom: 1.5rem;
max-width: 30ch;
}
.videoColumn {
flex: 1 1 400px;
.installPlatforms {
margin-top: 0.75rem;
font-size: 0.9rem;
color: var(--text-subtle);
}
.installDivider {
text-align: center;
margin-bottom: 1.5rem;
font-size: 0.85rem;
color: var(--text-subtle);
}
.installTerminal {
border-radius: 12px;
overflow: hidden;
border: 1px solid var(--border-subtle);
background: var(--grey-10);
}
.terminalBar {
display: flex;
gap: 6px;
padding: 12px 16px;
background: var(--grey-20);
}
.terminalDot {
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--grey-50);
}
.terminalBody {
padding: 1.25rem 1.5rem;
margin: 0;
font-size: 0.85rem;
line-height: 1.7;
color: #e0e0e0;
overflow-x: auto;
}
.installNote {
text-align: center;
margin-top: 1.25rem;
font-size: 0.9rem;
color: var(--text-subtle);
}
/* Video */
.videoWrapper {
max-width: 800px;
margin: 0 auto;
aspect-ratio: 16 / 9;
}
.video {
width: 100%;
max-width: 640px;
height: 100%;
border: none;
border-radius: 12px;
}
.aspect-ratio{
aspect-ratio: 16 / 9;
width: 100%;
}
/* Responsive */
@media (max-width: 996px) {
.featuresGridTop {
grid-template-columns: repeat(2, 1fr);
}
.featuresGridBottom {
grid-template-columns: repeat(2, 1fr);
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
.standardsGrid {
grid-template-columns: repeat(2, 1fr);
}
.communityGrid {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (max-width: 768px) {
.header {
padding: 1rem 1rem;
@media (max-width: 640px) {
.hero {
padding: 3rem 1.5rem 2rem;
}
.wrapper {
flex-direction: column;
text-align: center;
gap: 1rem;
padding: 1rem 1rem;
}
.textColumn {
text-align: center;
max-width: 100%;
flex: 1 1 400px;
margin-top: 0;
}
.subtitle {
.heroSubtitle {
font-size: 1.1rem;
line-height: 1.5;
margin: 0 auto 1.5rem;
}
.ctaButton {
font-size: 1rem;
width: auto;
.heroStats {
gap: 1.5rem;
}
.videoColumn {
flex: 1 1 180px;
aspect-ratio: 16 / 9;
width: 100%;
.statDivider {
display: none;
}
.featuresGridTop {
grid-template-columns: 1fr;
}
.featuresGridBottom {
grid-template-columns: 1fr;
}
.standardsGrid {
grid-template-columns: 1fr;
}
.communityGrid {
grid-template-columns: 1fr;
}
.section {
padding: 3rem 1.5rem;
}
}
+340 -24
View File
@@ -2,47 +2,363 @@ import type { ReactNode } from "react";
import Link from "@docusaurus/Link";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import Layout from "@theme/Layout";
import HomepageFeatures from "@site/src/components/HomepageFeatures";
import styles from "./index.module.css";
import { GooseLogo } from "../components/GooseLogo";
function HomepageHeader() {
const { siteConfig } = useDocusaurusContext();
function HeroSection() {
return (
<header className={styles.header}>
<div className={styles.wrapper}>
<div className={styles.textColumn}>
<div className="hero--logo">
<GooseLogo />
</div>
<p className={styles.subtitle}>{siteConfig.tagline}</p>
<Link className="button button--primary button--lg" to="docs/getting-started/installation">
install goose
<header className={styles.hero}>
<div className={styles.heroInner}>
<div className={styles.heroBadge}>
Open Source · Apache 2.0 · Linux Foundation
</div>
<div className={styles.heroLogo}>
<GooseLogo />
</div>
<p className={styles.heroSubtitle}>
Your native open source AI agent. Desktop app, CLI, and API — for code,
workflows, and everything in between.
</p>
<div className={styles.heroActions}>
<Link
className="button button--primary button--lg"
to="docs/getting-started/installation"
>
Install goose
</Link>
<Link
className={`button button--outline button--lg ${styles.secondaryButton}`}
to="docs/quickstart"
>
Quickstart
</Link>
</div>
<div className={styles.videoColumn}>
<iframe
src="https://www.youtube.com/embed/D-DpDunrbpo"
className="aspect-ratio"
title="vibe coding with goose"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
<div className={styles.heroStats}>
<div className={styles.stat}>
<span className={styles.statNumber}>38k+</span>
<span className={styles.statLabel}>GitHub stars</span>
</div>
<div className={styles.statDivider} />
<div className={styles.stat}>
<span className={styles.statNumber}>400+</span>
<span className={styles.statLabel}>Contributors</span>
</div>
<div className={styles.statDivider} />
<div className={styles.stat}>
<span className={styles.statNumber}>70+</span>
<span className={styles.statLabel}>MCP extensions</span>
</div>
</div>
</div>
</header>
);
}
type FeatureCardProps = {
title: string;
description: ReactNode;
icon: string;
};
function FeatureCard({ title, description, icon }: FeatureCardProps) {
return (
<div className={styles.featureCard}>
<div className={styles.featureIcon}>{icon}</div>
<h3 className={styles.featureTitle}>{title}</h3>
<div className={styles.featureDescription}>{description}</div>
</div>
);
}
type SmallCardProps = {
title: string;
description: ReactNode;
icon: string;
};
function SmallCard({ title, description, icon }: SmallCardProps) {
return (
<div className={styles.smallCard}>
<div className={styles.smallCardIcon}>{icon}</div>
<h3 className={styles.smallCardTitle}>{title}</h3>
<div className={styles.smallCardDescription}>{description}</div>
</div>
);
}
function FeaturesSection() {
return (
<section className={styles.section}>
<div className={styles.container}>
<h2 className={styles.sectionTitle}>What goose does</h2>
<p className={styles.sectionSubtitle}>
goose is a general-purpose AI agent that runs on your machine. Not
just for code — use it for research, writing, automation, data
analysis, or anything you need to get done.
</p>
<div className={styles.featuresGridTop}>
<FeatureCard
icon="🖥️"
title="Desktop app, CLI, and API"
description={
<p>
A native desktop app for macOS, Linux, and Windows. A full CLI
for terminal workflows. An API to embed it anywhere. Built
in Rust for performance and portability.
</p>
}
/>
<FeatureCard
icon="🔌"
title="Extensible"
description={
<p>
Connect to 70+ extensions — databases, APIs, browsers, GitHub,
Google Drive, and more — via the{" "}
<a href="https://modelcontextprotocol.io/" target="_blank" rel="noopener">
Model Context Protocol
</a>{" "}
open standard. Add community{" "}
<Link to="/skills">skills</Link>, or{" "}
<Link to="/docs/tutorials/custom-extensions">build your own</Link>.
</p>
}
/>
<FeatureCard
icon="🤖"
title="Any LLM, including your subscriptions"
description={
<p>
Works with 15+ providers — Anthropic, OpenAI, Google, Ollama,
OpenRouter, Azure, Bedrock, and more. Use API keys or your
existing Claude, ChatGPT, or Gemini subscriptions via{" "}
<Link to="/docs/guides/acp-providers">ACP</Link>.
</p>
}
/>
</div>
<div className={styles.featuresGridBottom}>
<SmallCard
icon="📋"
title="Recipes"
description={
<p>
Capture workflows as portable YAML configs. Share with your
team, run in CI, include instructions, extensions, parameters,
and{" "}
<Link to="/docs/guides/recipes/session-recipes">subrecipes</Link>.
</p>
}
/>
<SmallCard
icon="🧩"
title="MCP Apps"
description={
<p>
Extensions can render interactive UIs directly inside goose
Desktop — buttons, forms, visualizations. A new way to build{" "}
<Link to="/docs/tutorials/building-mcp-apps">
agent-powered tools
</Link>.
</p>
}
/>
<SmallCard
icon="🔀"
title="Subagents"
description={
<p>
Spawn independent{" "}
<Link to="/docs/guides/subagents">subagents</Link> to handle
tasks in parallel — code review, research, file processing —
keeping the main conversation clean.
</p>
}
/>
<SmallCard
icon="🔒"
title="Security"
description={
<p>
Prompt injection detection, tool permission controls, sandbox
mode, and an{" "}
<Link to="/docs/guides/security/adversary-mode">
adversary reviewer
</Link>{" "}
that watches for unsafe actions.
</p>
}
/>
</div>
</div>
</section>
);
}
function StandardsSection() {
return (
<section className={`${styles.section} ${styles.sectionAlt}`}>
<div className={styles.container}>
<h2 className={styles.sectionTitle}>Built on open standards</h2>
<div className={styles.standardsGrid}>
<div className={styles.standardCard}>
<h3>Model Context Protocol</h3>
<p>
<a href="https://modelcontextprotocol.io/" target="_blank" rel="noopener">MCP</a>{" "}
is the open standard for connecting AI agents to tools and data
sources. goose was one of the earliest adopters and has one of the
deepest integrations in the ecosystem — with 70+ documented
extensions and growing.
</p>
<Link to="/docs/category/mcp-servers">Browse MCP extensions →</Link>
</div>
<div className={styles.standardCard}>
<h3>Agent Client Protocol</h3>
<p>
<a href="https://agentclientprotocol.com/" target="_blank" rel="noopener">ACP</a>{" "}
is a standard for communicating with coding agents. goose works as
an ACP server — connect from Zed, JetBrains, or VS Code — and can
use ACP agents like Claude Code and Codex as providers.
</p>
<Link to="/docs/guides/acp-clients">goose as ACP server →</Link>
</div>
<div className={styles.standardCard}>
<h3>Agentic AI Foundation</h3>
<p>
goose is part of the{" "}
<a href="https://aaif.io/" target="_blank" rel="noopener">
Agentic AI Foundation
</a>{" "}
at the Linux Foundation — ensuring the project remains
vendor-neutral, community-governed, and open for the long term.
</p>
<a href="https://aaif.io/" target="_blank" rel="noopener">
Learn about AAIF →
</a>
</div>
</div>
</div>
</section>
);
}
function CommunitySection() {
return (
<section className={styles.section}>
<div className={styles.container}>
<h2 className={styles.sectionTitle}>Community</h2>
<p className={styles.sectionSubtitle}>
An active community of developers, contributors, and users building
extensions, sharing recipes, and pushing the boundaries of what local
AI agents can do.
</p>
<div className={styles.communityGrid}>
<a
href="https://discord.gg/goose-oss"
target="_blank"
rel="noopener"
className={styles.communityCard}
>
<h3>💬 Discord</h3>
<p>
Ask questions, share what you've built, get help from the
community.
</p>
</a>
<a
href="https://github.com/aaif-goose/goose"
target="_blank"
rel="noopener"
className={styles.communityCard}
>
<h3>🐙 GitHub</h3>
<p>
Star, fork, file issues, contribute code. goose is built in the
open.
</p>
</a>
<Link to="/extensions" className={styles.communityCard}>
<h3>🧩 Extensions</h3>
<p>Browse community-built MCP extensions and add your own.</p>
</Link>
<Link to="/blog" className={styles.communityCard}>
<h3>📝 Blog</h3>
<p>Tutorials, deep dives, release notes, and community spotlights.</p>
</Link>
</div>
</div>
</section>
);
}
function InstallSection() {
return (
<section className={`${styles.section} ${styles.sectionAlt}`}>
<div className={styles.container}>
<h2 className={styles.sectionTitle}>Get started</h2>
<div className={styles.installBlock}>
<div className={styles.installDesktop}>
<Link
className="button button--primary button--lg"
to="docs/getting-started/installation"
>
Download the desktop app
</Link>
<p className={styles.installPlatforms}>
Available for macOS, Linux, and Windows
</p>
</div>
<div className={styles.installDivider}>
<span>or install the CLI</span>
</div>
<div className={styles.installTerminal}>
<div className={styles.terminalBar}>
<span className={styles.terminalDot} />
<span className={styles.terminalDot} />
<span className={styles.terminalDot} />
</div>
<pre className={styles.terminalBody}>
<code>
{`curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | bash`}
</code>
</pre>
</div>
</div>
</div>
</section>
);
}
function VideoSection() {
return (
<section className={styles.section}>
<div className={styles.container}>
<h2 className={styles.sectionTitle}>See goose in action</h2>
<div className={styles.videoWrapper}>
<iframe
src="https://www.youtube.com/embed/D-DpDunrbpo"
className={styles.video}
title="vibe coding with goose"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
</div>
</div>
</section>
);
}
export default function Home(): ReactNode {
return (
<Layout description="your open source AI agent, automating engineering tasks seamlessly">
<HomepageHeader />
<Layout description="Your native open source AI agent. Desktop app, CLI, and API — for code, workflows, and everything in between.">
<HeroSection />
<main>
<HomepageFeatures />
<FeaturesSection />
<StandardsSection />
<CommunitySection />
<InstallSection />
<VideoSection />
</main>
</Layout>
);
@@ -393,7 +393,7 @@ function PageActionsMenu(): ReactNode {
const handleViewMarkdown = () => {
const source = metadata?.source?.replace('@site/', '') || '';
window.open(`https://raw.githubusercontent.com/block/goose/refs/heads/main/documentation/${source}`, '_blank');
window.open(`https://raw.githubusercontent.com/aaif-goose/goose/refs/heads/main/documentation/${source}`, '_blank');
setDropdownOpen(false);
};