> ## Documentation Index
> Fetch the complete documentation index at: https://repost.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Repost CLI

> Use the Repost CLI to connect internal forwarders to your local machine, inspect webhook traffic, and manage forwarding from the terminal.

export const SectionTitle = ({eyebrow, title, children}) => {
  return <div className="mb-8 max-w-3xl">
      {eyebrow && <div className="mb-3 repost-eyebrow">{eyebrow}</div>}
      <div className="text-2xl tracking-tight text-gray-950 dark:text-gray-100">{title}</div>
      <p className="mt-3 text-base leading-7 text-gray-600 dark:text-gray-400">{children}</p>
    </div>;
};

export const Section = ({children}) => {
  return <section className="py-12 border-t border-gray-100 dark:border-white/10 first:border-t-0 first:pt-6">{children}</section>;
};

export const CliTui = ({caption}) => {
  const W = 720;
  const u = n => `${(n / W * 100).toFixed(3)}cqw`;
  const MONO = "ui-monospace, SFMono-Regular, Menlo, monospace";
  const C = {
    bg: "var(--fd-surface)",
    chip: "var(--fd-node-bg)",
    chipBorder: "var(--fd-node-border)",
    border: "var(--fd-surface-border)",
    accent: "var(--fd-accent)",
    text: "var(--fd-text)",
    muted: "var(--fd-muted)",
    green: "var(--fd-ok)",
    blue: "var(--fd-accent-cool)",
    yellow: "var(--fd-warn)",
    red: "var(--fd-err)"
  };
  const tint = (c, pct) => `color-mix(in srgb, ${c} ${pct}%, transparent)`;
  const faint = "color-mix(in srgb, var(--fd-muted) 62%, transparent)";
  const rows = [{
    time: "11:40:18.204",
    method: "POST",
    path: "/webhooks/stripe",
    dest: "http://localhost:5000/webhooks/stripe",
    code: "200",
    status: "OK",
    dur: "24ms",
    ok: true,
    sel: false
  }, {
    time: "11:40:17.991",
    method: "POST",
    path: "/webhooks/github",
    dest: "http://localhost:5000/webhooks/github",
    code: "200",
    status: "OK",
    dur: "31ms",
    ok: true,
    sel: false
  }, {
    time: "11:40:15.620",
    method: "POST",
    path: "/webhooks/clerk",
    dest: "http://localhost:5000/webhooks/clerk",
    code: "500",
    status: "FAILED",
    dur: "1.21s",
    ok: false,
    sel: false
  }, {
    time: "11:40:13.882",
    method: "POST",
    path: "/v1/events",
    dest: "http://localhost:5000/v1/events",
    code: "202",
    status: "OK",
    dur: "18ms",
    ok: true,
    sel: false
  }, {
    time: "11:40:12.342",
    method: "POST",
    path: "/webhooks/smoke",
    dest: "http://localhost:5000/webhooks/smoke",
    code: "404",
    status: "FAILED",
    dur: "54ms",
    ok: false,
    sel: true
  }];
  const codeColor = code => {
    const n = parseInt(code, 10);
    if (n >= 500) return C.red;
    if (n >= 400) return C.yellow;
    if (n >= 200 && n < 300) return C.green;
    return C.muted;
  };
  const cols = ["Time", "Method", "Path", "Dest", "Code", "Status", "Duration"];
  const gridTemplateColumns = "auto auto auto auto minmax(0, 1fr) auto auto auto";
  const cell = {
    display: "flex",
    alignItems: "center",
    whiteSpace: "nowrap",
    minWidth: 0
  };
  const ellip = {
    overflow: "hidden",
    textOverflow: "ellipsis"
  };
  const badge = (text, c) => <span style={{
    display: "inline-flex",
    alignItems: "center",
    padding: `${u(1.5)} ${u(5)}`,
    fontSize: u(10),
    fontWeight: 700,
    letterSpacing: "0.02em",
    color: c,
    background: tint(c, 20)
  }}>
      {text}
    </span>;
  const keybinds = [["↑/k", "up"], ["space", "detail"], ["c", "copy"], ["ctrl+l", "clear"], ["q", "quit"]];
  const count = (mark, n, c) => <span style={{
    display: "inline-flex",
    alignItems: "center",
    gap: u(4),
    padding: `${u(1.5)} ${u(6)}`,
    fontSize: u(10),
    fontWeight: 700,
    color: c,
    background: tint(c, 20)
  }}>
      <span>{mark}</span>
      <span>{n}</span>
    </span>;
  return <div className="not-prose" style={{
    width: "100%"
  }}>
      {caption && <div style={{
    display: "flex",
    alignItems: "center",
    gap: "8px",
    marginBottom: "12px",
    fontSize: "11px",
    fontWeight: 600,
    letterSpacing: "0.04em",
    textTransform: "uppercase",
    color: "var(--fd-muted)"
  }}>
          <span className="fd-pulse" style={{
    width: "8px",
    height: "8px",
    background: "var(--fd-accent)"
  }} />
          {caption}
        </div>}

      <div style={{
    containerType: "inline-size",
    width: "100%",
    aspectRatio: "720 / 470",
    boxSizing: "border-box",
    display: "flex",
    flexDirection: "column",
    padding: u(18),
    fontFamily: MONO,
    color: C.text,
    background: C.bg,
    border: `1px solid ${C.border}`,
    overflow: "hidden"
  }}>
        {}
        <div style={{
    display: "flex",
    flexDirection: "column",
    gap: u(7),
    padding: `${u(11)} ${u(14)}`,
    border: `1px solid ${tint(C.accent, 55)}`
  }}>
          <div style={{
    display: "flex",
    alignItems: "center",
    gap: u(9),
    fontSize: u(11.5)
  }}>
            <span className="fd-pulse" style={{
    width: u(7),
    height: u(7),
    borderRadius: "9999px",
    background: C.green,
    flex: "0 0 auto"
  }} />
            <span style={{
    color: C.muted
  }}>Listening on</span>
            <span style={{
    padding: `${u(1.5)} ${u(7)}`,
    color: C.text,
    background: C.chip,
    border: `1px solid ${C.chipBorder}`
  }}>https://nuvera-dev.bucket.repost.sh</span>
          </div>
          <div style={{
    display: "flex",
    alignItems: "center",
    gap: u(9),
    fontSize: u(11.5),
    paddingLeft: u(16)
  }}>
            <span style={{
    color: C.muted
  }}>Forwarding to</span>
            <span style={{
    padding: `${u(1.5)} ${u(7)}`,
    color: C.text,
    background: C.chip,
    border: `1px solid ${C.chipBorder}`
  }}>http://localhost:5000</span>
          </div>
        </div>

        {}
        <div style={{
    display: "grid",
    gridTemplateColumns,
    columnGap: u(13),
    rowGap: u(7),
    marginTop: u(15),
    fontSize: u(11)
  }}>
          {}
          <span />
          {cols.map(c => <span key={c} style={{
    ...cell,
    color: C.muted,
    fontWeight: 700,
    letterSpacing: "0.03em"
  }}>{c}</span>)}
          {}
          <div style={{
    gridColumn: "1 / -1",
    height: "1px",
    background: C.border,
    margin: `${u(7)} 0`
  }} />
          {}
          {rows.map((r, i) => [<span key={`g${i}`} style={{
    ...cell,
    color: C.accent,
    fontWeight: 700
  }}>{r.sel ? "▶" : ""}</span>, <span key={`t${i}`} style={{
    ...cell,
    color: C.muted
  }}>{r.time}</span>, <span key={`m${i}`} style={cell}>{badge(r.method, C.blue)}</span>, <span key={`p${i}`} style={{
    ...cell,
    ...ellip,
    color: C.text
  }}>{r.path}</span>, <span key={`d${i}`} style={{
    ...cell,
    ...ellip,
    color: C.muted
  }}>
              <span style={{
    color: C.text
  }}>Local</span>
              <span style={{
    margin: `0 ${u(6)}`
  }}>→</span>
              {r.dest}
            </span>, <span key={`c${i}`} style={cell}>{badge(r.code, codeColor(r.code))}</span>, <span key={`s${i}`} style={{
    ...cell,
    color: r.ok ? C.green : C.red,
    fontWeight: 700
  }}>{r.status}</span>, <span key={`u${i}`} style={{
    ...cell,
    color: C.muted
  }}>{r.dur}</span>])}
        </div>

        {}
        <div style={{
    flex: 1,
    minHeight: u(36)
  }} />

        {}
        <div style={{
    display: "flex",
    flexDirection: "column",
    gap: u(8),
    paddingTop: u(11),
    borderTop: `1px solid ${C.border}`
  }}>
          <div style={{
    display: "flex",
    alignItems: "center",
    gap: u(11),
    fontSize: u(11)
  }}>
            <span style={{
    padding: `${u(2)} ${u(7)}`,
    fontWeight: 700,
    fontSize: u(10),
    letterSpacing: "0.04em",
    color: C.green,
    background: tint(C.green, 20)
  }}>CONNECTED</span>
            <span style={{
    color: C.text
  }}>nuvera-dev</span>
            <span style={{
    marginLeft: "auto",
    display: "flex",
    alignItems: "center",
    gap: u(7)
  }}>
              {count("✓", 3, C.green)}
              {count("✗", 2, C.red)}
              <span style={{
    color: faint,
    fontSize: u(10)
  }}>… 0</span>
            </span>
          </div>
          <div style={{
    display: "flex",
    alignItems: "center",
    gap: u(16),
    fontSize: u(11)
  }}>
            <span style={{
    display: "flex",
    alignItems: "center",
    gap: u(15)
  }}>
              {keybinds.map(([k, d]) => <span key={k} style={{
    display: "inline-flex",
    gap: u(5)
  }}>
                  <span style={{
    color: C.text,
    fontWeight: 700
  }}>{k}</span>
                  <span style={{
    color: faint
  }}>{d}</span>
                </span>)}
            </span>
            <span style={{
    marginLeft: "auto",
    display: "flex",
    alignItems: "center",
    gap: u(11)
  }}>
              <span style={{
    color: faint
  }}>8cf7709</span>
              <span style={{
    padding: `${u(1.5)} ${u(7)}`,
    color: C.bg,
    background: C.text,
    fontWeight: 600
  }}>repost.sh</span>
            </span>
          </div>
        </div>
      </div>
    </div>;
};

export const CliFlow = ({caption, frame = true}) => {
  const W = 960;
  const H = 360;
  const CY = 180;
  const u = n => `${(n / W * 100).toFixed(3)}cqw`;
  const MONO = "ui-monospace, monospace";
  const uid = "cli";
  const WEBHOOK = ["M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2", "m6 17 3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06", "m12 6 3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8"];
  const SRC = {
    cx: 140,
    w: 124,
    edge: 202
  };
  const BUCKET = {
    cx: 360,
    w: 118,
    h: 150
  };
  const FWD = {
    cx: 600,
    w: 122,
    h: 152
  };
  const CLI = {
    cx: 830,
    w: 196,
    h: 170
  };
  const sources = [{
    label: "Stripe",
    swatch: "#635BFF"
  }, {
    label: "Shopify",
    swatch: "#95BF47"
  }, {
    label: "GitHub"
  }];
  const sCy = [80, 180, 280];
  const ports = [150, 180, 210];
  const wirePath = (x1, y1, x2, y2) => {
    const dx = (x2 - x1) * 0.5;
    return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}`;
  };
  const placed = (cx, cy, w) => ({
    position: "absolute",
    left: `${cx / W * 100}%`,
    top: `${cy / H * 100}%`,
    width: `${w / W * 100}%`,
    transform: "translate(-50%, -50%)"
  });
  const label = (cx, title, sub) => <div style={{
    position: "absolute",
    left: `${cx / W * 100}%`,
    top: `${286 / H * 100}%`,
    width: `${220 / W * 100}%`,
    transform: "translateX(-50%)",
    textAlign: "center",
    display: "flex",
    flexDirection: "column",
    gap: u(4)
  }}>
      <span style={{
    fontSize: u(19),
    fontWeight: 700,
    color: "var(--fd-text)"
  }}>{title}</span>
      <span style={{
    fontFamily: MONO,
    fontSize: u(13),
    color: "var(--fd-muted)"
  }}>{sub}</span>
    </div>;
  const NODE = {
    boxSizing: "border-box",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    gap: u(11),
    padding: `${u(12)} ${u(18)}`,
    fontSize: u(19),
    fontWeight: 600,
    lineHeight: 1,
    whiteSpace: "nowrap",
    color: "var(--fd-text)",
    background: "var(--fd-node-bg)",
    border: "1px solid var(--fd-node-border)",
    backdropFilter: "blur(var(--fd-blur))",
    WebkitBackdropFilter: "blur(var(--fd-blur))"
  };
  const bucket = <div style={{
    ...placed(BUCKET.cx, CY, BUCKET.w),
    height: `${BUCKET.h / H * 100}%`,
    boxSizing: "border-box",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    overflow: "hidden",
    background: "var(--fd-bucket-bg)",
    border: "1px solid var(--fd-bucket-border)"
  }}>
      <span aria-hidden="true" className="fd-shine-border" style={{
    backgroundImage: "radial-gradient(transparent, transparent, var(--fd-shine), transparent, transparent)",
    "--fd-border-width": "var(--fd-shine-width)",
    "--fd-duration": "var(--fd-shine-duration)"
  }} />
      <svg viewBox="0 0 24 24" fill="none" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{
    width: u(34),
    height: u(34),
    stroke: "var(--fd-bucket-icon)"
  }}>
        {WEBHOOK.map((d, i) => <path key={i} d={d} />)}
      </svg>
    </div>;
  const forwarder = <div style={{
    ...placed(FWD.cx, CY, FWD.w),
    height: `${FWD.h / H * 100}%`,
    boxSizing: "border-box",
    display: "flex",
    flexDirection: "column",
    justifyContent: "center",
    gap: u(16),
    padding: `${u(22)} ${u(22)}`,
    background: "var(--fd-node-bg)",
    border: "1px solid var(--fd-node-border)",
    backdropFilter: "blur(var(--fd-blur))",
    WebkitBackdropFilter: "blur(var(--fd-blur))"
  }}>
      <span style={{
    height: u(13),
    width: "70%",
    background: "var(--fd-accent)"
  }} />
      <span style={{
    height: u(13),
    width: "100%",
    background: "var(--fd-wire)"
  }} />
      <span style={{
    height: u(13),
    width: "100%",
    background: "var(--fd-wire)"
  }} />
      <span className="fd-pulse" style={{
    marginTop: u(4),
    height: u(15),
    width: u(15),
    borderRadius: "9999px",
    background: "var(--fd-accent-cool)"
  }} />
    </div>;
  const bars = [{
    w: "62%",
    c: "var(--fd-accent)"
  }, {
    w: "44%",
    c: "var(--fd-ok)"
  }, {
    w: "72%",
    c: "var(--fd-accent-cool)"
  }, {
    w: "38%",
    c: "rgba(255,255,255,0.18)"
  }];
  const terminal = <div style={{
    ...placed(CLI.cx, CY, CLI.w),
    height: `${CLI.h / H * 100}%`,
    boxSizing: "border-box",
    display: "flex",
    flexDirection: "column",
    gap: u(15),
    padding: `${u(22)} ${u(22)}`,
    background: "#0d0e12",
    border: "1px solid rgba(255,255,255,0.10)"
  }}>
      <div style={{
    display: "flex",
    alignItems: "center",
    fontFamily: MONO,
    fontSize: u(16),
    lineHeight: 1
  }}>
        <span style={{
    color: "#71717a"
  }}>$ </span>
        <span style={{
    color: "#e5e7eb"
  }}>repost forward</span>
        <span className="fd-blink" style={{
    marginLeft: u(2),
    width: u(2.5),
    height: u(18),
    background: "var(--fd-accent)"
  }} />
      </div>
      {bars.map((b, i) => <span key={i} style={{
    height: u(13),
    width: b.w,
    background: b.c
  }} />)}
    </div>;
  const solidWires = sources.map((_, i) => wirePath(SRC.edge, sCy[i], BUCKET.cx - BUCKET.w / 2, ports[i]));
  const legBucketFwd = `M ${BUCKET.cx + BUCKET.w / 2} ${CY} L ${FWD.cx - FWD.w / 2} ${CY}`;
  const legFwdCli = `M ${FWD.cx + FWD.w / 2} ${CY} L ${CLI.cx - CLI.w / 2} ${CY}`;
  const dashedLegs = [legBucketFwd, legFwdCli];
  const stage = <div style={{
    position: "relative",
    width: "100%",
    aspectRatio: "960 / 360",
    containerType: "inline-size"
  }}>
      <svg viewBox="0 0 960 360" preserveAspectRatio="none" style={{
    position: "absolute",
    inset: 0,
    width: "100%",
    height: "100%"
  }} aria-hidden="true">
        <defs>
          <pattern id={`${uid}-grid`} width="28" height="28" patternUnits="userSpaceOnUse">
            <rect width="1.6" height="1.6" style={{
    fill: "var(--fd-grid)"
  }} />
          </pattern>
        </defs>
        <rect x="0" y="0" width="960" height="360" fill={`url(#${uid}-grid)`} opacity="0.6" />

        {}
        {solidWires.map((d, i) => <path key={`sw${i}`} id={`${uid}-sw-${i}`} d={d} fill="none" strokeWidth="2" style={{
    stroke: "var(--fd-wire)"
  }} />)}
        {solidWires.map((_, i) => <rect key={`sp${i}`} x="-4" y="-4" width="8" height="8" style={{
    fill: "var(--fd-accent)"
  }}>
            <animateMotion dur="2.6s" begin={`${i * 0.35}s`} repeatCount="indefinite">
              <mpath href={`#${uid}-sw-${i}`} />
            </animateMotion>
          </rect>)}

        {}
        {dashedLegs.map((d, i) => <path key={`dl${i}`} id={`${uid}-dl-${i}`} d={d} fill="none" strokeWidth="2.5" strokeDasharray="14 14" style={{
    stroke: "var(--fd-wire)"
  }}>
            <animate attributeName="stroke-dashoffset" from="28" to="0" dur="0.9s" repeatCount="indefinite" />
          </path>)}
        {dashedLegs.map((_, i) => <rect key={`dp${i}`} x="-4.5" y="-4.5" width="9" height="9" style={{
    fill: "var(--fd-accent-cool)"
  }}>
            <animateMotion dur="1.8s" begin={`${0.6 + i * 0.5}s`} repeatCount="indefinite">
              <mpath href={`#${uid}-dl-${i}`} />
            </animateMotion>
          </rect>)}
      </svg>

      {sources.map((s, i) => <div key={`s${i}`} style={{
    ...placed(SRC.cx, sCy[i], SRC.w),
    ...NODE
  }}>
          <span style={{
    width: u(15),
    height: u(15),
    flex: "0 0 auto",
    background: s.swatch || "var(--fd-swatch-neutral)"
  }} />
          <span>{s.label}</span>
        </div>)}

      {bucket}
      {forwarder}
      {terminal}

      {label(BUCKET.cx, "Bucket", "Webhook ingress")}
      {label(FWD.cx, "Internal forwarder", "Waits for CLI listener")}
      {label(CLI.cx, "CLI to localhost", "Inspect, copy, generate types")}
    </div>;
  return <div className="not-prose" style={{
    width: "100%"
  }}>
      {caption && <div style={{
    display: "flex",
    alignItems: "center",
    gap: "8px",
    marginBottom: "12px",
    fontSize: "11px",
    fontWeight: 600,
    letterSpacing: "0.04em",
    textTransform: "uppercase",
    color: "var(--fd-muted)"
  }}>
          <span className="fd-pulse" style={{
    width: "8px",
    height: "8px",
    background: "var(--fd-accent)"
  }} />
          {caption}
        </div>}
      {frame ? <div style={{
    padding: "16px",
    background: "var(--fd-surface)",
    border: "1px solid var(--fd-surface-border)"
  }}>{stage}</div> : stage}
    </div>;
};

export const CliFeature = ({icon, title, children}) => {
  return <div className="border border-gray-100 bg-white p-5 dark:border-white/10 dark:bg-white/5">
      <div className="mb-4 flex h-10 w-10 items-center justify-center bg-gray-100 dark:bg-white/10">
        <Icon icon={icon} size={18} color="#C146FF" />
      </div>
      <div className="text-base font-semibold text-gray-950 dark:text-gray-100">{title}</div>
      <p className="mt-2 text-sm leading-6 text-gray-600 dark:text-gray-400">{children}</p>
    </div>;
};

<div className="w-full">
  <Section>
    <div className="max-w-4xl">
      <p className="text-lg leading-8 text-gray-600 dark:text-gray-400">
        The Repost CLI connects your terminal to an internal forwarder. Use it when webhook traffic should reach a development machine, when you need to inspect a live request, or when forwarding needs to be paused during operational work.
      </p>

      <div className="mt-7 repost-action-row">
        <a href="/docs/cli/quickstart" className="repost-action-primary">
          Quickstart

          <Icon icon="arrow-right" size={15} />
        </a>

        <a href="/docs/cli/local-forwarding" className="repost-action-secondary">
          Start forwarding
        </a>
      </div>
    </div>

    <div className="mt-10">
      <CliFlow />
    </div>
  </Section>

  <Section>
    <SectionTitle eyebrow="Model" title="How the CLI fits into ingestion">
      Buckets receive webhook events. Internal forwarders hold those events for a connected CLI session. The CLI delivers each event to a local HTTP endpoint and reports the outcome back to Repost.
    </SectionTitle>

    <Columns cols={3} className="gap-y-4">
      <CliFeature icon="inbox" title="Select a bucket">
        Choose the webhook stream you want to work with.
      </CliFeature>

      <CliFeature icon="route" title="Attach forwarders">
        Listen to one or more internal forwarders from that bucket.
      </CliFeature>

      <CliFeature icon="search" title="Inspect traffic">
        See request and response details as events move through your local app.
      </CliFeature>
    </Columns>
  </Section>

  <Section>
    <SectionTitle eyebrow="TUI" title="Working in the forward session">
      `repost forward` opens an interactive terminal session. Incoming events stream in as they arrive, each is forwarded to your local endpoint, and the response code, status, and duration are recorded for every attempt.
    </SectionTitle>

    <CliTui />

    <ul className="mt-8 flex flex-col gap-3 text-sm leading-6 text-gray-600 dark:text-gray-400">
      <li className="flex gap-3">
        <span className="mt-2 h-1.5 w-1.5 shrink-0 bg-gray-400 dark:bg-white/30" />

        <span>
          <span className="font-semibold text-gray-950 dark:text-gray-100">Interactive.</span> Run <code>repost forward</code> with no flags to select the bucket and internal forwarders from prompts.
        </span>
      </li>

      <li className="flex gap-3">
        <span className="mt-2 h-1.5 w-1.5 shrink-0 bg-gray-400 dark:bg-white/30" />

        <span>
          <span className="font-semibold text-gray-950 dark:text-gray-100">Non-interactive.</span> Pass <code>{"--bucket"}</code> and one or more <code>{"--forwarder"}</code> flags to start a session without prompts.
        </span>
      </li>

      <li className="flex gap-3">
        <span className="mt-2 h-1.5 w-1.5 shrink-0 bg-gray-400 dark:bg-white/30" />

        <span>
          <span className="font-semibold text-gray-950 dark:text-gray-100">Generate types.</span> Press <code>t</code> on a selected event to generate type definitions from its request body.
        </span>
      </li>
    </ul>
  </Section>

  <Section>
    <SectionTitle eyebrow="Start" title="First commands">
      Install the binary, authenticate, then connect an internal forwarder to your local service.
    </SectionTitle>

    <CodeGroup>
      ```bash macOS/Linux theme={"languages":{"custom":["/languages/repost.json"]}}
      curl -fsSL https://releases.repost.sh/cli/install.sh | sh
      repost auth login
      repost forward
      ```

      ```powershell Windows theme={"languages":{"custom":["/languages/repost.json"]}}
      irm https://releases.repost.sh/cli/install.ps1 | iex
      repost auth login
      repost forward
      ```

      ```bash Non-interactive theme={"languages":{"custom":["/languages/repost.json"]}}
      repost forward \
        --bucket stripe-prod \
        --forwarder local-webhooks
      ```
    </CodeGroup>
  </Section>

  <Section>
    <SectionTitle eyebrow="Docs" title="Build from here">
      The CLI documentation is split by task so each page stays short.
    </SectionTitle>

    <Columns cols={3} className="gap-y-4">
      <Card title="Quickstart" icon="rocket" href="/docs/cli/quickstart" cta="Get started" arrow="true">
        Install the binary, sign in, and forward your first event to localhost.
      </Card>

      <Card title="Local forwarding" icon="send" href="/docs/cli/local-forwarding" cta="Forward events" arrow="true">
        Connect internal forwarders, handle pending events, and use the TUI.
      </Card>

      <Card title="CI & automation" icon="workflow" href="/docs/cli/ci-automation" cta="Automate" arrow="true">
        Token auth, headless forwarding, and pausing forwarders during a deploy.
      </Card>
    </Columns>

    <Columns cols={3} className="gap-y-4">
      <Card title="Authentication" icon="key-round" href="/docs/cli/authentication" cta="Auth & config" arrow="true">
        Browser login, API tokens, environment auth, credential storage, and configuration.
      </Card>

      <Card title="Schema" icon="braces" href="/docs/cli/schema" cta="Contracts" arrow="true">
        Define, validate, version, and generate a type-safe SDK and JSON Schema for webhook contracts.
      </Card>

      <Card title="Command reference" icon="list-tree" href="/docs/cli/reference" cta="See commands" arrow="true">
        Review commands, flags, shortcuts, and environment variables.
      </Card>
    </Columns>
  </Section>
</div>
