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
Binary file modified public/og.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 14 additions & 12 deletions src/app/(site)/quickstart/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import CodeBlock from "@/components/CodeBlock";
const SITE_URL = "https://agentdiff.app";

export const metadata: Metadata = {
title: "Quickstart — Claude Code spend report and CI gate",
title: "Quickstart — Claude Code & Codex spend report, and CI gate",
description:
"Run the AgentDiff spend report on your Claude Code sessions in one command, or set up the trajectory regression gate for agents you build.",
"Run the AgentDiff spend report on your Claude Code and Codex sessions in one command, or set up the trajectory regression gate for agents you build.",
keywords: [
"AgentDiff quickstart",
"Claude Code cost report",
Expand Down Expand Up @@ -121,7 +121,7 @@ export default function QuickstartPage() {
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 accounts, nothing uploaded. Start with the Claude Code spend report; if you build your own agents, the CI gate is further down this page.
No API keys, no accounts, nothing uploaded. Start with the spend report for Claude Code and Codex; if you build your own agents, the CI gate is further down this page.
</p>

{/* Fast Proof Points */}
Expand Down Expand Up @@ -152,13 +152,13 @@ export default function QuickstartPage() {
<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
Claude Code &amp; Codex 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.
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 Codex keeps in <code className="text-xs text-(--fg) font-mono bg-(--surface-2) px-1.5 py-0.5 rounded border border-(--border)">~/.codex/sessions</code>, and prints where the money went and what was avoidable.
</p>
</div>
</Reveal>
Expand All @@ -168,15 +168,16 @@ export default function QuickstartPage() {
<CodeBlock
language="bash"
filename="terminal"
code={`# Run once with uv (no install)
uvx --from agent-trajectory-diff agentdiff
code={`# Inside Claude Code: install the plugin once
/plugin install agentdiff --marketplace kerrshift/agentdiff
/agentdiff:report

# Or install it
pip install agent-trajectory-diff
agentdiff
# Any terminal with Node 18+
npx @kerrshift/agentdiff

# Inside a Claude Code session, prefix with !
!uvx --from agent-trajectory-diff agentdiff`}
# Python: run once with uv, or install
uvx --from agent-trajectory-diff agentdiff
pip install agent-trajectory-diff # or pipx / uv tool install`}
/>
</div>
<div className="rounded-2xl border border-(--border) bg-(--surface) overflow-hidden shadow-2xs">
Expand All @@ -185,6 +186,7 @@ agentdiff
filename="options"
code={`agentdiff # last 7 days
agentdiff --since 30d # 24h, 7d, 30d, 12w … or all
agentdiff --agent codex # only Codex (or claude)
agentdiff --project api # filter by project name
agentdiff --top 10 # more findings and sessions
agentdiff --json # machine-readable
Expand Down
15 changes: 8 additions & 7 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ export const metadata: Metadata = {
template: "%s | AgentDiff",
},
description:
"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.",
"One command reads your local Claude Code and Codex 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",
"Codex CLI cost",
"AI coding agent spend",
"token usage report",
"prompt caching",
Expand Down Expand Up @@ -78,7 +79,7 @@ export const metadata: Metadata = {
},
openGraph: {
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.",
description: "A local spend report for Claude Code and Codex: where the money went and what was avoidable. One command, nothing uploaded.",
url: "https://agentdiff.app",
siteName: "AgentDiff",
type: "website",
Expand All @@ -88,15 +89,15 @@ export const metadata: Metadata = {
url: "/og.png",
width: 1200,
height: 630,
alt: "AgentDiff - Trajectory Regression Testing for AI Agents",
alt: "AgentDiff: see what your AI coding agent actually did, and what it cost",
type: "image/png",
},
],
},
twitter: {
card: "summary_large_image",
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.",
description: "A local spend report for Claude Code and Codex: where the money went and what was avoidable. One command, nothing uploaded.",
images: ["/og.png"],
},
appleWebApp: {
Expand All @@ -123,7 +124,7 @@ const jsonLd = {
url: "https://agentdiff.app/",
name: "AgentDiff",
description:
"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.",
"See what your AI coding agent did, and what it cost. A local spend report for Claude Code and Codex sessions, plus a trajectory regression gate for agents you build.",
publisher: { "@id": "https://agentdiff.app/#organization" },
},
{
Expand All @@ -141,13 +142,13 @@ const jsonLd = {
operatingSystem: "Any",
url: "https://agentdiff.app/",
description:
"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.",
"AgentDiff reads local Claude Code and Codex 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.6.0",
softwareVersion: "0.7.0",
},
],
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/ClosingCTA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { ArrowRight, Check, Copy, Terminal } from "lucide-react";
import { Github } from "@lobehub/icons";
import Reveal from "./Reveal";

const RUN_COMMAND = "uvx --from agent-trajectory-diff agentdiff";
const GITHUB_ACTION_SNIPPET = `- uses: kerrshift/agentdiff/.github/actions/agentdiff-check@v0.6.0
const RUN_COMMAND = "npx @kerrshift/agentdiff";
const GITHUB_ACTION_SNIPPET = `- uses: kerrshift/agentdiff/.github/actions/agentdiff-check@v0.7.0
with:
baseline: baselines/default.envelope.json
candidate: traces/candidate.json`;
Expand Down
6 changes: 4 additions & 2 deletions src/components/CopyCommand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import React, { useState } from "react";
import { Copy, Check } from "lucide-react";

export const RUN_COMMAND = "uvx --from agent-trajectory-diff agentdiff";
export const RUN_COMMAND = "npx @kerrshift/agentdiff";
export const UVX_COMMAND = "uvx --from agent-trajectory-diff agentdiff";
export const PLUGIN_COMMAND = "/plugin install agentdiff --marketplace kerrshift/agentdiff";
export const PIP_COMMAND = "pip install agent-trajectory-diff";

export default function CopyCommand({
Expand Down Expand Up @@ -40,7 +42,7 @@ export default function CopyCommand({
dark ? "text-[#E8EAED]" : "text-(--fg)"
}`}
>
<span className="text-(--faint) select-none">${" "}</span>
{!cmd.startsWith("/") && <span className="text-(--faint) select-none">${" "}</span>}
{cmd}
</span>
<button
Expand Down
6 changes: 3 additions & 3 deletions src/components/FAQSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ const FAQS = [
},
{
q: "How do I run it?",
a: "With uv installed: `uvx --from agent-trajectory-diff agentdiff`. Or `pip install agent-trajectory-diff` and run `agentdiff`. From inside a Claude Code session, prefix the command with `!` to run it as a shell command; Claude sees the report too, so you can ask it what to change.",
a: "Inside Claude Code, install the plugin with `/plugin install agentdiff --marketplace kerrshift/agentdiff` and run `/agentdiff:report`. In a terminal, `npx @kerrshift/agentdiff` (Node 18+) or `uvx --from agent-trajectory-diff agentdiff` (uv). To install it, use `pip install agent-trajectory-diff`, `pipx install agent-trajectory-diff` or `npm i -g @kerrshift/agentdiff`. The command is `agentdiff`. Both the npm launcher and the plugin work with whatever you have: uv, pipx, or Python 3.10+.",
},
{
q: "How accurate are the dollar amounts?",
a: "Costs are rebuilt from the token usage Claude Code logs for every request, at Anthropic list prices per model, including cache reads and both cache-write TTLs. Each request is counted once, even across resumed or forked sessions. When a session carries Claude Code's own cost counter, that counter is used as the total, and anything the transcript doesn't show is reported as background calls. Applied to the same tokens, the price table lands within $0.02 of Claude Code's counter on a $47 session.",
a: "Costs are rebuilt from the token usage Claude Code logs for every request, at Anthropic list prices per model, including cache reads and both cache-write TTLs. Each request is counted once, even across resumed or forked sessions. When a session carries Claude Code's own cost counter, that counter is used as the total, and anything the transcript doesn't show is reported as background calls. Applied to the same tokens, the price table lands within $0.02 of Claude Code's counter on a $47 session. Codex logs carry no cost, so Codex figures are API-equivalent estimates at OpenAI list prices.",
},
{
q: "I'm on a Pro or Max subscription. Is this useful?",
a: "Yes. The figures are API-equivalent costs, which is still the clearest way to see which sessions and habits use the most of your plan.",
},
{
q: "Which agents are supported?",
a: "Claude Code today. The OpenAI Codex CLI is next; Gemini CLI and Cursor are planned.",
a: "Claude Code and the OpenAI Codex CLI (new in 0.7). One report covers both; use `--agent codex` or `--agent claude` to pick one. Gemini CLI and Cursor are planned.",
},
{
q: "CI gate: my agent is non-deterministic. Will the gate flake?",
Expand Down
17 changes: 12 additions & 5 deletions src/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ArrowRight } from "lucide-react";
import SpendTerminal from "./SpendTerminal";
import Reveal from "./Reveal";
import CopyCommand from "./CopyCommand";
import { ClaudeCode, Codex } from "@lobehub/icons";

export default function Hero() {
return (
Expand All @@ -17,7 +18,7 @@ export default function Hero() {
<Reveal animate>
<span className="inline-flex items-center gap-2 text-[11px] font-mono text-(--muted) border border-(--border) rounded-full px-3 py-1 bg-(--surface) mb-6">
<span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
New in 0.6 · Claude Code spend report
New in 0.7 · now reads Codex too
</span>

<h1 className="text-3xl sm:text-5xl lg:text-[4.25rem] font-extrabold tracking-[-0.035em] text-(--fg) leading-[1.12] mx-auto max-w-4xl text-balance">
Expand All @@ -27,11 +28,17 @@ export default function Hero() {
</h1>

<p className="max-w-3xl mx-auto text-base sm:text-lg lg:text-xl text-(--fg)/80 dark:text-(--fg)/85 leading-relaxed mt-5 mb-8 font-normal">
One command reads the Claude Code session logs already on your machine and tells you
One command reads the Claude Code and Codex 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.
</p>

<div className="mb-8 -mt-2 flex items-center justify-center gap-5 text-sm font-semibold text-(--fg)">
<span className="text-(--faint) font-medium">Works with</span>
<span className="inline-flex items-center gap-2"><ClaudeCode.Color size={20} />Claude Code</span>
<span className="inline-flex items-center gap-2"><Codex.Color size={20} />Codex</span>
</div>

<div className="flex flex-wrap items-center justify-center gap-3.5">
<div id="install-section" className="scroll-mt-24 max-w-full">
<CopyCommand />
Expand All @@ -45,9 +52,9 @@ export default function Hero() {
</Link>
</div>
<p className="mt-4 text-xs text-(--faint)">
Needs <a className="underline hover:text-(--fg)" href="https://docs.astral.sh/uv/" target="_blank" rel="noreferrer">uv</a>, or{" "}
<code className="font-mono">pip install agent-trajectory-diff</code> and run{" "}
<code className="font-mono">agentdiff</code>.
Or <code className="font-mono">uvx --from agent-trajectory-diff agentdiff</code>, or{" "}
<code className="font-mono">/agentdiff:report</code> inside{" "}
<a className="underline hover:text-(--fg)" href="#how-it-works">Claude Code</a>.
</p>
</Reveal>

Expand Down
41 changes: 27 additions & 14 deletions src/components/SpendHowItWorks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,45 @@
import React from "react";
import { Terminal, Package, MessageSquare, ShieldCheck } from "lucide-react";
import Reveal from "./Reveal";
import CopyCommand, { PIP_COMMAND, RUN_COMMAND } from "./CopyCommand";
import CopyCommand, { PIP_COMMAND, PLUGIN_COMMAND, RUN_COMMAND, UVX_COMMAND } from "./CopyCommand";

const WAYS = [
{
icon: MessageSquare,
title: "Inside Claude Code",
body: "Install the plugin once, then run /agentdiff:report in any session. Claude shows the report and explains what to change. It can also pick it up when you ask why usage is high.",
cmd: PLUGIN_COMMAND,
},
{
icon: Terminal,
title: "Run once, no install",
body: "With uv installed, this fetches AgentDiff into a throwaway environment and prints the report.",
title: "Any terminal with Node",
body: "npx fetches a tiny launcher that runs AgentDiff with uv, pipx or your Python 3.10+, whichever you have.",
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}`,
title: "Python people",
body: "Run it once with uv, or install it with pip, pipx or uv tool install. The command is agentdiff.",
cmd: UVX_COMMAND,
},
];

const ALSO = [PIP_COMMAND, "pipx install agent-trajectory-diff", "npm i -g @kerrshift/agentdiff", "/agentdiff:report --since 30d"];

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 --agent codex", "only Codex (or claude, all)"],
["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.",
"Reads Codex rollouts from ~/.codex/sessions ($CODEX_HOME) and prices each turn with the model it used, including OpenAI's long-context and Fast tiers. Codex logs carry no cost, so those figures are API-equivalent estimates.",
"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.",
];
Expand All @@ -55,7 +59,7 @@ export default function SpendHowItWorks() {
One command. <span className="text-emerald-500/90 dark:text-emerald-400">Zero setup.</span>
</h2>
<p className="mt-5 text-base sm:text-lg lg:text-xl text-(--muted) leading-relaxed font-normal max-w-3xl">
Claude Code already writes a log of every session to disk. AgentDiff reads it. Nothing
Claude Code and Codex already write a log of every session to disk. AgentDiff reads them. Nothing
to configure, no account, no key.
</p>
</div>
Expand All @@ -78,6 +82,15 @@ export default function SpendHowItWorks() {
</div>
</Reveal>

<Reveal delay={100}>
<div className="mt-5 flex flex-wrap gap-2 text-xs font-mono text-(--muted)">
<span className="font-sans text-(--faint) mr-1 self-center">Also:</span>
{ALSO.map((c) => (
<code key={c} className="px-2 py-1 rounded-md border border-(--border) bg-(--surface)">{c}</code>
))}
</div>
</Reveal>

<Reveal delay={120}>
<div className="mt-14 grid grid-cols-1 lg:grid-cols-2 gap-10">
<div>
Expand Down Expand Up @@ -115,7 +128,7 @@ export default function SpendHowItWorks() {

<Reveal delay={160}>
<p className="mt-10 text-xs text-(--faint)">
Supported today: Claude Code. Next: OpenAI Codex CLI. Planned: Gemini CLI, Cursor.
Supported: Claude Code and OpenAI Codex CLI. Planned: Gemini CLI, Cursor.
</p>
</Reveal>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/SpendTerminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface Line {
// 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: "$ npx @kerrshift/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)" },
Expand Down
Loading