How it works

Something is a Mac app that runs your product and lets you change it from the screen. This page walks through all of it. None of it needs you to know Git, and the words it uses are the ones your developers already say.

Two canvases of the Kestrel jobs page side by side: a phone width showing jobs as cards and a desktop width showing the full jobs table, both live.
The same page as a phone and as a desktop, both running, both yours to change.

Projects

Open a folder, or import from GitHub. The assistant reads the project and works out which command starts the product, where the source lives, which files hold the design tokens, which file states the house rules, and which scripts have to pass after a change. A checklist shows each step as it goes.

Then the product opens as a draft. Save keeps the setup. Adjust is where you tell it what it missed, a step to run first or a port, and it tries again. Discard throws the draft away. None of it is kept until you save.

What it worked out is written into the project as a small .something folder, so an engineer can read it in a diff and correct it in a pull request like any other file. The next person to open the folder inherits what you approved without asking again. Which projects this Mac knows about stays on this Mac.

The setup sheet for a newly opened project: Read project, Index project and Work out how to run it are ticked, Install packages is in progress, Start the app and Test it works are still to come.
The plan comes first. No command runs until you say yes, and you watch each step as it happens.
The projects window: Kestrel opened 10 minutes ago, Plume 2 days ago, Field notes 5 days ago, with Open Project and Import from GitHub on the left.
Your projects, most recent first. The list lives on this Mac and nowhere else.
Kestrel running full screen as a draft setup, with Discard, Adjust and Save in the title bar, before anything has been saved.
The product running as a draft. Keep it, adjust it, or throw it away; nothing is saved until you say so.

The canvas

The product is the whole window. No panel holds a permanent column. The canvas sizes itself to the page so you are not scrolling inside a window inside a canvas; set a size by hand and it stops adjusting, because then it is a device you chose. Open the same page as a phone and a desktop side by side, both live. Zoom, a dotted canvas, snap to grid, measuring between elements, and page states: empty, loading, error, and lots.

The product's own dark theme shows the way your customers see it, and the panel reads each token as it resolves there.

The page content menu set to Empty, with Real, Sample, Loading, Error and Lots beside it; both canvases show the jobs list's empty state, No jobs this week.
See the page the way a new customer does. Switch to Empty and both canvases show the list with nothing in it.
The same billing scene with Kestrel in its dark theme: the Upgrade plan button selected, the Design panel reading the brand token as #469C94 in dark.
Your product in its own dark theme, so you design for the customers who use it that way. The panel reads each token as it resolves in dark.

The design panel

Press ⌘I and click. The panel shows the element's component, its text as it appears on screen, and its properties where the component exposes them. Then its appearance, read the way your code wrote it: a token is shown by its name, a width set to fill is Fill, a width that hugs its content is Hug. A property no rule sets is empty, not a number the browser computed. An inherited value is dimmed and names where it comes from; click the mark to go there. A property the component sets in code says so and sends you there.

For developers: 100% reads as Fill, fit-content as Hug,var(--space-4) as space-4, and a clamp() is shown as aclamp().

Four kinds of thing can be changed from the panel: a design token, the words on screen, a component's own properties where it is used, and a value written directly on one element. The last one is what makes everything editable, and it stays narrow on purpose. It changes what is already written there, never adds something new, and says so when a value is worked out as the product runs rather than written down.

The Upgrade plan button selected on the billing page, and the Design panel beside it: padding space-4 on both sides, background brand, corner radius radius-md, shadow shadow-xs.
Click the button and the panel reads it the way your code wrote it. Padding, background and corners are all named tokens, so a change here is a change to the system.

The assistant

The chat is scoped to what you selected. Ask for a change in words and it is shown on the product before it is written. When the request is bigger than it looks, the assistant says so and names the simpler version. When the project's rules say "tokens, not raw colours" and you asked for a raw colour, it asks which token you meant rather than guessing. It knows which files your role may change, so it says what it cannot do instead of proposing something that gets refused later.

The Chat tab: the person asked to round the corners a little more, and the assistant proposes changing the medium radius token from 8px to 12px everywhere it is used, with Hold to compare, Discard and Apply.
You asked for rounder corners. The assistant found the one token every corner shares and proposes changing that, so the whole product changes together. Hold to compare before you decide.
The Kestrel invoices page on the canvas with two overdue rows tinted red, and a Chat thread asking whether the overdue rows can stand out more, with the assistant's answer.
Ask about what you see. Here, whether the overdue invoices could stand out more, and the assistant's answer, on the page it is about.

Changes and branches

Your first change on the shipping branch starts a branch of your own, named for what you touched ("Primary button background"), never for a hex value. The Changes tab lists each change as a row: the element, the property, the old value and the new, and its state. Undo is a word on the row. ⌘Z takes back the last step. History shows every step and Go Back restores one.

Apply to sits beside the change: just this one, all six in the sidebar, all twelve on this page, every button. The default is this one. Change your mind after it is written and the change is taken back and written again at the new reach.

Branches live in the title bar. The menu shows the one you are on, the ones in review with their pull request state read from GitHub, the shipping branch under its own name, and finished work folded under Done. No branch is deleted without you confirming.

Undo is real, even after the code was written. ⌘Z takes the heading back to its old size and the row says so.
The branch menu in the title bar: Billing heading size, draft, 2 changes; New job button label, in review; main, the live version; and Done, 3, folded.
Your branches, in the title bar. The one you are on, the one a developer is reviewing, the live version, and finished work folded away.
The History list: The Billing heading is one step larger, The plan price now uses the brand colour, and Before any changes, each with a thumbnail of the page.
Every step you took, newest first, each with a picture of the page as it was. Go back to any of them.

Send for Review

The sheet opens with the title and summary already written from your changes. Below them, the changes that go, each with its old and new value and its page. Notes are optional. Send makes the pull request and shows its number. If it could not be sent, it says why and keeps everything on the branch, so nothing is lost.

The pull request body has the summary, what changed with values and pages, your notes, where to look, which checks ran, and for a linked design system, which pull request this one depends on.

Pull requests go out under your own GitHub login. The first time, the app asks you to connect GitHub; it opens in your browser, you approve, and that is the last time it asks.

The Send for Review sheet with the title already written, Larger heading and brand-coloured price in Billing, a two-sentence summary, and the two changes listed with old and new values: price colour ink to brand, heading size text-xl to text-2xl.
Written for you from what you changed, and yours to edit.
Send for Review finished: Pull request #42, Larger heading and brand-coloured price in Billing, with Open on GitHub and Done.
Sent. The pull request is on GitHub, and its number is here so you can find it.

Checks

Your change is already on screen before it is written, so the checks run against what you see. What they look for: anything that disappeared, text on top of text, words cut off, a control smaller than 24 by 24, something off the edge, a page that started scrolling sideways, and contrast. Then the questions in the order that matters: does it still work, what does it cost the system, is there a simpler way.

A text change on the See all plans button waits in the Changes tab with a red Changes behaviour chip, opened to show that the exact words are also matched in e2e/plans.ts and src/funnel.ts, with Discard as the only action.
You changed a button's words, but a test and an analytics event still look for the old ones. This is the one check that stops rather than warns, and it waits for a developer.
A Needs an answer card for the primary button: background brand changed to #5C3CD4, with a note that the colour is off the scale, and the choices Write anyway or Discard.
A colour that is on nobody's scale waits with a note. Pick a token, or say write it anyway.

Comments

Draw a comment around any area of the product. It stays pinned to the element it was drawn on, re-anchors when the page changes, and lives in a panel with threads and resolution. Comments are kept on your Mac for now; they do not travel with the branch yet.

The component editor

Open a component from the panel. It is shown in its real context with its real props, and beside it every size by every state (default, hover, focus, pressed, disabled) by light and dark, with long and empty text to see what breaks. A state the stylesheet never styled says "No style". Under it, every file and line the component is used from. Keep writes your edits through the same Changes pipeline, at the reach you choose.

Two limits worth knowing. Props as controls need the component's types to be readable (plain unions, booleans and cva-style variant maps), and a production build shows states and schemes but not props.

The component editor on PrimaryButton: sizes sm, md and lg across, Default, Hover, Pressed and Focus down, No style under every Focus cell.
One button at every size and in every state, from the code. Where nobody wrote a focus style, it says No style rather than inventing one.
The component editor on GhostButton: sizes by states on the left, and on the right its Used in list with UpgradePanel.tsx line 55, DashboardPage.tsx line 38 and JobCard.tsx line 31 opened to show its props.
Everywhere this button is used, with the exact line, so you know what you are about to change before you change it. One usage opened to show the props it was given.

Linked repositories

A design system in its own repository is linked in Project Settings. A component the product installs from it is read and changed in that repository's source, shown on the product by building it, and sent for review there. Two pull requests from one branch, the system first. A monorepo needs no link.

Project Settings for Kestrel: start command, address, design tokens, house rules, checks, design system Required, and Linked repositories listing plume from github.com/kestrel-app/plume, with indexing options below.
The design system lives in its own repository and is linked here, so a change to a shared component is made at its source and still shown on your product.

Plugins

Almost everything in the app is a plugin: the AI engines, the source mapping, the checks, even Git. A plugin declares everything it can do before it runs, so you see what you are installing, and what it may do to the page has a switch. A plugin that changes the page goes through the same preview, the same questions and the same undo as your own edits.

Settings, Plugins: Claude Code on this Mac and Accessibility installed and enabled; Anthropic, Codex CLI, OpenAI, Gemini CLI and Gemini available to install.
The AI is a plugin you choose, and it is the subscription you already have. Here, Claude Code signed in on this Mac; the others are a click away.

Try it on your own product.

Not released yet. One email when the first signed build is out, nothing else. Privacy