Skip to content

Future Universe Preview

Greg Chambers edited this page Sep 29, 2026 · 1 revision

Before you let apply loose, look at the universe it will create. starchart preview renders the pending plan as one self-contained HTML report: before/after copies of every file fs would write, freshly rendered images side by side, unified diffs, and a card for every manual, review, retire and code item with the path explaining why it's impacted. Nothing in your repo or in any external system is touched. This page covers what it renders, where it writes, and a walkthrough on the demo after a price change.

Source: engine/preview.ts.

Usage

starchart preview                    # writes .starchart/preview/index.html
starchart preview -o /tmp/future     # somewhere else
Option Default Meaning
-o, --out <dir> .starchart/preview Output directory, resolved against the project root. Created if missing.

The preview is built from the same plan as starchart plan and apply (planFromLock: everything still out of sync with starchart.lock). After a partial apply or an ack, it shows only what's left. Nothing is journaled and the lock isn't touched. Files from an earlier run in the output directory are overwritten, not cleaned up. You'll probably want .starchart/preview/ in .gitignore.

What it renders

Every plan step becomes one entry. What the entry shows depends on its class and adapter:

Step Entry kind Rendered as
auto + fs, text file text before.<ext> and after.<ext> copies plus a unified diff (3 lines of context)
auto + fs, .png / .svg output image before / after files plus both images inlined side by side. A missing "before" shows does not exist yet.
auto + any other adapter (Stripe, or an App Store text field, with write: true) external A card that says synced through the <adapter> adapter on apply. No live data is fetched, so no API calls happen.
auto generated constant (codegen) external A card that says regenerated by starchart codegen on apply. The generated file isn't previewed.
manual, review, retire, code, break task A card with the reason and the why-path

For fs, the preview calls the same computeFsUpdate() that apply and template audits use, in dry mode. The diff you see is exactly what apply will write. If apply would refuse (an ambiguous old value, a list item with no place to go, an old value that isn't found), the card shows that error in red instead of a diff, and you've caught a failure before it stopped a real apply.

Every card has:

  • the label and id
  • a class tag (green for auto) and an adapter tag
  • the target path, for fs
  • the reason (replace embedded value, value is burned into media, …)
  • a why line: the explanation path from the changed fact, e.g. addon:pro.price.usd --embeds--> email:onboarding-day-3
  • the change summary, for fs

Test items (test class) are not plan steps, so they don't appear in the preview. starchart plan lists them.

The report

index.html is a single file with inline CSS. Images are embedded as data: URIs. Its Content Security Policy is default-src 'none'; img-src data:; style-src 'unsafe-inline': no scripts, no network. It opens from disk and is safe to attach to a PR or send to someone who has never heard of STARCHART.

Layout:

  1. Header. "Future Universe", the project name and the changed fact ids.
  2. Stats. Total entries and counts per class.
  3. Sections by class, in this order: auto, break, manual, review, retire, code. Each section lists its cards in plan order.

Walkthrough: the demo after a price change

In a copy of examples/pro-universe, change usd: 4.99 to usd: 5.99 in .starchart/entities/pro.yaml, then:

$ starchart preview
✓ 15 preview entries → .starchart/preview/index.html

Files written:

.starchart/preview/index.html
.starchart/preview/files/email_onboarding-day-3/before.md
.starchart/preview/files/email_onboarding-day-3/after.md
.starchart/preview/files/web_messages-en/before.json
.starchart/preview/files/web_messages-en/after.json
.starchart/preview/files/web_pricing-page/before.tsx
.starchart/preview/files/web_pricing-page/after.tsx
.starchart/preview/files/web_og-pro/after.png

Folder names are artifact ids with anything outside [A-Za-z0-9._-] replaced by _. web:og-pro has no before.png because the demo has never rendered its OG image, so its card shows "does not exist yet" next to the fresh 22 KB render.

The report's header reads pro-universe · changed: addon:pro.price, addon:pro.price.usd, and the stats show 15 artifacts: 6 auto, 5 manual, 1 review, 1 retire, 2 code.

The auto section:

Card Shows
email:onboarding-day-3 a diff (below)
web:messages-en a diff of the JSON string table
web:pricing-page a diff of page.tsx: <p className="price">$4.99 / month</p> → $5.99
web:og-pro before (does not exist yet) / after PNG side by side
symbol:ios/StarchartFacts.AddonPro.Price.usd, symbol:web/lib/starchart-facts#ADDON_PRO_PRICE_USD external cards for the codegen constants: "regenerated by starchart codegen on apply; preview shows no live data"

The email diff, as rendered:

--- a/marketing/emails/onboarding-day-3.md
+++ b/marketing/emails/onboarding-day-3.md
@@ -1,4 +1,4 @@
 # Day 3: unlock the whole galaxy
 
-Nebula Pro gives you every theme and sync across devices for $4.99 a month.
+Nebula Pro gives you every theme and sync across devices for $5.99 a month.
 

The rest are task cards:

Section Cards
manual · 5 stripe:price/pro-monthly (update in stripe, adapter is read-only), appstore:iap/pro-monthly, appstore:listing/description, appstore:screenshots/6.9/03 (value is burned into media), web:live-pricing
review · 1 web:landing-hero (describes this semantically)
retire · 1 reel:spring-2026 (expired 2026-06-30)
code · 2 symbol:ios/Pricing.proUSD (hardcoded value anchors this fact), symbol:web/lib/stripe#PRICE_PRO_MONTHLY (holds this artifact's external id)

Why-paths in the report look like why: addon:pro.price.usd --embeds--> web:messages-en.

Run apply --yes and preview again, and only the leftovers remain:

$ starchart preview
✓ 9 preview entries → .starchart/preview/index.html

5 manual, 1 review, 1 retire, 2 code. The applied files and the codegen constants are gone, matching starchart plan and check.

Known rough edges

  • Codegen cards don't show the regenerated file. Run starchart apply --dry-run for the list of targets, or starchart codegen on a scratch copy to see the output.
  • External cards don't preview remote state. A Stripe card won't show the new price id or current amount. Use starchart apply --dry-run for the adapter's own would … description.
  • Large text diffs: if the changed middle of a file is bigger than about 4 million line pairs, the diff falls back to a block replacement instead of a line-level LCS.

Where it fits

# edit a fact
starchart plan          # what's impacted, in what order
starchart preview       # what the files will look like
starchart apply         # do it (journaled)
starchart revert <id>   # changed your mind

The MCP Server and Claude Code Hook cover the same plan for agents. The preview is for humans who want to see it.

See also

Clone this wiki locally