fimo 0.9.0-experimental.7 → 0.9.0-experimental.9

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.
Files changed (52) hide show
  1. package/assets/skills/fimo-migration/references/pages.md +140 -1
  2. package/dist/cli/bundle.json +1 -1
  3. package/dist/cli/index.js +359 -187
  4. package/dist/runtime/app/FimoProviders.js +29 -7
  5. package/dist/runtime/primitives/components/RichText.d.ts +5 -1
  6. package/dist/runtime/primitives/components/RichText.js +2 -2
  7. package/dist/runtime/react/FimoSpaProviders.js +82 -14
  8. package/dist/runtime/react/index.d.ts +1 -0
  9. package/dist/runtime/react/index.js +1 -0
  10. package/dist/runtime/react/spa-content-cache.d.ts +27 -0
  11. package/dist/runtime/react/spa-content-cache.js +36 -0
  12. package/dist/runtime/wrapped/FimoRichTextBlock.d.ts +4 -1
  13. package/dist/runtime/wrapped/FimoRichTextBlock.js +2 -2
  14. package/dist/runtime/wrapped/content-fetch.pure.d.ts +20 -0
  15. package/dist/runtime/wrapped/content-fetch.pure.js +106 -0
  16. package/dist/runtime/wrapped/server.d.ts +5 -2
  17. package/dist/runtime/wrapped/server.js +15 -45
  18. package/dist/scripts/apply-wrap-templates.js +1 -1
  19. package/dist/scripts/apply-wrap.js +26 -2
  20. package/dist/scripts/cms/strapi/wiring.js +1 -1
  21. package/dist/scripts/detect-framework.js +6 -0
  22. package/dist/scripts/draft-rows.js +36 -0
  23. package/dist/scripts/frameworks/astro/routes.js +2 -18
  24. package/dist/scripts/frameworks/discover.d.ts +19 -6
  25. package/dist/scripts/frameworks/discover.js +96 -3
  26. package/dist/scripts/frameworks/discovered-route.d.ts +9 -0
  27. package/dist/scripts/frameworks/discovered-route.js +17 -0
  28. package/dist/scripts/frameworks/next/routes.d.ts +7 -0
  29. package/dist/scripts/frameworks/next/routes.js +31 -12
  30. package/dist/scripts/frameworks/nuxt/routes.js +2 -18
  31. package/dist/scripts/frameworks/remix/routes.js +4 -18
  32. package/dist/scripts/frameworks/sveltekit/routes.js +4 -19
  33. package/dist/scripts/frameworks/vite/routes.d.ts +5 -0
  34. package/dist/scripts/frameworks/vite/routes.js +59 -9
  35. package/dist/scripts/frameworks/vite/wiring.d.ts +12 -0
  36. package/dist/scripts/frameworks/vite/wiring.js +68 -23
  37. package/dist/scripts/lib/humanize.d.ts +14 -0
  38. package/dist/scripts/lib/humanize.js +54 -0
  39. package/dist/scripts/render-parity/capture.d.ts +7 -0
  40. package/dist/scripts/render-parity/capture.js +32 -4
  41. package/dist/scripts/routes/label-prefixes.d.ts +49 -0
  42. package/dist/scripts/routes/label-prefixes.js +136 -0
  43. package/dist/scripts/routes/module-resolve.d.ts +20 -0
  44. package/dist/scripts/routes/module-resolve.js +78 -0
  45. package/dist/scripts/routes/page-structure.d.ts +72 -0
  46. package/dist/scripts/routes/page-structure.js +234 -0
  47. package/dist/scripts/scan-wrappable.d.ts +4 -0
  48. package/dist/scripts/scan-wrappable.js +15 -2
  49. package/package.json +1 -1
  50. package/templates/react-router/package.json +1 -1
  51. package/dist/scripts/lib/discover-next-routes.d.ts +0 -17
  52. package/dist/scripts/lib/discover-next-routes.js +0 -134
@@ -50,9 +50,148 @@ unbound pages in the generated prompt. Your job:
50
50
  `schemas adopt-drafts` FIRST and bind with the FINAL names.
51
51
  3. Add pages the scanner missed (SPA relative/wildcard routes):
52
52
  `npx fimo pages set <id> --path /the/path --label "Label"`.
53
- 4. Verify: `npx fimo pages list --expand` materializes every instance —
53
+ Never repeat the folder/category in the label: the `/features/agents` page
54
+ is labeled "Agents", NOT "Feature: Agents" — the Studio tree already nests
55
+ it under Features.
56
+ Labels must read like a human wrote them: acronyms uppercase ("Agentic
57
+ CMS", "AI Stack", "SEO GEO" — never "Agentic Cms"), no two sibling pages
58
+ with the same name (a bound template is named after its schema — "Blog
59
+ Post" next to the "Blog" index; the machine does this when it binds, fix
60
+ any leftover with `--label`).
61
+ When the site's NAV groups flat pages editorially (a "Resources" menu over
62
+ /for-developers, /for-founders…), mirror it with
63
+ `npx fimo pages set <id> --group "Resources"` — the Studio Pages tree
64
+ folds them under that group even without a shared URL segment.
65
+ 4. Map each page to its label keys when they diverge. The Studio shows a
66
+ page's labels by key prefix, defaulting to `<pageId>.` — but wrapped keys
67
+ derive from FILE names (`AiCms.tsx` → `ai-cms.*`) or data files
68
+ (`personas.*`), which can differ from the URL-derived page id
69
+ (`agentic-cms`). A page whose Studio view is EMPTY almost always means
70
+ this mismatch. `fimo migrate` PREFILLS `labelPrefixes` wherever it can
71
+ prove the join (a staged key appears verbatim in the route's component
72
+ file) and the prompt § Routes & pages lists every UNCLAIMED prefix left.
73
+ Your job: place each unclaimed prefix — claim it with
74
+ `npx fimo pages set <id> --label-prefix "<prefix>"` (comma-separated for
75
+ several; claims MERGE into the existing list so machine-prefilled
76
+ prefixes survive, `""` clears the whole list) when one page renders those keys, or leave it
77
+ deliberately when it is shared (chrome, multi-page data files) and say so
78
+ in your report. No prefix may end up merely forgotten.
79
+ 5. Give each page the Lucide icon that best matches its CONTENT:
80
+ `npx fimo pages set <id> --icon <kebab-name>` (pricing → `tag`, blog →
81
+ `newspaper`, contact → `mail`, legal pages → `scale`, team/about →
82
+ `users`, docs → `book-open`). Read the page component to judge. Use
83
+ well-known Lucide names only — an unknown name silently falls back to
84
+ the default file icon in the Studio. Skip the flag when nothing clearly
85
+ fits.
86
+ 6. Verify: `npx fimo pages list --expand` materializes every instance —
54
87
  each page the site's nav links to must appear as a real URL.
55
88
 
89
+ ## Shared chrome → Single Types (the content-model rule)
90
+
91
+ A site's content model must read like a CMS, not like an implementation:
92
+
93
+ - **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.
101
+ - **Page-scoped structure** (a pricing page's FAQ list) → a component array
102
+ on that page's Single, or a collection + reference when genuinely reused
103
+ across pages. Never an orphan collection nobody can situate. CLAIM the
104
+ single on its page (`npx fimo pages set pricing --single Pricing`) — it
105
+ then edits inline in the page's Studio view and leaves the Singles tab.
106
+ - **Real repeating content** (blog posts, team members) → a collection, with
107
+ HUMAN slugs derived from the display field (never `faq-item-<hash>`), and
108
+ 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.
117
+ **The machine BUILDS this model for you**: `fimo migrate` writes, per
118
+ multi-section page, an analysis draft (`.fimo/migration/page-drafts/`,
119
+ regenerate with `npx fimo pages draft`) AND a ready page Single
120
+ (`.fimo/migration/page-singles/<Uid>.json` — singleton schema + document
121
+ filled with the staged label values and the source block rows). Sections
122
+ flagged `"shared": true` render on several pages — that is chrome: model
123
+ each once as a Single Type, never as a per-page block. The `wrap --check`
124
+ Content-model gate fails while a built Single is neither claimed
125
+ (`pages set <id> --single <Uid>`) nor recorded under
126
+ `wrap.modelDeviations` (`{"page": "<id>", "reason": "…"}`) — a reason the
127
+ user would accept; "faster as labels" is not one. Your work per page:
128
+ rename machine field keys to editorial names, push, `documents set`,
129
+ rewire the reads with source fallback, claim.
130
+
131
+ **Worked real example** (the Fimo homepage, the model the user ratified):
132
+ the page renders hero → logo strip → features grid (3 groups, each with
133
+ cards) → testimonials → integrations → stats bar → FAQ. Its Single:
134
+
135
+ ```json
136
+ {
137
+ "uid": "Home",
138
+ "isSingleton": true,
139
+ "fields": {
140
+ "builtOnTheBest": {
141
+ "type": "blocks",
142
+ "schema": { "fields": { "name": { "type": "string" }, "domain": { "type": "string" } } }
143
+ },
144
+ "features": {
145
+ "type": "blocks",
146
+ "schema": {
147
+ "fields": {
148
+ "title": { "type": "string" },
149
+ "subtitle": { "type": "string" },
150
+ "cards": {
151
+ "type": "blocks",
152
+ "schema": { "fields": { "title": { "type": "string" }, "description": { "type": "text" } } }
153
+ }
154
+ }
155
+ }
156
+ },
157
+ "testimonials": {
158
+ "type": "blocks",
159
+ "schema": {
160
+ "fields": {
161
+ "quote": { "type": "text" },
162
+ "metricValue": { "type": "string" },
163
+ "metricLabel": { "type": "string" },
164
+ "author": { "type": "string" },
165
+ "role": { "type": "string" }
166
+ }
167
+ }
168
+ },
169
+ "ecosystem": {
170
+ "type": "blocks",
171
+ "max": 1,
172
+ "schema": {
173
+ "fields": {
174
+ "title": { "type": "string" },
175
+ "stats": { "type": "blocks", "schema": { "fields": { "label": { "type": "string" } } } }
176
+ }
177
+ }
178
+ },
179
+ "faqs": { "type": "blocks", "schema": { "fields": { "q": { "type": "string" }, "a": { "type": "text" } } } }
180
+ }
181
+ }
182
+ ```
183
+
184
+ Note what made it right: block names are the on-page section titles
185
+ ("Built on top of the best" → `builtOnTheBest`), field names are ROLES
186
+ (`title`, `quote`, `author`) never copy slugs, a logo strip carries its
187
+ ITEMS (not just its heading), computed live values (stat numbers) stay in
188
+ code, and the whole thing was claimed on the page. Smart deviations were
189
+ reported, not silent.
190
+
191
+ - **Plumbing** (`WrappedRichText`, `WrappedMedia`) is storage — the Studio
192
+ hides it from Collections and shows the entries under their pages; never
193
+ present it as content in your report.
194
+
56
195
  ## SEO — a USER decision, never wired by default
57
196
 
58
197
  Who owns SEO metadata is recorded in `.fimo/migration/manifest.json` →
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-07-25T21:00:19.368Z",
4
+ "bundledAt": "2026-07-29T10:21:20.778Z",
5
5
  "cliVersion": "0.8.0",
6
6
  "external": [
7
7
  "oxc-parser",