fimo 0.9.0-experimental.10 → 0.9.0-experimental.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,34 +86,99 @@ unbound pages in the generated prompt. Your job:
86
86
  6. Verify: `npx fimo pages list --expand` materializes every instance —
87
87
  each page the site's nav links to must appear as a real URL.
88
88
 
89
- ## Shared chrome → Single Types (the content-model rule)
89
+ ## Content model — Collection vs Single vs Component (the decision rule)
90
90
 
91
- A site's content model must read like a CMS, not like an implementation:
91
+ A site's content model must read like a CMS, not like an implementation. The
92
+ test that decides **Single Type vs Component**: EDIT IT ONCE — should it change
93
+ on EVERY page (Single Type) or only on THIS page (Component)? That is a
94
+ question about CONTENT, not about how many pages the STRUCTURE appears on — a
95
+ component can appear on many pages too.
96
+
97
+ | Shape | Repeats as entries? | Structure across pages | **Content across pages** | Edit propagates? | Examples |
98
+ | ---------------------- | ------------------- | ---------------------- | ------------------------ | ---------------- | ----------------------------------------------------------------- |
99
+ | **Collection Type** | Yes (many) | — | — | — | Blog Post, FAQ Item, Team Member, Service |
100
+ | **Single Type** | No (one instance) | reused | **SAME everywhere** | Yes — everywhere | Header, Footer, Cookie Banner, Nav, a shared CTA _(if identical)_ |
101
+ | **Component (Blocks)** | No | reused (1+ pages) | **DIFFERENT per page** | No — local | a hero, a features grid, a Pricing page's plan tiers |
102
+
103
+ - **Structure appearing on many pages does NOT make it a Single.** A hero is on
104
+ every page but each page's hero content differs → Component. A header is a
105
+ Single Type because its content is identical everywhere.
106
+ - **Single Type detection is structural:** a shared component whose content is
107
+ BAKED INTO the component — no per-page content props, e.g. rendered by the
108
+ LAYOUT/root — is a Single Type. A component that RECEIVES its content per
109
+ page (props/children vary) is a Component, however many pages render it.
110
+ - **The Pricing page's plan tiers are the litmus test:** neither a Collection
111
+ (not managed like blog posts) nor a Single (their content is page-specific) —
112
+ a repeatable `Tier` **block** on the Pricing Single.
113
+ - **A page in the Studio shows all its content top to bottom, header to
114
+ footer.** The Single Types a page references render inline in its page view;
115
+ editing one there edits it on every page that includes it — a virtual
116
+ reference, not a copy.
117
+ - **The decision interview already answered the sensitive calls.** When
118
+ `fimo migrate wrap` ran, it asked the site owner the two questions detection
119
+ can't settle on its own, and LOCKED the answers in
120
+ `.fimo/migration/manifest.json`. Your agent prompt relays them under **LOCKED
121
+ DECISIONS** — execute them, never re-decide:
122
+ - **Illustration vs content** — a component that reproduces a UI in code (a
123
+ product screenshot/mock, a fake dashboard, a device frame, an animated
124
+ terminal/code demo) carries many tiny strings that belong to the
125
+ ILLUSTRATION, not to editable content. The owner marked which sections to
126
+ DROP: the machine already removed them from the CMS (labels stripped, seeded
127
+ rows deleted) and excludes their file on re-runs — do NOT model them or
128
+ re-add labels. Sections the owner kept as CONTENT stay in the model.
129
+ - **Content-model shape** — for a component rendered on 2+ pages that
130
+ detection left as a default Component (identical but copy-pasted into
131
+ different files), the owner classified it: SINGLE TYPE (same content
132
+ everywhere — model once, reference it), COLLECTION TYPE (repeated managed
133
+ entries), or COMPONENT (per-page content). Apply the classification exactly.
134
+ If a LOCKED DECISION is missing for a genuinely ambiguous section (an older
135
+ migration, or a decision recorded as `decidedBy: "default"`), surface it in
136
+ your report rather than guessing.
137
+
138
+ Then, mechanically:
92
139
 
93
140
  - **Chrome** (header, footer, nav, menus, banners) is edited as ONE thing →
94
- a SINGLE TYPE per piece (`src/schemas/<Name>.json` with
95
- `"isSingleton": true`, real fields mirroring the source: nav items as an
96
- array/blocks field, logo as media), pushed with `npx fimo schemas push`,
97
- its ONE document written from the source values with
98
- `npx fimo documents set <Name> --body '<json>'` (singletons REJECT the
99
- entries endpoints), component rewired to read it. Never a loose label
100
- pile, never a collection.
141
+ a SINGLE TYPE per piece. **The machine now BUILDS these for you**: every
142
+ section it detects on 2+ pages (`"shared": true`) becomes a ready Single —
143
+ schema + filled document — in `.fimo/migration/shared-singles/<Uid>.json`
144
+ (listed under SHARED CHROME SINGLE TYPES in this prompt). For each: review &
145
+ rename fields, `npx fimo schemas push`, `npx fimo documents set <Uid>
146
+ --body '<json>'` (singletons REJECT the entries endpoints), and reference it
147
+ from every page that renders the chrome. Never a loose label pile, never a
148
+ collection, never orphan flat labels.
101
149
  - **Page-scoped structure** (a pricing page's FAQ list) → a component array
102
150
  on that page's Single, or a collection + reference when genuinely reused
103
151
  across pages. Never an orphan collection nobody can situate. CLAIM the
104
152
  single on its page (`npx fimo pages set pricing --single Pricing`) — it
105
153
  then edits inline in the page's Studio view and leaves the Singles tab.
154
+ When a collection carries a field naming WHICH PAGE each entry belongs to
155
+ (one `FaqItem` collection whose rows are tagged `"about"`, `"pricing"`, …),
156
+ that field is `{"type": "string", "format": "page"}`, NEVER a bare
157
+ `{"type": "string"}`. `format: "page"` stores a registry page id and the
158
+ Studio renders a select of real pages instead of a free-text box — a
159
+ free string is a typo waiting to point at a page that does not exist.
106
160
  - **Real repeating content** (blog posts, team members) → a collection, with
107
161
  HUMAN slugs derived from the display field (never `faq-item-<hash>`), and
108
162
  schema field order matching reading order (question before answer).
109
- - **A page's SECTIONS are its Single's nested blocks.** A marketing page is
110
- a sequence of sections (hero, logo strip, features grid with grouped
111
- cards, testimonials, integrations, stats, FAQ) — model the page as ONE
112
- Single whose fields are nested block components mirroring that structure
113
- (blocks nest: a `features` field holds groups, each group holds cards).
114
- Section card lists are NEVER "page furniture" exemptions when they carry
115
- real copy — an exemption hides marketing content from the editor, which
116
- is a failed migration for that section. Claim the Single on its page.
163
+ - **A page's SECTIONS are its Single's nested blocks — blocks STRUCTURE the
164
+ page, this is not optional.** A marketing page is a sequence of sections
165
+ (hero, logo strip, features grid with grouped cards, testimonials,
166
+ integrations, stats, FAQ) — model the page as ONE Single whose fields are
167
+ nested block components mirroring that structure (blocks nest: a `features`
168
+ field holds groups, each group holds cards). Blocks are what make a page
169
+ EDITABLE: in the Studio a block is a COLLAPSIBLE group, so a human edits the
170
+ "Testimonials" block, not thirty loose fields. **A rich page dumped as a
171
+ FLAT PILE of individual labels (`faq`, `commonQuestions`, `10x`,
172
+ `fasterToLaunch`, `guillermoRauch`, `ceoVercel`, …) is a FAILED migration
173
+ even when every string is captured** — it is unnavigable, uncollapsible,
174
+ overwhelming, and nobody can contribute. Group them: a testimonial's
175
+ quote + author + role + logo is ONE repeatable `testimonials` block item, not
176
+ four sibling labels; a stat's value + label is one `stats` item; the FAQ is
177
+ one `faq` block of question + answer items. Section card lists are NEVER
178
+ "page furniture" exemptions when they carry real copy — an exemption hides
179
+ marketing content from the editor, which is a failed migration for that
180
+ section. Adopt the machine-built page Single (it already has this block
181
+ structure); do NOT re-flatten it into labels. Claim the Single on its page.
117
182
  **The machine BUILDS this model for you**: `fimo migrate` writes, per
118
183
  multi-section page, an analysis draft (`.fimo/migration/page-drafts/`,
119
184
  regenerate with `npx fimo pages draft`) AND a ready page Single
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-07-29T15:37:14.073Z",
4
+ "bundledAt": "2026-07-31T15:43:28.529Z",
5
5
  "cliVersion": "0.8.0",
6
6
  "external": [
7
7
  "oxc-parser",