Pearl

Your day changes. So does Pearl. Talk for a minute, and it builds the tools you need today, turning what’s on your mind into clear next steps and useful tools.

Inspiration

Pearl began with a simple problem: planning tools often ask overwhelmed people to do more planning.

A person must capture every concern, rank it, split large tasks, schedule each step, and keep the plan current. For someone who already struggles to start or choose, setting up the system can become another burden.

I wanted to ask less of the person. Instead of making them fill out a fixed planner, Pearl begins with one minute of natural speech. It then builds the tools that fit that day.

The goal was for Pearl to create a small, usable interface instead of another chat response: a timer when starting feels hard, rehearsal cards before a tense meeting, a decision aid when choices feel heavy, or a place to defer a concern that cannot be handled yet.

What it does

Pearl turns a spoken reflection into a native interface for the day.

The person speaks for up to 60 seconds. Pearl combines the transcript with trusted context from their calendar and Apple Health. It then creates a day with:

  • one clear Now;
  • up to two Next tools;
  • an optional Held area for concerns that do not need attention yet;
  • real calendar events placed on a live day view;
  • controls chosen for the person’s needs.

Pearl can generate timers, checklists, scales, notes, scripts, breathing tools, rehearsal cards, decision aids, symptom check-ins, and small first steps.

The interface remains useful after Pearl builds it. When the day changes, the person can say what happened. Pearl rebuilds the work that remains without resetting completed actions.

At the end of the day, Pearl asks whether each unfinished item should move to tomorrow or be released. Repeated choices become Patterns. If someone often makes a first step smaller, for example, Pearl begins with shorter steps on later days.

How I built it

I built Pearl as a native SwiftUI app.

Apple Speech transcribes the reflection on the device. EventKit supplies calendar events. HealthKit can supply facts such as sleep and recent workouts.

The main technical work is the generated interface.

At runtime, Pearl asks Auri’s composition service for an AuriUI document. It describes the generated part of the day: which native controls to use, their content and order, and their Now / Next / Held roles. Pearl checks the document, maps it to prebuilt SwiftUI views, and saves user state by interaction ID. No generated Swift code runs on the device.

For example:

screen today "A clearer start" "Tuesday"
arc "The shape of today" id:day_arc
item "Design review" at:"12:00 PM" fixed
first "Open the deck and title one slide" id:review_start seconds:90
support id:review_start role:now intent:initiate smaller:"Open the deck" seconds:30

AuriUI uses one line for each part of the interface. Pearl can parse and show each valid line as it arrives. The format uses about one-eighth as many tokens as our earlier JSON format for the same interface.

Each accepted line maps to a tested SwiftUI view. The app controls layout, accessibility, timers, choices, clock positions, saved state, and actions. Pearl gains the range of generated UI without running generated code.

A local policy check runs before anything reaches the screen. It removes invented times, unsupported personal claims, unsafe content, duplicate IDs, and screens that are too large. It also enforces rules such as showing exactly one Now.

Each control has a stable ID. Pearl saves choices, notes, timer progress, completed actions, deferrals, and requests to make a step smaller. During a later rebuild, Pearl restores that state and puts back any completed control that the new result left out.

I used Codex with GPT-5.6 Sol throughout development. It helped me build the streaming parser, SwiftUI renderer, state system, policy checks, test suite, calendar logic, and day-close flow. I made the main product choices ourselves, then used Codex to apply those rules across the app and turn failures into tests.

Challenges I faced

Making generated UI useful

A model can produce many controls, but more controls do not make a better product. Pearl needed to choose the smallest interface that could help.

I created a clear set of purposes, including starting, deciding, preparing, calming down, remembering, and deferring. I also added the Now / Next / Held structure so each generated screen has a clear order.

Keeping the interface grounded

Generated personal advice can sound certain even when it lacks a source. Pearl checks visible claims against the person’s words, calendar, or trusted device data.

Exact times must come from the person or EventKit. Health values must come from HealthKit. High-risk reflections stay on the device and show fixed, reviewed support text.

Preserving state during a rebuild

Generating the first screen was only part of the problem. Pearl also had to change that screen after the person had used it.

A new result might leave out a timer that the person had already completed. I solved this by saving state under stable IDs, restoring completed controls, and checking the combined document again.

Mixing model choices with fixed rules

The model should choose the right tool, but it should not control facts, time calculations, safety rules, or saved state.

So the model proposes the interface; the app owns truth and behavior.

Streaming without broken screens

Pearl needed to show useful controls quickly without waiting for a full response. It also needed to survive incomplete or bad output.

The parser reads one line at a time. A bad line is dropped by itself, while valid parts continue to render. If the service fails, Pearl saves the recording and shows a fixed local fallback.

What I learned

A useful generated interface must keep state, respond to new facts, survive failures, and remain clear after several changes. Without those parts, generated UI is only a demo.

I learned that a small interface language works better than generated code. The model gets enough freedom to choose the right experience, while the app keeps control of safety, accessibility, data, and behavior.

Finally, actions are more useful than guesses. Pearl learns from what the person completed, deferred, released, or made smaller. It does not need to invent a profile or claim that one event caused another.

What I'm proud of

Pearl is both a useful app and a serious test of generative UI.

It helps a person decide what to do now. At the same time, it shows that a generated interface can stream, use native controls, save state, change with new input, and stay tied to trusted facts.

The result is a planner that builds the tools each day requires and keeps them useful after the first screen.

Built With

Share this project:

Updates