From 7b441638aec6d4bf7ce6f946e77155f3d302864e Mon Sep 17 00:00:00 2001 From: lostmartian Date: Mon, 19 Oct 2026 06:36:09 +0530 Subject: [PATCH] feat(site): lead with the Claude Code spend report, keep the CI gate The landing page now opens on the 0.6 spend report: new hero with real report output, what it finds, how to run it (uvx, pip, ! inside Claude Code), how the numbers are computed and the privacy model. The trajectory regression gate stays as a clearly labelled second section with the PR comment and integrations showcases. Quickstart gains a spend-report section ahead of the gate steps. Removes the unbacked '12 repos' claim, fixes the gate snippet and GitHub links, and updates metadata to 0.6.0. --- src/app/(site)/quickstart/page.tsx | 73 +++++++++++++--- src/app/layout.tsx | 23 +++-- src/app/page.tsx | 16 ++-- src/components/ClosingCTA.tsx | 33 ++++--- src/components/CopyCommand.tsx | 31 ++++--- src/components/FAQSection.tsx | 40 +++++---- src/components/GateIntro.tsx | 54 ++++++++++++ src/components/Header.tsx | 26 +++--- src/components/Hero.tsx | 119 +++++++------------------ src/components/PRCommentShowcase.tsx | 2 +- src/components/SpendFindings.tsx | 91 ++++++++++++++++++++ src/components/SpendHowItWorks.tsx | 124 +++++++++++++++++++++++++++ src/components/SpendTerminal.tsx | 75 ++++++++++++++++ 13 files changed, 531 insertions(+), 176 deletions(-) create mode 100644 src/components/GateIntro.tsx create mode 100644 src/components/SpendFindings.tsx create mode 100644 src/components/SpendHowItWorks.tsx create mode 100644 src/components/SpendTerminal.tsx diff --git a/src/app/(site)/quickstart/page.tsx b/src/app/(site)/quickstart/page.tsx index c7205b8..5cbc429 100644 --- a/src/app/(site)/quickstart/page.tsx +++ b/src/app/(site)/quickstart/page.tsx @@ -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", @@ -24,7 +25,7 @@ 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", @@ -32,7 +33,7 @@ export const metadata: Metadata = { 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.", }, }; @@ -114,20 +115,20 @@ export default function QuickstartPage() {
- Developer Onboarding + Quickstart

- Zero to gated agent in five minutes. + Your spend report in one command.

- 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.

{/* Fast Proof Points */}
- 5-Minute Setup + ~10 seconds to a report • @@ -145,14 +146,64 @@ export default function QuickstartPage() {
- {/* 2. STEP-BY-STEP MARKETING PIPELINE */} -
+ {/* 2. CLAUDE CODE SPEND REPORT */} +
+
+ +
+ + Claude Code spend report + +

+ Run it. Read it. Change one habit. +

+

+ AgentDiff reads the session logs Claude Code keeps in ~/.claude/projects and prints where the money went and what was avoidable. +

+
+
+ +
+
+ +
+
+ +
+
+
+
+
+ + {/* 3. CI GATE: STEP-BY-STEP */} +
- The 4-Step Flow + CI gate · for agents you build

From local execution to automated CI gate. diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a8d287b..0cd767b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -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", @@ -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", @@ -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: { @@ -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" }, }, { @@ -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", }, ], }; diff --git a/src/app/page.tsx b/src/app/page.tsx index 206545d..d8e9de0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -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"; @@ -19,13 +18,14 @@ export default async function Home() {
+ {/* Claude Code spend report (primary since 0.6.0) */} - - - + + + {/* Trajectory regression gate for agents you build */} + -
diff --git a/src/components/ClosingCTA.tsx b/src/components/ClosingCTA.tsx index bf61a6a..9cdf243 100644 --- a/src/components/ClosingCTA.tsx +++ b/src/components/ClosingCTA.tsx @@ -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); }; @@ -38,29 +37,29 @@ export default function ClosingCTA() { {/* Left Column: Bold Value Proposition & Action Buttons */}
- Ready to Deploy + Try it now

- Stop agent regressions before they merge. + Find out where your agent budget went.

- 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.

{/* Primary CTA Buttons */}
- Read Quickstart Guide + How it works - Zero Cloud Dependencies + Runs locally, nothing uploaded - Sub-5ms Graph Alignment + No account or API key
@@ -99,13 +98,13 @@ export default function ClosingCTA() { bash
- PyPI Release + Spend report

$ - {PIP_COMMAND} + {RUN_COMMAND}
@@ -111,14 +119,14 @@ export default function FAQSection() { {/* Bottom Support Link */}
- Have a unique custom framework or telemetry format? + Another agent or log format you want supported? - Ask in GitHub Discussions + Open an issue on GitHub
diff --git a/src/components/GateIntro.tsx b/src/components/GateIntro.tsx new file mode 100644 index 0000000..0ae155c --- /dev/null +++ b/src/components/GateIntro.tsx @@ -0,0 +1,54 @@ +"use client"; + +import React from "react"; +import Link from "next/link"; +import { ArrowRight } from "lucide-react"; +import Reveal from "./Reveal"; +import AdapterLogos from "./AdapterLogos"; + +export default function GateIntro() { + return ( +
+
+ +
+
+ + Also in AgentDiff · for agents you build + +

+ A trajectory regression gate for your CI. +

+

+ Building your own agent with LangGraph, CrewAI, the OpenAI Agents SDK or OpenTelemetry? + AgentDiff compares each PR's agent run against a recorded baseline and fails the + build on runaway tool loops or cost spikes. It handles non-deterministic agents with + N-run baselines, posts a verdict on the PR, and re-baselines with a{" "} + /agentdiff approve comment. +

+
+
+ + Set up the gate + + + How it works + +
+
+
+ +
+ +
+
+
+
+ ); +} diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 424779c..bb958df 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -12,15 +12,14 @@ import useMounted from "./useMounted"; const NAV_ITEMS = [ { href: "/quickstart", label: "Quickstart" }, - { href: "/features", label: "Features" }, + { href: "/features", label: "CI Gate" }, { href: "/adapters", label: "Adapters" }, { href: "/action", label: "GitHub Action" }, - { href: "/compare", label: "Compare" }, { href: "/docs", label: "Docs" }, { href: "/blog", label: "Blog" }, ]; -export default function Header({ version = "0.5.0" }: { version?: string }) { +export default function Header({ version = "0.6.0" }: { version?: string }) { const [open, setOpen] = useState(false); const mounted = useMounted(); const pathname = usePathname(); @@ -100,14 +99,13 @@ export default function Header({ version = "0.5.0" }: { version?: string }) { {/* Bottom Utilities */}
- setOpen(false)} className="inline-flex items-center justify-center gap-2 px-3.5 py-2 rounded-xl bg-(--fg) text-(--bg) text-xs font-semibold hover:opacity-90 transition-opacity" > - Install GitHub App - + Get started +
@@ -185,14 +183,12 @@ export default function Header({ version = "0.5.0" }: { version?: string }) { {/* Right Action Utilities: App Install + Theme + GitHub */}
- - Install App - + Get started +
- {/* Headline with standalone inline symbols & playful typography on silent, broken, and ship */} + + + New in 0.6 · Claude Code spend report + +

- Catch{" "} - - silent - {" "} - - cost surges - - {" "} - and{" "} - - bro - ken - {" "} - - agent loops - - - - - - - {" "} - before they{" "} - - - ship - - - - - - - - - . + See what your AI coding agent{" "} + actually did, and what it{" "} + cost.

- {/* High-visibility subtitle */} -

- Statistical baselines and honest CI gates for AI agents. Measure variance bands, block infinite loops, catch silent cost surges, and re-baseline with a single PR comment. +

+ One command reads the Claude Code session logs already on your machine and tells you + where the money went and what was avoidable: long context re-sent every turn, caches + rebuilt after breaks, stuck retries. No config, no API key, nothing uploaded.

- {/* CTAs + Copy Command */}
+
+ +
- Try in 5 Minutes + How it works -
- -
+

+ Needs uv, or{" "} + pip install agent-trajectory-diff and run{" "} + agentdiff. +

- {/* Adapter logos */} -
- -
- - {/* Product terminal visual with clearly visible ambient green glow */} -
+
- {/* Primary Green Terminal Ambient Aura */}
- - {/* Secondary Soft Diffusion Aura */} -
-
- +

- Automated PR checks · Blocks broken runs before code merges + A real week from the author's own logs · session names changed

); -} \ No newline at end of file +} diff --git a/src/components/PRCommentShowcase.tsx b/src/components/PRCommentShowcase.tsx index 8fd3c02..32a9818 100644 --- a/src/components/PRCommentShowcase.tsx +++ b/src/components/PRCommentShowcase.tsx @@ -696,7 +696,7 @@ export default function PRCommentShowcase() {
- AgentDiff GitHub Action v0.1.0 installed across 12 repos + Example AgentDiff gate comment
View workflow runs diff --git a/src/components/SpendFindings.tsx b/src/components/SpendFindings.tsx new file mode 100644 index 0000000..22c5694 --- /dev/null +++ b/src/components/SpendFindings.tsx @@ -0,0 +1,91 @@ +"use client"; + +import React from "react"; +import Reveal from "./Reveal"; + +const FINDINGS = [ + { + tag: "Usually the biggest", + title: "Long context, re-sent every turn", + body: "Each turn re-reads the whole conversation. Past a few hundred thousand tokens, most of your bill is the model re-reading what it already saw.", + fix: "One session per task. /compact before it gets huge.", + }, + { + tag: "Surprisingly expensive", + title: "Cache rebuilt after a break", + body: "Come back to a long session after the prompt cache expired and the entire context is written again at cache-write prices. One resume of an 818k-token session cost $6.38.", + fix: "After a long break, start fresh instead of resuming.", + }, + { + tag: "Agent behaviour", + title: "Stuck retries and repeated failures", + body: "The same command failing the same way, again and again, or one kind of command failing all session long.", + fix: "Fix the setup step, cwd or flaky test once.", + }, + { + tag: "Agent behaviour", + title: "Re-reads and identical calls", + body: "Unchanged files read repeatedly, and identical calls returning identical output. Cost with no new information.", + fix: "Point the agent at the right section; keep notes in CLAUDE.md.", + }, +]; + +export default function SpendFindings() { + return ( +
+
+ +
+ + What it finds + +

+ Your bill shows a total.{" "} + Not a reason. +

+

+ On real Claude Code usage, most of the spend isn't the model writing code. It's + context habits. Every finding names the session and the file or command involved, + with a dollar estimate. +

+
+
+ + +
+ {FINDINGS.map((f) => ( +
+ + {f.tag} + +

{f.title}

+

{f.body}

+

+ → + {f.fix} +

+
+ ))} +
+
+ + +
+
+
$420
+
real spend across the author's 17 sessions. Naively summing the logs says $640, because resumed sessions copy history.
+
+
+
42%
+
of it flagged avoidable, almost all from long context and cache rebuilds.
+
+
+
$0.02
+
gap between our price table and Claude Code's own cost counter, on the same tokens of a $47 session.
+
+
+
+
+
+ ); +} diff --git a/src/components/SpendHowItWorks.tsx b/src/components/SpendHowItWorks.tsx new file mode 100644 index 0000000..a8be18e --- /dev/null +++ b/src/components/SpendHowItWorks.tsx @@ -0,0 +1,124 @@ +"use client"; + +import React from "react"; +import { Terminal, Package, MessageSquare, ShieldCheck } from "lucide-react"; +import Reveal from "./Reveal"; +import CopyCommand, { PIP_COMMAND, RUN_COMMAND } from "./CopyCommand"; + +const WAYS = [ + { + icon: Terminal, + title: "Run once, no install", + body: "With uv installed, this fetches AgentDiff into a throwaway environment and prints the report.", + cmd: RUN_COMMAND, + }, + { + icon: Package, + title: "Install it", + body: "Then just type agentdiff. Works with pip, pipx or uv tool install.", + cmd: PIP_COMMAND, + }, + { + icon: MessageSquare, + title: "From inside Claude Code", + body: "Prefix with ! to run it as a shell command without leaving your session. Claude sees the report too, so you can ask it what to change.", + cmd: `!${RUN_COMMAND}`, + }, +]; + +const OPTIONS = [ + ["agentdiff", "last 7 days (same as agentdiff sessions)"], + ["agentdiff --since 30d", "24h, 7d, 30d, 12w … or all"], + ["agentdiff --project api", "only projects whose name contains “api”"], + ["agentdiff --top 10", "list more findings and sessions"], + ["agentdiff --json", "machine-readable output"], +]; + +const NUMBERS = [ + "Reads ~/.claude/projects (or $CLAUDE_CONFIG_DIR), including subagent transcripts.", + "Counts each billed request once. Claude Code repeats usage on every content block, and resumed or forked sessions copy their parent's history.", + "Prices per model at Anthropic list prices, with cache reads and both cache-write TTLs (5-minute and 1-hour). Fast mode included.", + "Uses Claude Code's own cost counter as the total when a session has one; the gap shows up as background calls not in the transcript.", + "On Pro/Max plans these are API-equivalent costs: still the clearest view of which sessions and habits use the most.", +]; + +export default function SpendHowItWorks() { + return ( +
+
+ +
+ + How it works + +

+ One command. Zero setup. +

+

+ Claude Code already writes a log of every session to disk. AgentDiff reads it. Nothing + to configure, no account, no key. +

+
+
+ + +
+ {WAYS.map(({ icon: Icon, title, body, cmd }) => ( +
+
+ + + +

{title}

+
+

{body}

+ +
+ ))} +
+
+ + +
+
+

Options

+
+ {OPTIONS.map(([cmd, desc]) => ( +
+ {cmd} + {desc} +
+ ))} +
+
+
+

How the numbers are computed

+
    + {NUMBERS.map((n) => ( +
  • + + {n} +
  • + ))} +
+
+ +

+ Private by design. Session logs + contain your source code. AgentDiff reads them locally, makes no network calls and has + no telemetry. +

+
+
+
+
+ + +

+ Supported today: Claude Code. Next: OpenAI Codex CLI. Planned: Gemini CLI, Cursor. +

+
+
+
+ ); +} diff --git a/src/components/SpendTerminal.tsx b/src/components/SpendTerminal.tsx new file mode 100644 index 0000000..7399156 --- /dev/null +++ b/src/components/SpendTerminal.tsx @@ -0,0 +1,75 @@ +"use client"; + +import React, { useEffect, useState } from "react"; + +interface Line { + t: string; + c?: string; +} + +// A real week from the author's own Claude Code logs (session names changed). +// Keep in sync with the README example in kerrshift/agentdiff. +const LINES: Line[] = [ + { t: "$ uvx --from agent-trajectory-diff agentdiff", c: "text-(--fg) font-semibold" }, + { t: "" }, + { t: "AgentDiff · Claude Code · last 7d", c: "text-(--fg) font-semibold" }, + { t: "12 sessions · 7 projects · $314.61", c: "text-(--muted)" }, + { t: "" }, + { t: "Where the money went", c: "text-(--fg) font-semibold" }, + { t: " Re-reading context (cache reads) $162.64 52% ████████████████", c: "text-(--muted)" }, + { t: " Writing context to cache $93.33 30% █████████", c: "text-(--muted)" }, + { t: " Model output (incl. thinking) $51.34 16% █████", c: "text-(--muted)" }, + { t: " Background calls not in transcript $7.28 2% █", c: "text-(--muted)" }, + { t: "" }, + { t: "Avoidable ≈ $132.08 (42% of spend, conservative estimate)", c: "text-(--fg) font-semibold" }, + { t: " ▸ Long context re-sent every turn $86.64", c: "text-(--danger)" }, + { t: " Start a fresh session per task; /compact before it gets huge.", c: "text-(--faint)" }, + { t: " ▸ Cache rebuilt after breaks $45.44", c: "text-(--danger)" }, + { t: " After a long break, start a new session instead of resuming.", c: "text-(--faint)" }, + { t: "" }, + { t: "Biggest item", c: "text-(--fg) font-semibold" }, + { t: " $23.89 Cache rebuilt 7x after breaks (worst: 818k tokens after 93 min)", c: "text-(--muted)" }, + { t: " Refactor billing service · api", c: "text-(--faint)" }, +]; + +export default function SpendTerminal() { + const [shown, setShown] = useState(1); + + useEffect(() => { + if (shown >= LINES.length) return; + const id = setTimeout(() => setShown((s) => s + 1), 110); + return () => clearTimeout(id); + }, [shown]); + + return ( +
+
+
+ + + +
+ + agentdiff · Claude Code spend report + + + LOCAL + +
+ +
+ {LINES.map((line, i) => ( +
= shown ? "invisible" : ""}`} + > + {line.t || " "} + {i === shown - 1 && ( + + )} +
+ ))} +
+
+ ); +}