Repository navigation
Future Universe Preview
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.
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.
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.
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:
- Header. "Future Universe", the project name and the changed fact ids.
- Stats. Total entries and counts per class.
- Sections by class, in this order: auto, break, manual, review, retire, code. Each section lists its cards in plan order.
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.
- Codegen cards don't show the regenerated file. Run
starchart apply --dry-runfor the list of targets, orstarchart codegenon 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-runfor the adapter's ownwould …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.
# 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 mindThe MCP Server and Claude Code Hook cover the same plan for agents. The preview is for humans who want to see it.
★ STARCHART
☠ a Space Pirate Zero joint
STARCHART Every dependency. Code to cosmos.
Guides
Concepts
- Three-Layer Model
- Facts and Entities
- Artifacts and Bindings
- Edge Types
- Node IDs
- Impact Analysis
- Lockfile and Drift
- Rollout Ordering
Authoring
Code layer
Commands & API
Adapters & engine
- Adapters Overview
- Adapter: fs
- Adapter: url
- Adapter: Stripe
- Adapter: App Store Connect
- Writing an Adapter
- Audit and Break Detection
- Apply, Revert and Journals
- Future Universe Preview
- Viewer and Serve
- Reality X-Ray
Rules & analysis
Integrations
Project