BuildHow this site shipped with AI

How this site shipped with AI

Directed AI build of this portfolio — workflow, Cursor spend, and token receipts refreshed at build time from local logs.

Thanks for reading. I built this site as a recruiter-facing hub — work, CV, lab, contact — with Cursor Agent on Pro ($20/mo) doing most of the implementation while I set direction and taste. The numbers are live from local Cursor logs, not hand-edited.

Live receipts · Cursor Pro · refreshed at build

Est. API spend$120.34Cursor Pro · API estimate, not invoice
Tokens (incl. cache)138,251,15912,015,540 fresh in+out
How I steered272/123typed turns / browser picks
Agent tool calls4,60965 src files · 9,569 lines

Built with Cursor Agent on Pro —87 sessions,~272 typed turns,~123 browser picks,~4,609 tool calls,~65 files /~9,569 lines in src/.

Mostly steered via typed prompts; browser picks were secondary.

How I direct AI

Me · Product ownerAgent · Strong implementer
Intent, taste, and accept/reject — not vibe codingExecutes under constraints — not a co-author of intent
Audience, scope, and stop rulesScaffold and implementation under the brief
Kit fidelity and release readinessLocal edits from pointed browser picks
Loop: brief → build → review → correctRuns each pass inside the brief
Ship gates: adversarial review + fail-fast UISurfaces kit mismatches before release

Loop

  1. Brief

    Decide what the site must do for recruiters before any UI

    whya vague brief lets the agent invent work you never asked for

  2. Build

    Lock Astro + a living design kit first — the kit is the shared visual language the agent must copy, then fill pages from that frame

    whywithout a kit, the agent invents a new look each pass and the site drifts

  3. Review

    Read the result as a recruiter and as a senior engineer — against the kit

    whycatch taste and fidelity issues before they pile up

  4. Correct

    Click the exact UI problem in the browser and fix only that

    whysmall, pointed fixes beat vague “redesign this” prompts

Cursor usage

SessionsEst. API spendTokens (total / fresh)
87$120.34138,251,159 / 12,015,540

I build on Cursor Pro. The $ figure is Cursor’s usage export priced at API rates for conversations in this project — useful for volume, not my Pro subscription invoice. Per-conversation Cursor export stores spend only; tokens are prorated from each calendar day’s machine totals by spend share.

Agent tool mix

  • Read1,422
  • StrReplace1,084
  • Grep827
  • Shell363
  • UpdateCurrentStep255
  • Glob180
  • Write177
  • Task81

Bar length vs top tool · % of listed calls

Stack

workbenchCursor Agent (Pro)
frameworkAstro 7 (static)
contentContent collections + MDX
iconsastro-icon + Lucide / Simple Icons
designSignal Map kit — light B&W, IBM Plex Sans + Mono
hostVercel
domainhoanluu.dev
src/~65 files / ~9,569 lines (at last receipts refresh)

Milestone snapshots

Frozen totals at major updates (not every build). Delta is vs the previous milestone.

WhenMilestoneEst. $TokensΔ est. $Δ tokens
Initial ship — blog + live receiptsFirst public receipts + milestone history$75.7768,388,104
System Map hover + messagingVerified hover copy; Kafka/BullMQ messaging; AI personal workflow; ops stack$111.95121,071,105+$36.18+52,683,001
Polish About + blog receipts$120.34138,251,159+$8.39+17,180,054

Generated Aug 3, 2026, 2:24 AM · sources: cursor-events, cursor-transcripts · run npm run receipts (also on prebuild) · major updates: npm run receipts:snap -- "label"

What I am not claiming

  • I did not type every line by hand. I directed product and taste; the agent wrote and rewrote most of the surface.
  • Design was not one-shot. The Signal Map kit and homepage went through many visual revisions.
  • I am on Cursor Pro. The dollar figure is an API-priced estimate from Cursor’s usage export (what that volume would cost on usage billing) — not my Pro subscription invoice.
  • Cursor tokens for a conversation are prorated from day totals by spend share (the per-chat export stores dollars more cleanly than tokens).
  • Live totals refresh on npm run receipts / prebuild. Major ships freeze a row via npm run receipts:snap -- "label".