Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions src/app/(site)/quickstart/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import CodeBlock from "@/components/CodeBlock";
const SITE_URL = "https://agentdiff.app";

export const metadata: Metadata = {
title: "Quickstart — Zero to Gated Agent in 5 Minutes",
title: "Quickstart — Claude Code spend report and CI gate",
description:
"Install, record, diff, and gate with AgentDiff. Step-by-step developer onboarding with CLI commands, pytest integration, and GitHub Action workflows.",
"Run the AgentDiff spend report on your Claude Code sessions in one command, or set up the trajectory regression gate for agents you build.",
keywords: [
"AgentDiff quickstart",
"Claude Code cost report",
"agent trajectory testing tutorial",
"AI agent regression CI/CD",
"record agent trace",
Expand All @@ -24,15 +25,15 @@ export const metadata: Metadata = {
robots: { index: true, follow: true },
openGraph: {
title: "Quickstart | AgentDiff",
description: "Install, record, diff, and gate — AgentDiff in five minutes.",
description: "One command for your Claude Code spend report; five minutes to a CI gate.",
url: `${SITE_URL}/quickstart`,
siteName: "AgentDiff",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Quickstart | AgentDiff",
description: "Install, record, diff, and gate — AgentDiff in five minutes.",
description: "One command for your Claude Code spend report; five minutes to a CI gate.",
},
};

Expand Down Expand Up @@ -114,20 +115,20 @@ export default function QuickstartPage() {
<Reveal>
<div className="max-w-4xl">
<span className="text-xs uppercase tracking-[0.18em] text-(--faint) block mb-4 font-medium">
Developer Onboarding
Quickstart
</span>
<h1 className="text-3xl sm:text-5xl lg:text-6xl font-bold tracking-[-0.035em] text-(--fg) leading-[1.08]">
Zero to gated agent in <span className="text-emerald-500/90 dark:text-emerald-400">five minutes</span>.
Your spend report in <span className="text-emerald-500/90 dark:text-emerald-400">one command</span>.
</h1>
<p className="mt-6 text-base sm:text-lg lg:text-xl text-(--muted) leading-relaxed max-w-3xl font-normal">
No API keys. No external accounts. No telemetry daemons. One clean install, one recorded golden trace, and an automated regression gate protecting every PR.
No API keys, no accounts, nothing uploaded. Start with the Claude Code spend report; if you build your own agents, the CI gate is further down this page.
</p>

{/* Fast Proof Points */}
<div className="mt-8 flex flex-wrap items-center gap-6 text-xs text-(--muted)">
<span className="flex items-center gap-2">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
<span className="text-(--fg) font-semibold">5-Minute Setup</span>
<span className="text-(--fg) font-semibold">~10 seconds to a report</span>
</span>
<span className="text-(--border) select-none">•</span>
<span className="flex items-center gap-2">
Expand All @@ -145,14 +146,64 @@ export default function QuickstartPage() {
</div>
</section>

{/* 2. STEP-BY-STEP MARKETING PIPELINE */}
<section className="py-24 sm:py-32 bg-transparent">
{/* 2. CLAUDE CODE SPEND REPORT */}
<section id="spend-report" className="py-24 sm:py-32 bg-transparent scroll-mt-20">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<Reveal>
<div className="max-w-3xl mb-12">
<span className="text-xs uppercase tracking-[0.18em] text-(--faint) block mb-3 font-medium">
Claude Code spend report
</span>
<h2 className="text-2xl sm:text-4xl lg:text-5xl font-bold tracking-[-0.035em] text-(--fg) leading-[1.1]">
Run it. Read it. Change one habit.
</h2>
<p className="mt-5 text-base text-(--muted) leading-relaxed">
AgentDiff reads the session logs Claude Code keeps in <code className="text-xs text-(--fg) font-mono bg-(--surface-2) px-1.5 py-0.5 rounded border border-(--border)">~/.claude/projects</code> and prints where the money went and what was avoidable.
</p>
</div>
</Reveal>
<Reveal delay={80}>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div className="rounded-2xl border border-(--border) bg-(--surface) overflow-hidden shadow-2xs">
<CodeBlock
language="bash"
filename="terminal"
code={`# Run once with uv (no install)
uvx --from agent-trajectory-diff agentdiff

# Or install it
pip install agent-trajectory-diff
agentdiff

# Inside a Claude Code session, prefix with !
!uvx --from agent-trajectory-diff agentdiff`}
/>
</div>
<div className="rounded-2xl border border-(--border) bg-(--surface) overflow-hidden shadow-2xs">
<CodeBlock
language="bash"
filename="options"
code={`agentdiff # last 7 days
agentdiff --since 30d # 24h, 7d, 30d, 12w … or all
agentdiff --project api # filter by project name
agentdiff --top 10 # more findings and sessions
agentdiff --json # machine-readable
agentdiff --path ~/.claude # another config dir`}
/>
</div>
</div>
</Reveal>
</div>
</section>

{/* 3. CI GATE: STEP-BY-STEP */}
<section id="ci-gate" className="py-24 sm:py-32 bg-transparent scroll-mt-20">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">

<Reveal>
<div className="max-w-3xl mb-16 sm:mb-20">
<span className="text-xs uppercase tracking-[0.18em] text-(--faint) block mb-3 font-medium">
The 4-Step Flow
CI gate · for agents you build
</span>
<h2 className="text-2xl sm:text-4xl lg:text-5xl font-bold tracking-[-0.035em] text-(--fg) leading-[1.1]">
From local execution to automated CI gate.
Expand Down
23 changes: 14 additions & 9 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@ const themeScript = `
export const metadata: Metadata = {
metadataBase: new URL("https://agentdiff.app"),
title: {
default: "AgentDiff - Trajectory Regression Testing for AI Agents",
default: "AgentDiff - See what your AI coding agent did, and what it cost",
template: "%s | AgentDiff",
},
description:
"AgentDiff compares agent execution traces as DAGs in CI/CD - automatically detecting trajectory drift, redundant tool loops, and cost regressions.",
"One command reads your local Claude Code session logs and shows where the money went and what was avoidable: long context, cache rebuilds, stuck retries. Plus a trajectory regression gate for agents you build.",
applicationName: "AgentDiff",
keywords: [
"Claude Code cost",
"Claude Code usage",
"AI coding agent spend",
"token usage report",
"prompt caching",
"AI agents",
"LLM testing",
"trajectory diff",
Expand Down Expand Up @@ -72,8 +77,8 @@ export const metadata: Metadata = {
apple: "/favicon.svg",
},
openGraph: {
title: "AgentDiff - Trajectory Regression Testing for AI Agents",
description: "Compare agent execution traces as DAGs. Detect drift, loops, and cost regressions in CI/CD.",
title: "AgentDiff - See what your AI coding agent did, and what it cost",
description: "A local spend report for Claude Code: where the money went and what was avoidable. One command, nothing uploaded.",
url: "https://agentdiff.app",
siteName: "AgentDiff",
type: "website",
Expand All @@ -90,8 +95,8 @@ export const metadata: Metadata = {
},
twitter: {
card: "summary_large_image",
title: "AgentDiff - Trajectory Regression Testing for AI Agents",
description: "Compare agent execution traces as DAGs. Detect drift, loops, and cost regressions in CI/CD.",
title: "AgentDiff - See what your AI coding agent did, and what it cost",
description: "A local spend report for Claude Code: where the money went and what was avoidable. One command, nothing uploaded.",
images: ["/og.png"],
},
appleWebApp: {
Expand All @@ -118,7 +123,7 @@ const jsonLd = {
url: "https://agentdiff.app/",
name: "AgentDiff",
description:
"Trajectory regression testing for AI agents. Diff agent execution traces as DAGs and block drift, tool loops, and cost spikes in CI/CD.",
"See what your AI coding agent did, and what it cost. A local spend report for Claude Code sessions, plus a trajectory regression gate for agents you build.",
publisher: { "@id": "https://agentdiff.app/#organization" },
},
{
Expand All @@ -136,13 +141,13 @@ const jsonLd = {
operatingSystem: "Any",
url: "https://agentdiff.app/",
description:
"AgentDiff compares AI agent execution traces as DAGs in CI/CD, detecting trajectory drift, tool loops, and cost regressions.",
"AgentDiff reads local Claude Code session logs and reports where spend went and what was avoidable. It also gates agents you build in CI against trajectory regressions.",
offers: {
"@type": "Offer",
price: "0",
priceCurrency: "USD",
},
softwareVersion: "0.5.0",
softwareVersion: "0.6.0",
},
],
};
Expand Down
16 changes: 8 additions & 8 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import Header from "../components/Header";
import Hero from "../components/Hero";
import ProblemSolution from "../components/ProblemSolution";
import BlueprintWorkspace from "../components/BlueprintWorkspace";
import FeaturesGrid from "../components/FeaturesGrid";
import SpendFindings from "../components/SpendFindings";
import SpendHowItWorks from "../components/SpendHowItWorks";
import GateIntro from "../components/GateIntro";
import PRCommentShowcase from "../components/PRCommentShowcase";
import IntegrationShowcase from "../components/IntegrationShowcase";
import StackFitSection from "../components/StackFitSection";
import FAQSection from "../components/FAQSection";
import ClosingCTA from "../components/ClosingCTA";
import Footer from "../components/Footer";
Expand All @@ -19,13 +18,14 @@ export default async function Home() {
<div id="main-grid-container" className="max-w-7xl mx-auto w-full flex-1 flex flex-col bg-(--bg) relative border-x border-(--border)">
<Header version={version} />
<main className="flex-1 divide-y divide-(--border)">
{/* Claude Code spend report (primary since 0.6.0) */}
<Hero />
<ProblemSolution />
<BlueprintWorkspace />
<FeaturesGrid />
<SpendFindings />
<SpendHowItWorks />
{/* Trajectory regression gate for agents you build */}
<GateIntro />
<PRCommentShowcase />
<IntegrationShowcase />
<StackFitSection />
<FAQSection />
<ClosingCTA />
</main>
Expand Down
33 changes: 16 additions & 17 deletions src/components/ClosingCTA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ import { ArrowRight, Check, Copy, Terminal } from "lucide-react";
import { Github } from "@lobehub/icons";
import Reveal from "./Reveal";

const PIP_COMMAND = "pip install agent-trajectory-diff";
const GITHUB_ACTION_SNIPPET = `- name: Run AgentDiff Gate
uses: agentdiff/action@v1
const RUN_COMMAND = "uvx --from agent-trajectory-diff agentdiff";
const GITHUB_ACTION_SNIPPET = `- uses: kerrshift/agentdiff/.github/actions/agentdiff-check@v0.6.0
with:
baseline: tests/golden_baseline.json
max-divergence: 0.25`;
baseline: baselines/default.envelope.json
candidate: traces/candidate.json`;

export default function ClosingCTA() {
const [copiedPip, setCopiedPip] = useState(false);

const handleCopyPip = () => {
navigator.clipboard.writeText(PIP_COMMAND);
navigator.clipboard.writeText(RUN_COMMAND);
setCopiedPip(true);
setTimeout(() => setCopiedPip(false), 2000);
};
Expand All @@ -38,29 +37,29 @@ export default function ClosingCTA() {
{/* Left Column: Bold Value Proposition & Action Buttons */}
<div className="lg:col-span-7 space-y-6">
<span className="text-xs uppercase tracking-[0.18em] text-(--faint) block font-medium">
Ready to Deploy
Try it now
</span>

<h2 className="text-3xl sm:text-5xl lg:text-6xl font-bold tracking-[-0.035em] text-(--fg) leading-[1.08]">
Stop agent regressions before they merge.
Find out where your agent budget went.
</h2>

<p className="text-base sm:text-lg text-(--muted) leading-relaxed font-normal max-w-xl">
Install in seconds. Compare candidate executions against golden baselines, block infinite tool loops, and protect your token budget on every PR.
One command, about ten seconds, nothing uploaded. Building your own agents too? The same package gates them in CI.
</p>

{/* Primary CTA Buttons */}
<div className="flex flex-wrap items-center gap-3.5 pt-2">
<Link
href="/quickstart"
href="/#how-it-works"
className="px-8 py-3.5 rounded-full bg-(--fg) text-(--bg) text-sm font-semibold hover:opacity-90 transition-opacity inline-flex items-center gap-2 shadow-sm"
>
<span>Read Quickstart Guide</span>
<span>How it works</span>
<ArrowRight className="w-4 h-4" />
</Link>

<Link
href="https://github.com/agentdiff/agentdiff"
href="https://github.com/kerrshift/agentdiff"
target="_blank"
rel="noreferrer"
className="px-7 py-3.5 rounded-full border border-(--border) bg-(--surface) text-(--fg) text-sm font-semibold hover:border-(--border-strong) hover:bg-(--surface-2) transition-all inline-flex items-center gap-2"
Expand All @@ -78,11 +77,11 @@ export default function ClosingCTA() {
</span>
<span className="flex items-center gap-2">
<Check className="w-4 h-4 text-emerald-400 shrink-0" />
<span>Zero Cloud Dependencies</span>
<span>Runs locally, nothing uploaded</span>
</span>
<span className="flex items-center gap-2">
<Check className="w-4 h-4 text-emerald-400 shrink-0" />
<span>Sub-5ms Graph Alignment</span>
<span>No account or API key</span>
</span>
</div>
</div>
Expand All @@ -99,13 +98,13 @@ export default function ClosingCTA() {
<span className="w-2.5 h-2.5 rounded-full bg-(--border)" />
<span className="ml-2 text-xs font-medium text-(--muted)">bash</span>
</div>
<span className="text-[11px] text-emerald-400 font-mono font-semibold">PyPI Release</span>
<span className="text-[11px] text-emerald-400 font-mono font-semibold">Spend report</span>
</div>

<div className="p-4 flex items-center justify-between gap-3 font-mono text-xs text-(--fg)">
<div className="flex items-center gap-2 truncate">
<span className="text-(--faint) select-none">$</span>
<span className="truncate">{PIP_COMMAND}</span>
<span className="truncate">{RUN_COMMAND}</span>
</div>
<button
onClick={handleCopyPip}
Expand All @@ -121,7 +120,7 @@ export default function ClosingCTA() {
<div className="rounded-2xl border border-(--border) bg-(--bg) overflow-hidden shadow-2xs">
<div className="px-4 py-2.5 bg-(--surface-2)/60 border-b border-(--border) flex items-center justify-between">
<span className="text-xs text-(--muted) font-medium">.github/workflows/ci.yml</span>
<span className="text-[11px] text-(--muted) font-mono">CI Gate</span>
<span className="text-[11px] text-(--muted) font-mono">CI gate (optional)</span>
</div>
<pre className="p-4 font-mono text-[11px] text-(--fg)/85 leading-[1.6] overflow-x-auto">
{GITHUB_ACTION_SNIPPET}
Expand Down
31 changes: 20 additions & 11 deletions src/components/CopyCommand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,31 @@
import React, { useState } from "react";
import { Copy, Check } from "lucide-react";

const CMD = "pip install agent-trajectory-diff";
export const RUN_COMMAND = "uvx --from agent-trajectory-diff agentdiff";
export const PIP_COMMAND = "pip install agent-trajectory-diff";

export default function CopyCommand({ dark = false, bare = false }: { dark?: boolean; bare?: boolean }) {
export default function CopyCommand({
cmd = RUN_COMMAND,
dark = false,
bare = false,
wrap = false,
}: {
cmd?: string;
dark?: boolean;
bare?: boolean;
wrap?: boolean;
}) {
const [copied, setCopied] = useState(false);

const copy = () => {
navigator.clipboard.writeText(CMD);
navigator.clipboard.writeText(cmd);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

return (
<div
className={`inline-flex items-center gap-2 ${
className={`${wrap ? "flex items-start justify-between w-full" : "inline-flex items-center max-w-full"} gap-2 ${
bare
? "px-1 py-1"
: `rounded-lg px-3 py-2 sm:px-4 sm:py-2.5 ${
Expand All @@ -25,19 +36,17 @@ export default function CopyCommand({ dark = false, bare = false }: { dark?: boo
}`}
>
<span
className={`text-xs sm:text-[13px] font-mono whitespace-nowrap ${
className={`text-xs sm:text-[13px] font-mono ${wrap ? "break-all text-left" : "truncate"} ${
dark ? "text-[#E8EAED]" : "text-(--fg)"
}`}
>
<span className={`${dark ? "text-(--faint)" : "text-(--faint)"} select-none`}>
${" "}
</span>
{CMD}
<span className="text-(--faint) select-none">${" "}</span>
{cmd}
</span>
<button
onClick={copy}
aria-label="Copy install command"
className={`flex-shrink-0 transition-colors duration-150 ${
aria-label="Copy command"
className={`flex-shrink-0 transition-colors duration-150 cursor-pointer ${
dark ? "text-(--faint) hover:text-white" : "text-(--faint) hover:text-(--fg)"
}`}
>
Expand Down
Loading
Loading