claire vo

founder, builder, mom.
san francisco, by way of texas.

currently making chatprd.
talking to people about how they ai.
helping teams build with AI at cxo.dev.
investing in AI, dev tools, and hard things.

My homepage photo follows your cursor now

Spent today polishing this notebook: cleaning up the homepage copy, figuring out where my photo should sit, and getting it live. The fun part was turning a bitmap portrait I made in Flora into a small interaction with Codex. I look toward your cursor, and a click pulls up my hoodie and makes me wink.

Build a cursor-following portrait with Flora and Codex

The actual transparent bitmap portrait used as the base for Claire’s cursor-following homepage animation.
build-a-cursor-following-portrait-with-flora-and-codex.png
The actual transparent bitmap portrait used as the base for Claire’s cursor-following homepage animation.
Flora + GPT Image 2 + Codex computer use in Chrome + HTML / CSS / JavaScript + Next.js + Vercel

I made a black-and-white bitmap portrait of myself in Flora, then asked Codex what we could do with it. We landed on a photo that looks toward your cursor. Click it and I pull up my hoodie and wink. Try it at the top of my homepage.

The whole interaction uses six still images: front, left, right, up, down, and the wink. The browser chooses which one to show. Here’s how we built it.

  1. Pick the base portrait. I already had a bitmap version I liked in Flora. We removed the colored background accents and used the clean, front-facing cutout as the reference. This is the image the other poses needed to match.
  2. Generate the looking directions. I had Codex operate Flora in Chrome using computer use. It made image-edit nodes for the different poses, using the front portrait as the reference. We started with left and right, then added up and down. The up/down generations used GPT Image 2 at High quality, 4:3, and 2k. The prompts asked for small changes to the head and eyes while preserving my face, smile, hair, hoodie, lighting, crop, and position in the frame.
  3. Make a separate click reaction. For the wink, Codex used the same front-facing reference and asked for the hood of my existing hoodie to be up, with one eye closed. No raised hands or new outfit. Keeping the face and shoulders in the same position made it possible to switch to this image without the whole portrait jumping.
  4. Remove the backgrounds and export the set. Codex used Flora’s Remove background tool, with BiRefNet General Use (Light), then downloaded the PNGs. It checked the files for real transparency; a visible checkerboard is not enough to prove the background is transparent. We ended up with six 2304 × 1728 images, named front.png, left.png, right.png, up.png, down.png, and wink.png.
  5. Try the interaction in a local preview. Codex built a small HTML, CSS, and JavaScript page with the images stacked in the same spot. Moving the pointer around the portrait changes the visible pose. A small neutral area keeps it looking forward when the cursor is near the face; a short delay and some tolerance around diagonal movements keep it from flickering between directions. Clicking shows the hood-up wink for 900 milliseconds, then returns to the current direction.
  6. Put the version I liked into the actual page. Once I’d tried the preview, Codex moved it into a small React component in my Next.js app. We placed it between my name and bio and removed the preview controls. The component serves smaller images with next/image, works with keyboard activation and taps, respects reduced-motion settings, and resets when it scrolls offscreen. Codex checked desktop and mobile, ran the app’s tests and build, and deployed it to Vercel after I approved it.

I could stay focused on the parts I cared about: whether it looked like me, which expressions were fun, and where it belonged on the page. Codex handled the repeated Flora setup, exports, and interaction code. Once the images are generated, moving the cursor doesn’t call an AI model. It just switches between saved pictures.

Below are the original up-glance and wink prompts, an adapted build prompt, and the component and CSS running on this site. To use the code in your own Next.js app, put your six PNGs in public/portraits/claire/ or change the image path, save the two source files together, and update the accessible button label for your own portrait.

Promptportrait-animation-frames.md
# Generate matching portrait frames in Flora

Setup used for the up-glance and wink frames: GPT Image 2, High quality, 4:3, 2k, quantity 1. Connect the finished front-facing portrait as the image input for each generation.

The two prompts below are copied verbatim from the Flora nodes used for this portrait. Replace the person-specific details when using your own photo.

## Upward glance — original prompt

Edit this exact finished black-and-white bitmap cutout into ONE matching animation frame. Preserve this same woman and her identity, facial proportions, warm toothy smile, hairstyle, black hoodie, precise 1990s monochrome dithering, shoulders, torso, and crop. Keep the 4:3 canvas, subject scale, head center, body position and lighting exactly aligned to the reference. Do not shift, mirror, zoom, or change camera position. Keep the surroundings completely empty with REAL transparent alpha: no checkerboard, colored graphics, symbols, text, scenery, props or shadows outside the person. The ONLY change: tilt her head slightly upward about 10 degrees and direct both eyes toward the TOP EDGE of the image, as if following a cursor just above her. This is a gentle upward glance, not looking at the ceiling. Keep the entire head and hair inside the existing crop.

## Hood-up wink — original prompt

Edit this exact finished black-and-white bitmap cutout into ONE matching animation frame. Preserve this same woman and her identity, facial proportions, warm toothy smile, hairstyle, black hoodie, precise 1990s monochrome dithering, shoulders, torso, and crop. Keep the 4:3 canvas, subject scale, head center, body position and lighting exactly aligned to the reference. Do not shift, mirror, zoom, or change camera position. Keep the surroundings completely empty with REAL transparent alpha: no checkerboard, colored graphics, symbols, text, scenery, props or shadows outside the person. Make a playful click-reaction frame: she faces straight ahead in exactly the original pose, has pulled the hood of the SAME black hoodie over her head, and gives a friendly wink with her right eye (the eye on the LEFT side of the image) fully closed while the other eye remains open. Keep the same warm toothy smile and preserve visible hair framing her face beneath the hood. No hands or arms raised. The hood is plain black fabric with the same bitmap shading, not a hat, costume or helmet. Keep her face center and shoulders in exactly the reference position.

## Complete the set

For left, right, and down, use the same front-facing reference and alignment constraints, changing only the requested head and eye direction. These instructions summarize the workflow; they are not verbatim copies of those three prompts.

Use Flora's Remove background tool on the outputs. We used BiRefNet General Use (Light). Check that the downloaded PNGs have real transparency, rather than a checkerboard painted into the image.

Keep all six canvases the same size and keep the subject aligned. Export front.png, left.png, right.png, up.png, down.png, and wink.png. Our final PNGs were 2304 × 1728.
Promptbuild-a-cursor-following-portrait.md
# Build a cursor-following portrait

Adapted from the implementation we built with Codex; not an original transcript.

I have six aligned, transparent PNGs: front.png, left.png, right.png, up.png, down.png, and wink.png. The wink frame is a special click reaction. Use these existing images without regenerating them.

First build a small local HTML/CSS/JavaScript preview. Stack the images in one fixed-size box so changing frames cannot move the surrounding layout. Show front by default, and switch among the four directional poses based on the pointer's position relative to the portrait. Keep a neutral area around the face and return to front when the pointer moves far away.

Keep direction changes from twitching: use a short settling delay and retain the previous direction near diagonal boundaries. Clicking, tapping, or activating the portrait with the keyboard should show the wink for about 900ms, then return to the current direction.

Check every frame before showing it so loading never produces a blank portrait. Disable automatic cursor following for reduced-motion preferences and touch pointers. Reset when the portrait scrolls offscreen or the browser tab becomes hidden. Clean up timers and event listeners.

Once the preview feels right, add it to the existing Next.js homepage as a small client component. Keep the rest of the page server-rendered. Place it between my name and short bio, aligned with the text, without the preview's pose controls. Use next/image to serve appropriately sized versions of the PNGs.

Check desktop and mobile layouts, all looking directions, the click/tap reaction, keyboard activation, and image loading. Run the project's checks. Show me the local result before deploying.
interactive-portrait.tsxcode
interactive-portrait.tsx
'use client';

import Image from 'next/image';
import { useEffect, useRef, useState } from 'react';
import styles from './interactive-portrait.module.css';

const poses = ['front', 'left', 'right', 'up', 'down', 'wink'] as const;
type Pose = (typeof poses)[number];

export function InteractivePortrait() {
  const portraitRef = useRef<HTMLButtonElement>(null);
  const [pose, setPose] = useState<Pose>('front');

  useEffect(() => {
    const portrait = portraitRef.current;
    if (!portrait) return;

    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
    const finePointer = window.matchMedia('(pointer: fine)');
    let visible = false;
    let desired: Pose = 'front';
    let candidate: Pose = 'front';
    let reacting = false;
    let frame = 0;
    let settleTimer: ReturnType<typeof setTimeout> | undefined;
    let reactionTimer: ReturnType<typeof setTimeout> | undefined;

    const show = (next: Pose) => {
      const image = portrait.querySelector<HTMLImageElement>(
        `[data-pose="${next}"]`,
      );
      // Keep the previous frame until the next one is ready to avoid flashes.
      if (image?.complete && image.naturalWidth > 0) setPose(next);
    };
    const look = (next: Pose) => {
      desired = next;
      if (reacting || candidate === next) return;
      candidate = next;
      clearTimeout(settleTimer);
      settleTimer = setTimeout(() => show(desired), 65);
    };
    const reset = () => {
      cancelAnimationFrame(frame);
      clearTimeout(settleTimer);
      clearTimeout(reactionTimer);
      reacting = false;
      desired = candidate = 'front';
      setPose('front');
    };
    const follow = (event: PointerEvent) => {
      if (
        !visible ||
        document.hidden ||
        reducedMotion.matches ||
        !finePointer.matches ||
        event.pointerType === 'touch'
      )
        return;
      cancelAnimationFrame(frame);
      frame = requestAnimationFrame(() => {
        const box = portrait.getBoundingClientRect();
        const dx = event.clientX - (box.left + box.width / 2);
        const dy = event.clientY - (box.top + box.height * 0.39);
        const x = Math.abs(dx);
        const y = Math.abs(dy);
        if (Math.hypot(dx, dy) > 380 || (x < 30 && y < 26)) {
          look('front');
          return;
        }
        // A little hysteresis keeps diagonal movement from flickering.
        const vertical = desired === 'up' || desired === 'down';
        if (y > Math.max(36, x * (vertical ? 0.82 : 1.12)))
          look(dy < 0 ? 'up' : 'down');
        else if (x > 40) look(dx < 0 ? 'left' : 'right');
        else look('front');
      });
    };
    const wink = () => {
      const image =
        portrait.querySelector<HTMLImageElement>('[data-pose="wink"]');
      if (!image?.complete || !image.naturalWidth) return;
      clearTimeout(settleTimer);
      clearTimeout(reactionTimer);
      reacting = true;
      show('wink');
      reactionTimer = setTimeout(() => {
        reacting = false;
        candidate = desired;
        show(desired);
      }, 900);
    };
    const onVisibilityChange = () => {
      if (document.hidden) reset();
    };
    const observer = new IntersectionObserver(([entry]) => {
      visible = entry.isIntersecting;
      if (!visible) reset();
    });

    observer.observe(portrait);
    portrait.addEventListener('click', wink);
    document.addEventListener('pointermove', follow, { passive: true });
    document.addEventListener('pointerleave', reset);
    document.addEventListener('visibilitychange', onVisibilityChange);
    reducedMotion.addEventListener('change', reset);
    finePointer.addEventListener('change', reset);

    return () => {
      observer.disconnect();
      cancelAnimationFrame(frame);
      clearTimeout(settleTimer);
      clearTimeout(reactionTimer);
      portrait.removeEventListener('click', wink);
      document.removeEventListener('pointermove', follow);
      document.removeEventListener('pointerleave', reset);
      document.removeEventListener('visibilitychange', onVisibilityChange);
      reducedMotion.removeEventListener('change', reset);
      finePointer.removeEventListener('change', reset);
    };
  }, []);

  return (
    <button
      ref={portraitRef}
      className={styles.portrait}
      type="button"
      aria-label="Make Claire wink"
      data-facing={pose}
    >
      {poses.map((frame) => (
        <Image
          key={frame}
          src={`/portraits/claire/${frame}.png`}
          alt=""
          aria-hidden="true"
          width={2304}
          height={1728}
          sizes="192px"
          loading="eager"
          fetchPriority={frame === 'front' ? 'high' : 'low'}
          draggable={false}
          data-pose={frame}
          className={frame === pose ? styles.visible : undefined}
        />
      ))}
    </button>
  );
}
interactive-portrait.module.csscode
interactive-portrait.module.css
.portrait {
  position: relative;
  display: block;
  width: 192px;
  aspect-ratio: 4 / 3;
  /* Offset the transparent inset so the portrait itself aligns with the text. */
  margin: -0.375rem 0 0.75rem -1.5625rem;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  visibility: hidden;
  user-select: none;
  -webkit-user-drag: none;
}

.portrait img.visible {
  visibility: visible;
}

.portrait:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 5px;
  border-radius: 2px;
}

Moving off WordPress and adding eight new game worlds

Spent today testing Product Intelligence in ChatPRD, including how we bring in customer conversations from Intercom. Also got this notebook live on Sanity and Vercel and moved off WordPress. In between, I had Codex prep three more podcast photos in Flora and add eight collectible locations to a little game I’ve been building. Apparently collecting animals and auras was no longer enough.

Moving a WordPress site to Sanity and Vercel with Codex

An abstract bitmap sculpture unfolds from a dense block into an open lattice of blue, pink, green, and black-and-white tiles.
move-wordpress-to-sanity-and-vercel-with-codex.png
An abstract bitmap sculpture unfolds from a dense block into an open lattice of blue, pink, green, and black-and-white tiles.
Codex + Terminal + computer use in Chrome + Sanity + Vercel

I wanted to move clairevo.com off WordPress and make it easy for both me and my agents to write here. We had already built the new notebook in Next.js. I had Codex connect it to Sanity, import eight journal entries and twelve workflows, and deploy it to Vercel. Each workflow has its own URL and can appear in more than one journal entry.

Codex used the terminal for the code, content import, and deployment. When we needed settings in my signed-in accounts, it used computer use in Chrome. I opened the right accounts, handled sign-in, and approved publishing and the domain changes; it worked through the setup, moved the domain over, and checked the published pages, artwork, and redirects.

That took a lot of the work of moving between accounts and doing manual setup off my plate. Now an agent can create or edit a draft directly in Sanity, and I can review and publish it. Writing a new post doesn’t mean opening a pull request or rebuilding the app.

Generating collectible game worlds and adding them to a working game

An original generated game location: a golden observatory on floating islands beneath a star-filled sky.
generate-collectible-game-worlds-with-codex.png
An original generated game location: a golden observatory on floating islands beneath a star-filled sky.
Codex + Image generation + Vercel

A little game I’ve been building already had collectible animals and auras, but it needed more things to earn. I asked Codex to add locations: illustrated places players could unlock and use as the background for their companion. It generated eight worlds and added them to the existing rewards and collection screens.

The locations share a bright fantasy style, but each has its own scene. There’s the floating observatory shown here, a crystal cove, and a rainbow railway through the clouds. Codex used image generation for the artwork and changed the game code so the locations could be earned, collected, and equipped.

Then I tried it in the game. The scenes needed to be bigger, the companion’s aura covered too much of the background, and the images looked soft at the new size. I had Codex adjust the layout and regenerate each location as its own 1672 × 941 landscape. We also made undiscovered locations stay hidden until they were earned.

The useful part was being able to go from “we need more things to collect” to new artwork and a working reward category in the same conversation. I could react to how it actually looked and behaved, while Codex handled the images, code changes, and deployment.

ChatPRD Product Intelligence, 131 photos, and Monday’s podcast

Spent today on Product Intelligence in ChatPRD: connecting sources and making it easier to get useful insights out of them. Also worked through a bug in prototype chats. In between, I had Codex edit 131 event photos in Lightroom, clear space on my very full laptop, and get Monday’s How I AI posts scheduled in Sanity. A mix of product work and all the other stuff that still needs to get done.

Bulk edit crops, lighting, and red-eye in Lightroom with Codex computer use

A bitmap photo laboratory with a lily being enlarged, cropped prints, and an editing screen.
lightroom-photo-lab.png
A bitmap photo laboratory with a lily being enlarged, cropped prints, and an editing screen.
Codex + computer use + Lightroom

I had 131 event photos to clean up. I opened them in Lightroom and asked Codex to straighten the shots, improve the crops, and fix red-eye. It used computer use, looking at the screen and clicking through the desktop app.

  1. Adjust the lighting across the batch so the photos have a consistent starting point.
  2. Review each photo individually for crooked horizons, awkward crops, and red-eye. Those decisions need to be made photo by photo.
  3. Check the whole set after the edits, keeping the changes reversible in Lightroom.

It reviewed all 131. I could hand off the repetitive editing while keeping the photos in the app where I’d normally review them.

Promptphoto-polish.md
# Photo polish

Use computer use to work in the Lightroom desktop app I have open. Review the selected event photos, keeping edits reversible.

## Establish the lighting

Inspect a few representative photos first. Adjust exposure, highlights, shadows, and white balance to suit the batch. Check automatic corrections before accepting them—direct-flash portraits can become too bright.

If the photos share similar lighting, copy only the appropriate light/color adjustments across them. Do not copy crop settings or localized eye corrections. Revisit photos whose lighting differs from the rest.

## Check each photo

Move through the selection one photo at a time. Straighten against visible reference lines and inspect the result. Crop awkward edges or excess headroom without cutting people out. Zoom in enough to check red-eye, apply corrections where needed, and inspect the eyes afterward.

Keep track of which photos have been reviewed so none are skipped. Do not claim every photo was individually adjusted if only shared settings were applied.

## Finish

Review the edits and check Lightroom's save/sync status. Report what changed, the number reviewed, and anything still unfinished. Do not export or share unless I ask.

Free up disk space by clearing Git worktree caches with Codex

A bitmap Git branch and folder tree with selected dependency files being dragged toward the trash.
git-worktrees-bitmap.png
A bitmap Git branch and folder tree with selected dependency files being dragged toward the trash.
Codex + shell + Git worktrees

My laptop was almost out of space. Git worktrees let me work on several branches at once, but each checkout can accumulate its own dependencies and build files. One Next.js cache alone was taking up 18.9 GiB.

  1. I asked Codex to use the terminal to find the biggest folders and explain what they contained.
  2. It checked Git status and running processes to separate my code and active work from files the tools could recreate.
  3. I picked what to remove, and Codex cleared those cache and dependency folders.

That recovered 24.7 GiB. The worktrees and uncommitted changes stayed; dependencies in the cleaned folders would need reinstalling. Having an agent investigate the folders first saved me from guessing what was safe to delete.

Promptmake-room.md
# Make room, keep the work

Help me recover disk space in the repositories and worktrees I select.

## 01. Look before touching

Measure disk usage. Identify large generated caches and reinstallable dependencies. Check Git status, ignored files, and active processes. Keep source files, local work, credentials, and databases out of the cleanup list.

## 02. Make the plan concrete

Show the exact paths, their sizes, what each contains, and whether a running process uses them. Separate cache cleanup from deleting whole worktrees. Explain what will need reinstalling or rebuilding.

Ask me to approve the exact cleanup targets and any processes you need to stop.

## 03. Clean only the approved targets

Use the narrowest appropriate operation. Never expand a target to its parent directory or delete worktrees just because their caches are large.

## 04. Verify the result

Measure the space recovered. Confirm source files and uncommitted changes are unchanged. Report any stopped processes and what I need to reinstall before running a project again.

Schedule podcast and blog posts in Sanity with Codex browser use

A bitmap publishing desk with four related page proofs passing through a press and one date marked on a calendar.
sanity-publishing-desk.png
A bitmap publishing desk with four related page proofs passing through a press and one date marked on a calendar.
Codex + computer use + Chrome + Sanity

A How I AI release includes the episode post and companion posts explaining the workflows from the conversation. Getting them all ready means finding the related drafts, checking their URLs, and scheduling each one. It’s a lot of clicking through the same CMS screens.

I gave Codex the episode and publish date, with Sanity already open in Chrome. Using computer use in that browser session, it found the three companion posts, cleaned up the URLs, and scheduled all four. I could delegate the release as one task instead of walking through each post myself.

Promptpublishing-preflight.md
# Schedule a podcast release

Use browser or computer use in the CMS session I already have open. Help me prepare and schedule the episode and related posts I select.

I will provide the episode, publish date, time, and time zone. Find its companion posts and handle the repetitive editing and scheduling work across the set.

## 01. Identify the release

Confirm the exact documents, publication date, time, and time zone. Check the current draft and schedule status of every document. Do not guess which similarly named post belongs in the release.

## 02. Review the content

Check titles, slugs, internal links, summaries, images, and required fields. Flag anything missing or inconsistent. Distinguish a saved draft from a scheduled snapshot.

## 03. Check the version that will publish

Make sure the scheduled version contains the intended draft changes. If the CMS keeps an earlier snapshot, show me what must be replaced and preserve the latest draft.

Ask for approval of the exact content and schedule before creating or replacing publication schedules, unless I have already approved them in this session.

## 04. Read it back

After the authorized scheduling action, verify each document's saved slug, scheduled version, publication date, and time zone. Report scheduled and published states separately. Note any links that will only work after publication.

The Last Roadmap, with my notes on a Kindle

The day started with the last bit of preparation for my Lenny Summit talk. I had Codex package the slides, full notes, and speaker questions into a compact set of PDFs I could take onto my Kindle.

Make a Kindle reference pack from slides and speaker notes

Speaker notes on an e-ink reader
make-a-kindle-reference-pack-from-slides-and-speaker-notes.png
Speaker notes on an e-ink reader
Codex + Keynote + PDF + Kindle Scribe + Email

Before my talk, I wanted the slides and full speaker notes together on my Kindle. I had Codex turn the deck into a compact portrait PDF, with slides on the left and notes on the right, so I could review them without flipping between files.

We landed on two or three slides per page across seven pages, plus a separate one-page sheet of speaker questions. Codex handled the extraction and layout, then emailed both PDFs to my Kindle after I confirmed the destination. It turned the materials I already had into a reference pack suited to the device I wanted to use.

How I Happy Hour screens and Lenny Summit prep

Worked on How I Happy Hour and got ready for my Lenny Summit talk. I built the event app with Codex, refined the phone form in the browser, and added a slide rotation for the room’s screens. Also got the CXO.dev postcards ready for print and cut my Keynote speaker notes down to a few cues per slide. Much easier to glance at while speaking.

Build an event screen from Figma and a slide PDF with Codex

Bitmap slides feeding a flower projection, with a compact pixel playback strip.
event-screen-pixel.png
Bitmap slides feeding a flower projection, with a compact pixel playback strip.
Codex + Figma MCP + Browser comments + Next.js + Vercel + agent-browser

For How I Happy Hour, I wanted people to share an AI workflow from their phone and see it appear on a screen in the room. I gave Codex our Figma branding and a brief, then opened the app it built and directed changes by commenting on the page in the browser.

It handled the phone form, the rotating board of submissions, and an image people could share afterward. When I added a PDF of event slides, Codex converted the pages and mixed them into the same screen rotation. I could work from the brand files and slides we already had, then give feedback on what guests would actually see.

Promptevent-screen-from-pdf.md
# Turn an event PDF into a rotating screen

Add a full-screen event page that alternates the supplied PDF slides with the app’s live board. Inspect the PDF first, skip genuinely blank pages, and preserve each slide’s aspect ratio and complete content. Convert the pages into appropriately sized browser assets without requiring me to export them one at a time.

Make the screen loop automatically. Choose sensible reading time for each type of slide, include pause and next/previous controls, and let the controls fade while the screen is playing. Keep the live board fresh between slide appearances.

Preview at the display’s resolution. Verify every slide loads, nothing is cropped, the live board appears, and the playlist returns to the beginning. Show me the complete preview. Deploy when requested, then verify the deployed screen and tell me whether already-open screen tabs need a refresh.

Rehearsal feedback and the last edits to The Last Roadmap

I was getting ready for Lenny Summit, working on the talk and event preparation. I went back through the rehearsal feedback with Codex, tightened the speaker notes, and tried editable ASCII visuals for the closing slides.

Turn rehearsal feedback into Keynote edits with Codex

Revising a presentation
turn-rehearsal-feedback-into-keynote-edits-with-codex.png
Revising a presentation
Codex + Keynote + Computer use

I gave Codex feedback from a rehearsal of The Last Roadmap and asked it to compare that with my actual Keynote deck. I wanted to know where the talk lost people and what needed to change on the slides versus in my speaker notes.

It mapped the feedback to specific slides, including a missing transition and an explanation that needed to be clearer. After we worked through the recommendations, Codex operated Keynote to update the notes. We also replaced three closing images with editable ASCII art that matched the deck’s existing black-and-white, monospaced style.

Codex saved the deck and checked the edited slides in Keynote. It removed the translation work between a loose set of rehearsal comments and a concrete edit list, then did the repetitive native-app editing. I could stay focused on what I wanted the audience to understand.

A ChatPRD newsletter and an editable character animation

Published the latest ChatPRD newsletter as a blog post, bringing over the images and embeds and adjusting the copy for the website. Also finished the animation experiment I started yesterday after seeing a character loop on X. I wanted the finished video, but I also wanted to understand how to make another one. Codex left me an editable project and a walkthrough along with the eight-second animation.

Make an editable SVG character animation with QuiverAI, CoAnimator, and Codex

Codex + QuiverAI + CoAnimator + Browser control + CoAnimator CLI

I saw this animation by @rege_dev on X and asked Codex to teach me how to make something like it. I wanted to be able to change the character’s expressions and timing after it was made.

QuiverAI generated the character as an SVG, an image made of editable shapes. Codex brought it into CoAnimator, then used the animation timeline to add blinks, head tilts, changing expressions, and sound. Keeping the character’s parts separate meant it could move the eyes or tilt the head without regenerating the drawing.

The loop below is the actual result. Along with the eight-second video, I got the source illustration, editable project, and instructions for making another one.

seekable-loop.jscode
seekable-loop.js
// Adapted timing example, not the original character project.
const duration = 8;

export function poseAt(seconds) {
  const t = ((seconds % duration) + duration) % duration;
  const phase = t / duration;
  return {
    headTilt: 8 * Math.sin(phase * Math.PI * 2),
    eyeScaleY: 1 - Math.exp(-Math.pow((t - 3.2) / 0.09, 2)),
  };
}

// Preview, scrubber, and exporter all call the same function.
// Apply poseAt(seconds) to the independently editable SVG parts.

A development Mac, newsletter prep, and the start of an animation

I worked on ChatPRD prototypes and newsletter and podcast preparation, and started an editable character-animation experiment. I also finished getting my Mac mini ready for development, with the app and a local database running there.

Set up a remote development Mac with Codex over SSH

A remote development computer
set-up-a-remote-development-mac-with-codex-over-ssh.png
A remote development computer
Codex + SSH + Tailscale + Node.js + PostgreSQL + Prisma

I wanted my Mac mini to be a development machine I could direct from my laptop. Getting SSH to connect was only the beginning: the repos, runtime, dependencies, database, and app all had to work there too.

Codex connected over SSH through Tailscale and worked through the setup on the mini. It fixed the shell environment, installed dependencies, and set up a local PostgreSQL database for ChatPRD. Then it applied the application’s migrations, generated the database client, and checked types, database reads and writes, and app startup.

I finished with a working development environment and a short connection and startup guide. The agent took care of the chain of setup chores and tested the result at the application level. I could use the laptop to direct the work and review it while the development environment lived on the mini.

Podcast portraits, AIM for agents, and a hand-tracking app

Recorded a podcast and worked on the visuals: portraits in Flora, then thumbnail options in Figma. Also played with a few ways to interact with my agents, including an AIM-style Mac app for Codex conversations and a news stream on the MiniToo. Somewhere in there I asked Codex to build a Mac app that could read hand gestures through the camera. That one needed some actual trying-it-out.

Turn podcast photos into consistent portrait assets with Codex and Flora

Three fictional portrait poses treated with matching bitmap detail and pink rim lighting.
flora-portraits-bitmap.png
Three fictional portrait poses treated with matching bitmap detail and pink rim lighting.
Codex + Computer use + Chrome + Flora + GPT Image 2

Our How I AI thumbnail designer needs good cutouts to work with. I had photos from a recording and an existing style in Flora, the image-generation board we use: a black background with purple light around the subject.

After I imported the photos, I had Codex operate Flora in Chrome using computer use. It set up an image edit for each pose, matched the lighting and background, and exported full-resolution PNGs with names our designer could understand. Later I came back with a two-person photo and had it apply the same treatment.

That took care of preparing a consistent set of source images. Our designer could start arranging the thumbnail instead of spending that time cleaning up each photo.

Promptprepare-thumbnail-portrait-sources.md
# Prepare portrait sources for a thumbnail designer

Use computer use in the open Flora board in Chrome. Inspect the existing portrait examples to understand the studio treatment before editing my supplied recording photos.

Create one image-edit node per pose. Preserve the person, expression, head angle, hand pose, and natural anatomy. Match the established background, clothing, lighting, and crop. Keep the whole head and relevant hands inside the frame with a little margin. Do not add text, logos, or thumbnail graphics.

Generate high-resolution 16:9 PNGs. Inspect each result for facial and hand errors. Export the full-resolution originals, name the files by pose, and package them with a short file list for the designer. Leave clearly named nodes in Flora so we can reuse the treatment for another photo.

Prototype a hand-tracking Mac app with Codex and Apple Vision

Dithered hands with computer-vision landmarks and a pointer between a pinching finger and thumb.
hand-tracking-bitmap.png
Dithered hands with computer-vision landmarks and a pointer between a pinching finger and thumb.
Codex + SwiftUI + Apple Vision + Computer use

I wanted to try controlling my Mac with hand gestures through the camera. I described the idea to Codex, and it built a native app using SwiftUI for the interface and Apple Vision to recognize hand positions. It included a practice area so I could test gestures before using them to control the computer.

Then I tried it. Nothing moved. I told Codex what I was seeing, and it used computer use to inspect the running app and macOS permissions, then adjusted the controls. By the end, the prototype was recognizing my pointing gesture.

The useful part was that I could try the interaction and have the same agent look at the app with me. That got the idea far enough along to test what a hand-controlled interface could feel like.

Build an AIM-style Mac interface for Codex tasks

Agent task conversations in a retro messenger
build-an-aim-style-mac-interface-for-codex-tasks.png
Agent task conversations in a retro messenger
Codex + macOS + Computer use

I asked Codex to turn my agent tasks into a Mac app that felt like a 1990s AIM buddy list. I wanted the familiar little conversation windows to show my real tasks and messages.

Codex built a standalone app around my local task history, with searchable project groups, live transcripts, favorites, and saved drafts. It installed the app, checked the native windows, and tested a real chat reply as well as queuing and canceling a message.

The result was a local prototype with a pixel bot and a very different way to browse my tasks. Codex handled both the interface and the connection to the underlying work, which made it possible to try the idea as an actual Mac app.

ChatPRD work and a playable Blender fashion studio

Between ChatPRD prototype and chat work, I asked Codex to build a fashion-design game with Blender. By the afternoon I could customize an outfit, walk it down a runway, and have the agent drive a tour while I narrated.

Turn a Blender scene into a playable fashion-design app

Editable fashion garments and pattern pieces
turn-a-blender-scene-into-a-playable-fashion-design-app.png
Editable fashion garments and pattern pieces
Codex + Blender + glTF + Chrome

I asked Codex to make a modern fashion-design game: customize an outfit, then walk around wearing it. I wanted it to use Blender, so the result would include a scene I could edit as well as an app I could play with.

Codex wrote and ran a Blender script, exported the assets as glTF, and built a browser interface around them. Dream Atelier let me change clothes, colors, fabrics, and accessories, save looks, and walk a runway or rooftop. Codex then used Chrome to try clothing changes, restore a saved outfit, and check the movement.

One agent carried the work from scene setup through export and into the interface. I didn’t have to stitch together separate 3D and web-development steps. I had a playable local prototype and the editable Blender file. You can see the fashion experiment in this later How I AI episode.

Have Codex operate a product demo while you narrate

An agent follows a demonstration sequence beside a microphone
have-codex-operate-a-product-demo-while-you-narrate.png
An agent follows a demonstration sequence beside a microphone
Codex + Chrome + Computer use

Once the fashion-design prototype worked, I wanted to record a tour. I had Codex put Chrome back on the starting screen and wait for my cue. Then it drove the demo slowly enough for me to talk over it.

It changed the outfit, showed the customization controls, saved a look, and took the character onto the runway and rooftop, with pauses along the way. That let me concentrate on explaining what we had built instead of remembering the clicks while narrating. This was the on-screen demo pass; the workflow didn’t include editing or exporting the recording.

Promptnarrated-product-tour.md
# Run a product tour while I narrate

Adapted from this workflow; not the original transcript.

Use the open browser to demonstrate [product]. First inspect the working app and propose a short sequence showing [features]. Use sample data suitable for a public recording.

Reset the app to a clean starting screen and wait for me to say go. Do not begin before my cue.

When I say go, operate the demo slowly. Pause after each meaningful change so I can explain it. Keep the cursor clear of the result where possible. If something fails, stop and tell me rather than clicking through it.

End on [desired closing state]. Leave the app there.

CXO.dev quotes, course prospects, and lead handoffs

Spent time on the business side of CXO.dev: quoting projects, organizing course prospects, and figuring out who should follow up with new leads. I turned earlier quoting work into a reusable Codex skill and sorted out how individual learners, teams, and consulting opportunities should fit together in Attio. Then I had Codex build a draft workflow to assign leads and prepare the Slack handoff.

Build an AI lead-routing workflow in Attio with Codex browser use

A hand sorting contact cards and attached notes into cubbies with colored index tabs.
attio-routing-bitmap.png
A hand sorting contact cards and attached notes into cubbies with colored index tabs.
Codex + Chrome computer use + Attio + Slack

New CXO.dev leads can be interested in a course, training for a team, or consulting. Before anyone follows up, we have to read the context and decide who should take it. I had Codex use Chrome to build a draft workflow in Attio, where we keep those leads.

  1. Gather the deal, company, contacts, and notes so the decision uses the context already in Attio.
  2. Have an AI step choose an owner using the rules I provided, explain its choice, and flag unclear cases for review.
  3. Assign the deal and send a short Slack handoff with the context and a link back to Attio.

I described how I wanted leads handled. Codex set up the fields, branches, and message variables in the browser. The goal is for someone to get a lead they can act on without first having to dig through the CRM.

Promptdraft-attio-lead-routing.md
# Draft a lead-routing workflow in Attio

Use computer use in Chrome to configure an unpublished Attio workflow for the lead handoff I describe.

First inspect the existing workflow and show how its steps connect. Use my routing rules and the exact owners I provide; do not invent either.

Configure an agent to read the triggering Deal and its linked People, Company, and Notes. Return one owner, a short reason, a review-needed flag, and one readable lead summary. Use only information supported by the linked context. Mark missing or conflicting information for review.

Order the steps as follows:
1. Enrich the lead context and choose an owner.
2. Update the Deal owner through the appropriate branch.
3. Prepare the Slack handoff with the owner, reason, review flag, concise lead summary, and a direct Attio link.

Check the saved owner fields, message variables, and workflow diagnostics. Keep the workflow unpublished. Report exactly what is configured and what still needs a live test. Do not send test messages or contact leads.

ChatPRD source setup, Slack fixes, and a tiny agent screen

Worked on ChatPRD’s Product Intelligence setup and tested how it turns source material into insights and product documentation. I wanted to go through connecting sources myself, so there was plenty of work on that flow. Also worked through issues with our Slack integration and document canvases. My side project for the day: getting a Divoom MiniToo to show what my agents were doing on a tiny screen on my desk.

Show what your AI agents are doing on a Divoom MiniToo

A tiny pixel display showing an agent update beside a stack of conversation cards.
pixel-agent-companion.png
A tiny pixel display showing an agent update beside a stack of conversation cards.
Codex + Divoom MiniToo + Python + Bluetooth

I wanted to see what my agents were doing without opening another task. The Divoom MiniToo is a little pixel display that can sit on my desk, so I asked Codex to give my agents a way to send updates to it.

I started with bugzmanov’s MiniToo toolkit and alvinunreal’s macOS project. Codex used that work to build a local command-line tool and plugin. An agent could send a short progress message, live typing, or an animation over Bluetooth. A temporary update could disappear and bring back the drawing that was there before.

I got the updates showing on the screen. Now progress could show up beside my computer while I stayed in whatever I was working on.

CXO.dev launch polish and a more useful podcast archive

I was getting CXO.dev ready to launch, polishing the site and working on the announcement alongside ChatPRD work. I also went back through the How I AI archive with Codex to make the episodes easier to discover and the archive better to browse.

Make a podcast archive crawlable with Codex

A connected podcast archive
make-a-podcast-archive-crawlable-with-codex.png
A connected podcast archive
Codex + Next.js + Chrome + GitHub

I asked Codex why How I AI episodes were hard to find in search. It checked the actual episode pages, sitemap, canonical URLs, redirects, and rendered links against the code. Two things stood out: an episode could have competing blog and podcast URLs, and most episodes were behind a button that loaded more results.

Codex fixed the duplicate routes first. When I pushed back on its initial archive design, it replaced that with normal server-rendered pagination, so people and crawlers could follow real links through the catalog. It also checked the structured data and handled a review finding before pushing the pagination change.

This gave the agent a concrete investigation across the running site and repository, followed by a change it could test. It saved me from manually comparing routes, HTML, and metadata. The result that day was a pushed change with passing local checks; I hadn’t measured any change in search traffic.

CXO.dev assessment polish, Figma colors, and reusable skills

Spent the morning simplifying CXO.dev’s AI-readiness assessment and making the results easier to understand. Cleaned up the Figma colors and started packaging repeat engineering work into Codex skills. Also kept working on ChatPRD’s Product Intelligence prototype and How I AI’s episode archive, including duplicate URLs and making the full catalog easier to find in search. A lot of making things we already have work better.

Organize Figma colors into reusable light and dark themes with Codex

Color swatches connected to matching light and dark interface fragments, with a dithered eyedropper.
figma-color-tokens-bitmap.png
Color swatches connected to matching light and dark interface fragments, with a dithered eyedropper.
Codex + Figma

A palette tells you which colors you have. It doesn’t tell you which one to use for a button, a background, or an error message. I gave Codex a copy of our Figma palette and asked it to organize the colors around those jobs.

These are called semantic tokens: a name describes what a color does, so the same background can use a light color in light mode and a dark one in dark mode. Through the Figma connector, Codex linked those names to our existing brand colors, set up both modes, and rebuilt the swatch sheet.

It created 99 tokens and connected the swatches to them. I could review how the colors should be used instead of manually creating and binding every variable.

Promptsemantic-figma-palette.md
Work in this copied Figma palette. Inspect its existing primitive and semantic color variables before making changes.

Organize colors by their jobs: backgrounds, text, borders and focus, actions, feedback, indicators, data visualization, and workflow states. Include a five-step good-to-bad scale and matching subtle backgrounds.

Reuse the existing brand colors through variable aliases. Support light and dark modes, and reuse existing semantic variables where they already fit.

Update the copied swatch sheet so the visible examples are bound to their semantic variables. Read back the result and verify the number of tokens, light/dark aliases, unbound swatches, remaining primitive labels, and clipped or overflowing content.

Report what changed and any unresolved naming or accessibility questions.

Build and test a Codex skill that checks a codebase before you start coding

Bitmap software modules arranged around a test tray, with a green check marking the selected module.
tested-agent-skills-pixel.png
Bitmap software modules arranged around a test tray, with a green check marking the selected module.
Codex + GitHub + Node.js

I wanted to reuse the checks we do when starting work on a codebase: can an agent figure out how to install it, run it, and test a change? A Codex skill is saved instructions, sometimes with helper scripts, that an agent can use again. This was one of a set I made for repeat engineering work.

  1. I asked Codex to turn those checks into a skill, including scripts to inspect the project and tests using sample repositories.
  2. I had a second agent try the skill on our own site. It found a test command that existed but wasn’t running in the automated checks.
  3. That trial also exposed a gap in the skill: it missed instructions in the parent repository. Codex fixed the scanner and added a test for that case.

The next time I start work on a project, I can ask Codex to run that skill. The instructions and checks are already there, including what we learned from trying it on our own code.

CXO.dev launch prep, The Last Roadmap, and an open-source reviewer

Split today between ChatPRD product work and getting CXO.dev ready to launch. Worked on connecting customer insights with product knowledge and planned work, built a launch-supporter list, and spent time on The Last Roadmap using last year’s keynote as a reference. Also took the code-review agent we use internally and made it a public repo other teams could adapt.

Open-source an internal code-review agent with Codex

Two bitmap patch sheets with pink and green changes, a pixel bug, and a review cursor.
pr-review-pixel.png
Two bitmap patch sheets with pink and green changes, a pixel bug, and a review cursor.
Codex + GitHub + Eve + Vercel

We had an agent at ChatPRD that reviews proposed code changes on GitHub. I wanted other teams to be able to use it, but our version assumed our codebase, our risks, and our team. I asked Codex to make it something another team could set up for themselves.

Using the terminal and GitHub CLI, it pulled out the company-specific assumptions, made the review rules configurable, and wrote a setup guide. We also included a skill that helps adapt the reviewer to a different team’s technology and priorities. Codex tested that customization against a fictional project with a different stack.

The public repo includes the reviewer and the customization instructions. That meant I could share a tool we already used with a way for people to make it useful in their own codebase.

PR review agentrepo

Prototype quality and a design benchmark I could judge myself

I spent the day working on ChatPRD prototype quality and product research, then ran another round of the How I AI benchmark. I wanted to look at the designs myself and see whether the automated judge was rewarding the same things I was.

Build a visual AI benchmark with a human judging pass

Comparing four generated designs
build-a-visual-ai-benchmark-with-a-human-judging-pass.png
Comparing four generated designs
Claude Code + Vercel AI Gateway + Chrome

I wanted to know which models could make a useful prototype, but a single design score hid too much. For this round of my How I AI benchmark, I had Claude Code separate four questions: can a model follow art direction, what does it make with almost no direction, can it organize a complicated wireframe, and can it improve an existing design without breaking it?

Claude Code changed the prompts and rubrics, ran the models through Vercel AI Gateway, and extracted their HTML into a browser review page. The run produced 40 prototypes. I could try them, score them without seeing the model names, and download my ratings. The agent handled the repeated runs and comparison-page assembly; I spent my time looking at the actual work.

Then I had it compare my ratings with the automated judge. They disagreed enough to make the judging process worth investigating. One apparently broken prototype turned out to be a problem with the review page’s iframe, which Claude Code reproduced and fixed. We ended with an adjustable comparison of human and automated scores. That was more useful to me than treating the first leaderboard as the answer.

Taking the recording light out of the browser

Alongside How I AI transcript edits and developer-environment work, I came back to the light I had connected earlier in the week. I wanted its controls in the Mac menu bar, and Codex turned the browser experiment into an app I could leave running.

Build a Bluetooth podcast-light controller and Mac app with Codex

A studio light controlled from a Mac
build-a-bluetooth-podcast-light-controller-and-mac-app-with-codex.png
A studio light controlled from a Mac
Codex + Bluetooth Low Energy + Nordic Bluetooth Mesh + SwiftUI

I had a Bluetooth light bulb nearby and asked Codex to connect to it. It first tried macOS Bluetooth settings, then scanned for Bluetooth Low Energy devices directly when the bulb did not appear. That found a Bluetooth Mesh device the normal settings screen could not pair.

Codex used Nordic’s Bluetooth Mesh tooling, wrote a local controller, and worked through a compatibility issue in the bulb’s responses. It provisioned the bulb and sent real color commands. I then asked for a podcast lighting console, and it built scenes, brightness and color sliders, a looping palette, and stop controls around the working connection.

I later asked to take it out of the browser. Codex packaged the Bluetooth helper inside a native SwiftUI menu-bar app with startup and reconnect behavior. After working through the app’s connection setup, it confirmed the bulb was responding from the menu-bar version.

This went from a device I could not see in Bluetooth settings to a control panel I could use while recording. Codex handled the protocol research, controller code, interface, and Mac packaging in the same conversation. I supplied the physical device and kept asking for the next useful version.

A visual language for CXO.dev, and better podcast posts

I worked on CXO.dev imagery and Figma foundations while bringing more of the original conversations into the How I AI archive. Codex ran image comparisons in Midjourney and helped move a small batch of transcript-backed articles through review.

Test a visual direction in Midjourney with Codex browser use

Testing a brand across different subjects
test-a-visual-direction-in-midjourney-with-codex-browser-use.png
Testing a brand across different subjects
Codex + Pinterest + Midjourney + Browser use

I gave Codex the emerging CXO.dev branding and a Pinterest board, then asked it to develop image concepts that would work for an AI transformation business. I wanted a wider range of subjects and metaphors to try across social and content posts.

Codex inspected the references, assembled a prompt bank, and operated Midjourney in the browser. It pinned style references and generated a small set of tests, then ran instruction-only versions so we could compare how much the references were helping. Seeing the same direction applied to different subjects gave me something concrete to react to.

The heavy texture was getting in the way. I pushed the treatment toward lighter imagery with readable detail, and Codex adjusted the prompts and ran more comparisons. It handled the repetitive reference setup and generation work; I could spend the time deciding which images actually belonged together.

Improve a podcast archive from transcripts with Codex and Sanity

Audio sources become article proofs
improve-a-podcast-archive-from-transcripts-with-codex-and-sanity.png
Audio sources become article proofs
Codex + Dropbox + YouTube captions + Sanity

I wanted the How I AI articles to carry more of what made the conversations useful. I had Codex go back to the transcripts, match them to the existing posts, and improve the writing with the actual steps and examples from each episode.

It gathered transcripts from Dropbox, used YouTube captions for the remaining matches, and worked through repository scripts and Sanity to prepare the revisions as drafts. The batch covered 92 articles. Codex also validated the drafts, which meant I could review the writing without manually collecting and matching every source first.

We published a small review batch of three and checked the live pages against the saved content. Those included Alex Finn’s Local AI Fleet and Designing AI Agent Loops. The rest stayed pending. The agent did the repeated transcript and CMS work; the small batch let me judge the voice and depth before releasing more.

Promptimprove-articles-from-transcripts.md
# Improve existing articles from their source transcripts

Adapted from this workflow; not the original transcript.

Inventory the existing articles and match each to its full source transcript. Use the source locations I provide. Flag missing or ambiguous matches instead of guessing.

Read the current article and any current draft before editing. Improve the article using the actual tools, steps, examples, and explanations in the transcript. Preserve names, URLs, document IDs, and slugs. Do not invent quotes, outcomes, or time savings.

Save revisions as CMS drafts using revision checks. Validate the content and maintain a simple progress record showing matched, drafted, validated, and needs-review items. Prepare a small representative review batch before proceeding broadly.

Do not publish until I approve the exact copy. After any authorized publication, check the public page against the approved content.

A podcast light that listens to my Mac

Between ChatPRD review work and How I AI production, I asked Codex to connect to a Bluetooth bulb near my desk. That became a local lighting console, followed by the much more familiar job of getting the video of the experiment ready.

Build a Bluetooth podcast-light controller and Mac app with Codex

A studio light controlled from a Mac
build-a-bluetooth-podcast-light-controller-and-mac-app-with-codex.png
A studio light controlled from a Mac
Codex + Bluetooth Low Energy + Nordic Bluetooth Mesh + SwiftUI

I had a Bluetooth light bulb nearby and asked Codex to connect to it. It first tried macOS Bluetooth settings, then scanned for Bluetooth Low Energy devices directly when the bulb did not appear. That found a Bluetooth Mesh device the normal settings screen could not pair.

Codex used Nordic’s Bluetooth Mesh tooling, wrote a local controller, and worked through a compatibility issue in the bulb’s responses. It provisioned the bulb and sent real color commands. I then asked for a podcast lighting console, and it built scenes, brightness and color sliders, a looping palette, and stop controls around the working connection.

I later asked to take it out of the browser. Codex packaged the Bluetooth helper inside a native SwiftUI menu-bar app with startup and reconnect behavior. After working through the app’s connection setup, it confirmed the bulb was responding from the menu-bar version.

This went from a device I could not see in Bluetooth settings to a control panel I could use while recording. Codex handled the protocol research, controller code, interface, and Mac packaging in the same conversation. I supplied the physical device and kept asking for the next useful version.

Assemble a recorded demo and handle its CapCut export with Codex

Finishing a recorded video
assemble-a-recorded-demo-and-handle-its-capcut-export-with-codex.png
Finishing a recorded video
Codex + CapCut + Video-processing tools + TikTok Studio

I recorded the light-bulb experiment in several clips and asked Codex to help finish the video. I wanted the full recorded sequence preserved. Once that was clear, it assembled the clips in order, kept every spoken word and the full frame, and made a vertical export with clean joins.

We also worked in the open CapCut project using computer use. Codex inspected the HDR settings and the voice-enhancement processing around the switch between camera and screen footage. The color pass still needed my correction. I made that adjustment and had it leave my grade alone for the export.

Codex then operated the export controls, checked the resulting file’s dimensions, frame rate, color space, and audio, and uploaded it to the TikTok Studio composer without posting. The useful division of work was having the agent assemble, inspect, export, and stage the video while I made the final visual call.

Promptfinish-and-verify-video.md
# Finish and verify an existing video

Adapted from this workflow; not the original transcript.

Inspect the video clips or open editor project I provide. Preserve the recorded order, spoken content, and framing unless I explicitly ask for cuts. Identify any HDR/SDR mismatch and audio processing that may affect the result. Show me a representative section before applying changes throughout the timeline.

Preserve any corrections I have made. Once the edit is approved, export for the destination I specify and inspect the actual file: dimensions, duration, frame rate, color space, video codec, and audio. Report what the file contains, not only the settings you selected.

Leave publishing to me. If I authorize an upload, stop in the destination composer before posting.

From a research sheet to a browsable directory

I kept working on the CXO.dev company research while How I AI content work continued. I wanted to see the research as something a person could browse, so I had Codex turn a sample of it into a company and people directory.

Turn a research spreadsheet into a browsable directory with Codex

Research becomes a browsable directory
turn-a-research-spreadsheet-into-a-browsable-directory-with-codex.png
Research becomes a browsable directory
Codex + Google Sheets + Vercel + Chrome

After collecting research for AI Native 100, I wanted to see how someone would explore it outside a spreadsheet. I asked Codex to turn the research into an editorial wireframe with separate company and people directories, linked profiles, and the sources behind each example.

It built filtering, profile pages, and links between people and companies. The sample included three company profiles and three people profiles. Fields we had not verified stayed visibly unfinished, so the wireframe could test the reading experience without pretending the research was complete.

Codex deployed the AI Native 100 wireframe to Vercel and checked navigation, direct profile links, filtering, and desktop and mobile layouts. I could evaluate the shape of the directory by using it. The agent handled the work between a table of research and a browsable product.

Finding companies that changed how they work

I spent the day on CXO.dev research and operating roadmaps alongside ChatPRD development. A company list turned into a much more useful question: where could we find concrete evidence that AI had changed how a team worked?

Research how companies use AI internally with Codex and Google Sheets

Research evidence cataloged as geometric specimens
research-how-companies-use-ai-internally-with-codex-and-google-sheets.png
Research evidence cataloged as geometric specimens
Codex + Google Sheets + Web search + GitHub

I started with a list of companies on GitHub and asked Codex to find out how they actually used AI inside the business. For CXO.dev, the useful examples were changes to engineering, design, and day-to-day operations. Selling an AI product did not tell me whether a company had changed how its own team worked.

Codex searched company articles and public posts, then wrote the findings into Google Sheets with source links, dates, the practice being described, and named practitioners where those were public. That gave me a research ledger I could inspect and question without opening the same pages and copying the same fields over and over.

I pushed on the evidence standard as we went. A firsthand post could earn a place on a watchlist, but an example I would hold up needed concrete mechanics, credible evidence of use, and ideally corroboration. Keeping those distinctions in the sheet made it possible to collect broadly without treating every discovery as an endorsement.

Promptresearch-internal-ai-practices.md
# Research internal AI practices

Adapted from this workflow; not the original transcript.

Starting with the company list I provide, research how each company uses AI internally. Focus on concrete engineering, design, and operating practices. Distinguish internal adoption from marketing for an AI product.

Create a reviewable table with company, practice, source URL, source date when available, public practitioner names where relevant, supporting evidence, and open questions. Prefer firsthand company or practitioner accounts. Do not invent metrics or publication dates.

Keep promising leads separate from well-supported examples. Explain the evidence needed to promote a lead. Deduplicate repeated sources and leave gaps visible. Save the research privately for review; do not contact anyone or publish it.

A How I AI trailer between prototype tests

ChatPRD prototypes and model testing continued while I got How I AI launch material ready. I gave Codex the episode recording and asked for a short cut with punchy quotes, funny moments, and enough room around each edit to keep the speech intact.

Cut a trailer from a long recording with Codex and FFmpeg

A long podcast recording cut into shorter trailers
cut-a-trailer-from-a-long-recording-with-codex-and-ffmpeg.png
A long podcast recording cut into shorter trailers
Codex + Whisper + FFmpeg

I gave Codex long recordings and asked it to find the punchy quotes and funny moments for short trailers. It used local transcription to locate possible cuts and FFmpeg to assemble and export them. The first rounds needed my direction: horizontal video, no overlays, and more cuts between speakers.

On one recording, it made three trailer options, but some edits clipped the beginning or end of a word. I asked it to leave more room around the speech, and it rebuilt the cuts with short buffers. That became part of the next brief: fast pacing still has to leave a complete thought.

For a How I AI episode, Codex used word-level timestamps to choose six moments from a 36-minute recording and assembled a 58-second cut. It kept hard visual cuts and added tiny fades at the audio edges. I supplied the editorial direction; the agent handled the initial search through the recording, the selects, the assembly, and the export.

Promptcut-a-speech-safe-trailer.md
# Cut a short trailer

Adapted from my workflow; this is not the original transcript.

Use the recording I provide to make an approximately 60-second horizontal trailer. Find punchy quotes, funny moments, and reactions that make sense without the full conversation. Preserve the original framing and sound. Do not add captions, titles, music, or overlays.

Use an existing transcript or create one with word timestamps. Build a short sequence from several parts of the recording, with enough context for each moment to land. Keep the pace quick, but preserve complete thoughts.

Listen around every edit. Leave enough audio before the first word and after the last word that no syllable or final consonant is clipped. Use small audio-edge fades where needed. Do not choose cut boundaries solely to hit an exact runtime.

Export the trailer, check its audio, video, and duration, and save the source time ranges used in the edit. Keep the original recording unchanged.

ChatPRD prototypes and a place to keep the content ideas

I spent the day on ChatPRD prototyping and model-evaluation work. In the evening, a question about who I follow on X grew into a content queue that connected public conversations with ideas from the work already happening across my projects.

Build a source-backed content queue with Codex

Source slips collected in an editorial inbox
build-a-source-backed-content-queue-with-codex.png
Source slips collected in an editorial inbox
Codex + X MCP + Granola + GitHub + Codex automations

I started by asking Codex which people I interacted with on X, then expanded the question to their companies, colleagues, and past How I AI guests. It used authenticated X tools and the podcast feed to build a watchlist. Looking only at familiar accounts missed useful people doing related work.

From there, I asked for a way to connect those public conversations with ideas from my own work. Codex created a local content store with source-linked records from project work and meeting notes, plus privacy labels to keep private material out of public drafts. It set up a morning research routine, an evening capture routine, and a weekly editorial pass. The first research digest was ready that night.

The digest suggested a few conversations where I had something relevant to contribute, with the original post and an angle to consider. Nothing posted automatically. The work I was handing off was finding the sources, connecting them, and keeping the ideas somewhere I could return to, rather than reconstructing the week whenever I wanted to write.

Promptcapture-source-backed-ideas.md
# Capture ideas from actual work

Adapted from my workflow; this is not the original transcript.

Review the work sources and public feeds I authorize for this run. Look for a small number of useful ideas grounded in something I actually did, observed, or learned.

For each idea, save a short claim, the supporting source links, what happened versus what was only proposed, why it might help a reader, and what still needs verification. Mark whether the source is public, needs anonymization, requires permission, or must remain private. Do not turn private quotes or details into public copy.

Compare with the existing queue and merge duplicates. If a relevant public conversation exists, include its original link and explain what experience I could contribute. Skip conversations where I have nothing useful to add.

Give me a short digest to review. Keep all ideas as private research or drafts; do not post, reply, like, or message anyone.

A local ChatPRD coding harness, with an explanation of its own code

A How I AI episode sent me into an experiment with a local coding harness for ChatPRD. I worked with Codex on the architecture and implementation, then asked it to turn the code into an explainer and presentation so I could see how the pieces fit together.

Build a local coding harness around existing tools with Codex

Connected tool cartridges in a local coding harness
build-a-local-coding-harness-around-existing-tools-with-codex.png
Connected tool cartridges in a local coding harness
Codex + Claude Agent SDK + Sentry + Vercel CLI + Ink

After reading our How I AI episode about Mozilla’s agent workflow, I asked Codex what a similar setup could look like for ChatPRD. The discussion moved toward a local coding harness: an application that gives a coding agent a defined task, the relevant tools, and a place to save its work. I also used Factory’s CLI as a reference while thinking through the interface.

Codex inspected the skills and command-line tools we already used, then built a terminal interface around a Claude Agent SDK worker. The harness could assemble a task brief, run readiness checks, collect available evidence, and save the worker prompt and outputs together. Investigation and code-editing modes had different permissions. I wanted the setup for a task to be repeatable, including which tools the agent should reach for first.

This got to a local implementation with checks and a browsable record of runs. Some integrations still needed configuration. The useful experiment was packaging our existing development workflow so I would not have to explain the same tools, context, and expectations at the start of every task.

Turn generated code into an HTML explainer with Codex

Software layers mapped to a branching schematic
turn-generated-code-into-an-html-explainer-with-codex.png
Software layers mapped to a branching schematic
Codex + HTML + CSS + JavaScript

Once the local coding harness existed, I asked Codex to make an HTML page explaining how the code worked, what the application added, and how someone could build something similar. It read the implementation and produced a code map and an explanation of the run loop. I pushed it to make the page more visual, with architecture diagrams and ChatPRD styling.

I also asked it to identify the interesting prompts in the code. The explainer traced the prompt builder, the generated worker prompt, the worker’s tool permissions, and the saved outputs. That gave me specific places to look when I wanted to understand how the agent was being instructed.

Codex then made a separate ten-slide HTML presentation with keyboard navigation and a link back to the explainer. Having the agent turn its implementation into something I could inspect and explain removed a separate documentation pass. My feedback went into the explanation and the diagrams while the code was still fresh.

Promptexplain-this-codebase.md
# Explain this application

Adapted from my workflow; this is not the original transcript.

Read the implementation of the application I identify. Create a standalone HTML explainer for its owner that answers:

- What does it do, and when would I use it?
- What happens from the initial input to the final result?
- Which files own the important parts?
- Where do agent prompts come from, which tools can the agent use, and where are outputs saved?
- Which parts are implemented, and which still need configuration or development?

Use diagrams for the architecture and main execution path. Link explanations to the relevant source files. Distinguish observed behavior from intended behavior. Use the application’s existing visual style where available.

Check that the page opens, its navigation works, and its diagrams and explanations match the code. Keep example data free of secrets and private customer information.

Fresh examples for the course, and a few trailer cuts

I worked on ChatPRD engineering alongside preparation for my Maven course. Codex compared the course decks with our newer writing and added comments for me to work through. I also had it cut a talk into a few trailer options, then give the words a little more room at the edits.

Update a Gamma course deck from recent writing with Codex

Course slides with source notes and annotation flags
update-a-gamma-course-deck-from-recent-writing-with-codex.png
Course slides with source notes and annotation flags
Codex + Chrome + Gamma + Git

I asked Codex to compare the two decks for my Maven course with the newsletters and articles we had written since the last version. It pulled the latest content repository, read the newer material, and opened the decks in Gamma using Chrome. I pointed it toward a few ideas I wanted to develop: software factories, the changing role of engineers, and giving agents useful company context.

Codex turned those sources into nine comments attached to specific slides. I reviewed the suggestions, approved posting them, and it added the comments in Gamma and checked that they were there. I could work through an edit list inside the deck instead of keeping articles open while hunting for the right place to use each idea.

The useful part was asking for the connection between the writing and the teaching material. “Make this more current” is a vague request. Giving the agent the actual newer work, the current slides, and a few themes produced changes I could evaluate one by one.

Promptrefresh-course-deck.md
# Refresh a course deck

Adapted from my workflow; this is not the original transcript.

Compare the course deck I provide with the newer articles, newsletters, and other source material I identify. Read the sources and inspect the actual slides.

Find specific places where a newer example, clearer explanation, or changed assumption would improve the course. For each suggestion, give the slide title, the proposed change, the source link, and a short explanation of why it belongs there. Do not force every new article into the deck.

Draft the suggestions as concise slide comments. Show me the proposed comments before posting them. After I approve them, add each comment to its corresponding slide in the presentation app and check that it appears in the right place.

Cut a trailer from a long recording with Codex and FFmpeg

A long podcast recording cut into shorter trailers
cut-a-trailer-from-a-long-recording-with-codex-and-ffmpeg.png
A long podcast recording cut into shorter trailers
Codex + Whisper + FFmpeg

I gave Codex long recordings and asked it to find the punchy quotes and funny moments for short trailers. It used local transcription to locate possible cuts and FFmpeg to assemble and export them. The first rounds needed my direction: horizontal video, no overlays, and more cuts between speakers.

On one recording, it made three trailer options, but some edits clipped the beginning or end of a word. I asked it to leave more room around the speech, and it rebuilt the cuts with short buffers. That became part of the next brief: fast pacing still has to leave a complete thought.

For a How I AI episode, Codex used word-level timestamps to choose six moments from a 36-minute recording and assembled a 58-second cut. It kept hard visual cuts and added tiny fades at the audio edges. I supplied the editorial direction; the agent handled the initial search through the recording, the selects, the assembly, and the export.

Promptcut-a-speech-safe-trailer.md
# Cut a short trailer

Adapted from my workflow; this is not the original transcript.

Use the recording I provide to make an approximately 60-second horizontal trailer. Find punchy quotes, funny moments, and reactions that make sense without the full conversation. Preserve the original framing and sound. Do not add captions, titles, music, or overlays.

Use an existing transcript or create one with word timestamps. Build a short sequence from several parts of the recording, with enough context for each moment to land. Keep the pace quick, but preserve complete thoughts.

Listen around every edit. Leave enough audio before the first word and after the last word that no syllable or final consonant is clipped. Use small audio-edge fades where needed. Do not choose cut boundaries solely to hit an exact runtime.

Export the trailer, check its audio, video, and duration, and save the source time ranges used in the edit. Keep the original recording unchanged.