fimo 0.16.0 → 0.18.0

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 (162) hide show
  1. package/assets/astro/components/DateTime.astro +22 -0
  2. package/assets/astro/components/index.d.ts +1 -0
  3. package/assets/astro/components/index.js +1 -0
  4. package/assets/content-templates/shared/types.eta +2 -0
  5. package/assets/skills/fimo-cli/SKILL.md +5 -2
  6. package/assets/skills/fimo-cli/references/content.md +2 -2
  7. package/assets/skills/fimo-cli/references/deploy.md +2 -0
  8. package/assets/skills/fimo-cli/references/init.md +11 -4
  9. package/assets/skills/fimo-cli/references/locales.md +38 -14
  10. package/assets/skills/fimo-cli/references/pages.md +70 -0
  11. package/assets/skills/fimo-cli/references/webhooks.md +1 -1
  12. package/assets/skills/fimo-code/SKILL.md +11 -0
  13. package/assets/skills/fimo-code/assets/react-router-locales/LocaleLayout.tsx +12 -0
  14. package/assets/skills/fimo-code/assets/react-router-locales/routes.ts +7 -6
  15. package/assets/skills/fimo-code/references/best-practices/astro.md +47 -0
  16. package/assets/skills/fimo-code/references/best-practices/next.md +42 -0
  17. package/assets/skills/fimo-code/references/best-practices/sveltekit.md +17 -0
  18. package/assets/skills/fimo-code/references/content/richtext.md +5 -0
  19. package/assets/skills/fimo-code/references/content/schema.md +4 -1
  20. package/assets/skills/fimo-code/references/frameworks/astro.md +5 -3
  21. package/assets/skills/fimo-code/references/frameworks/hosting.md +5 -2
  22. package/assets/skills/fimo-code/references/frameworks/next/app-router.md +6 -0
  23. package/assets/skills/fimo-code/references/frameworks/next/locales.md +12 -2
  24. package/assets/skills/fimo-code/references/frameworks/next.md +7 -0
  25. package/assets/skills/fimo-code/references/frameworks/react-router.md +15 -7
  26. package/assets/skills/fimo-code/references/frameworks/sveltekit.md +15 -8
  27. package/assets/skills/fimo-code/references/labels.md +9 -1
  28. package/assets/skills/fimo-code/references/locales.md +8 -2
  29. package/assets/skills/fimo-code/references/migrations/react-router-route-ownership.md +93 -0
  30. package/assets/skills/fimo-code/references/ui.md +21 -2
  31. package/assets/skills/fimo-migration/SKILL.md +276 -51
  32. package/assets/skills/fimo-migration/references/content.md +119 -35
  33. package/assets/skills/fimo-migration/references/decision.md +72 -0
  34. package/assets/skills/fimo-migration/references/forms.md +38 -6
  35. package/assets/skills/fimo-migration/references/frameworks/nextjs.md +179 -23
  36. package/assets/skills/fimo-migration/references/import-contract.md +71 -19
  37. package/assets/skills/fimo-migration/references/manifest.md +11 -161
  38. package/assets/skills/fimo-migration/references/media.md +33 -1
  39. package/assets/skills/fimo-migration/references/platforms.md +26 -2
  40. package/assets/skills/fimo-migration/references/qa.md +167 -13
  41. package/assets/skills/fimo-migration/references/workers/content-execution.md +39 -0
  42. package/assets/skills/fimo-migration/references/workers/content-planner.md +64 -0
  43. package/assets/skills/fimo-migration/references/workers/framework.md +37 -0
  44. package/assets/skills/fimo-migration/references/workers/validator.md +25 -0
  45. package/assets/skills/fimo-migration/references/workers.md +82 -0
  46. package/assets/skills/fimo-migration/references/workflow.md +140 -192
  47. package/assets/skills/fimo-migration/scripts/apply-decision.mjs +534 -0
  48. package/assets/skills/fimo-migration/scripts/build-canonical-manifest.mjs +7 -4
  49. package/assets/skills/fimo-migration/scripts/write-migration-report.mjs +191 -4
  50. package/assets/skills/fimo-studio/references/cms.md +25 -7
  51. package/assets/skills/fimo-studio/references/webhooks.md +1 -1
  52. package/assets/sveltekit/components/DateTime.svelte +35 -0
  53. package/assets/sveltekit/components/FimoProvider.svelte +2 -2
  54. package/assets/sveltekit/components/index.d.ts +1 -0
  55. package/assets/sveltekit/components/index.js +1 -0
  56. package/dist/build/next/config.d.ts +4 -1
  57. package/dist/build/next/config.js +21 -5
  58. package/dist/build/sveltekit/vite.d.ts +3 -4
  59. package/dist/build/sveltekit/vite.js +3 -4
  60. package/dist/build/vite/plugins/runtime-env.d.ts +2 -1
  61. package/dist/build/vite/plugins/runtime-env.js +14 -10
  62. package/dist/cli/bundle.json +2 -2
  63. package/dist/cli/index.js +76 -78
  64. package/dist/runtime/app/FimoProviders.js +25 -14
  65. package/dist/runtime/app/prefetch.d.ts +3 -1
  66. package/dist/runtime/app/prefetch.js +11 -55
  67. package/dist/runtime/astro/preview.js +7 -9
  68. package/dist/runtime/content/client/internal.js +1 -0
  69. package/dist/runtime/i18n/locale.d.ts +4 -0
  70. package/dist/runtime/i18n/locale.js +14 -14
  71. package/dist/runtime/next/client-runtime.js +5 -1
  72. package/dist/runtime/next/client.d.ts +3 -2
  73. package/dist/runtime/next/client.js +2 -1
  74. package/dist/runtime/next/labels.d.ts +2 -2
  75. package/dist/runtime/next/labels.js +2 -2
  76. package/dist/runtime/next/preview.d.ts +13 -0
  77. package/dist/runtime/next/preview.js +34 -0
  78. package/dist/runtime/next/primitives/server.d.ts +2 -0
  79. package/dist/runtime/next/primitives/server.js +8 -0
  80. package/dist/runtime/next/provider.d.ts +5 -0
  81. package/dist/runtime/next/provider.js +17 -3
  82. package/dist/runtime/next/server-runtime.js +4 -1
  83. package/dist/runtime/next/server.d.ts +1 -1
  84. package/dist/runtime/next/server.js +1 -1
  85. package/dist/runtime/paths/get-fimo-paths.d.ts +6 -5
  86. package/dist/runtime/paths/get-fimo-paths.js +43 -42
  87. package/dist/runtime/preview/location.d.ts +19 -2
  88. package/dist/runtime/preview/location.js +16 -2
  89. package/dist/runtime/primitives/index.d.ts +1 -0
  90. package/dist/runtime/primitives/index.js +1 -0
  91. package/dist/runtime/react/primitives/editable/DateTime.d.ts +4 -0
  92. package/dist/runtime/react/primitives/editable/DateTime.js +13 -0
  93. package/dist/runtime/react/primitives/renderers/DateRenderer.d.ts +7 -1
  94. package/dist/runtime/react/primitives/renderers/DateRenderer.js +11 -8
  95. package/dist/runtime/react-router/{routes.d.ts → legacy/routes.d.ts} +6 -1
  96. package/dist/runtime/react-router/{routes.js → legacy/routes.js} +22 -7
  97. package/dist/runtime/routes/contract.d.ts +116 -0
  98. package/dist/runtime/routes/contract.js +377 -0
  99. package/dist/runtime/routes/index.d.ts +3 -0
  100. package/dist/runtime/routes/index.js +3 -0
  101. package/dist/runtime/routing/AppRoutesProvider.js +4 -3
  102. package/dist/runtime/seo/resolver.d.ts +5 -0
  103. package/dist/runtime/seo/resolver.js +10 -42
  104. package/dist/runtime/shared/fimo-config.types.d.ts +34 -8
  105. package/dist/runtime/shared/preview-location.d.ts +1 -22
  106. package/dist/runtime/shared/preview-location.js +5 -93
  107. package/dist/runtime/sveltekit/preview.d.ts +12 -3
  108. package/dist/runtime/sveltekit/preview.js +13 -8
  109. package/dist/scripts/sync-forms.js +1 -1
  110. package/dist/scripts/sync-schemas.js +1 -4
  111. package/dist/scripts/validate-fimo-config.js +5 -1
  112. package/dist/scripts/validate-page-registry.d.ts +2 -0
  113. package/dist/scripts/validate-page-registry.js +167 -0
  114. package/dist/scripts/validate-route-metadata.js +132 -41
  115. package/package.json +7 -3
  116. package/templates/astro/.fimo/config.json +13 -5
  117. package/templates/astro/AGENTS.md +5 -1
  118. package/templates/astro/astro.config.mjs +7 -0
  119. package/templates/astro/package.json +1 -1
  120. package/templates/astro/pnpm-workspace.yaml +0 -3
  121. package/templates/astro/src/components/ProjectOverview.astro +9 -6
  122. package/templates/astro/src/layouts/Base.astro +1 -1
  123. package/templates/astro/src/locales.ts +4 -0
  124. package/templates/astro/src/pages/[locale]/index.astro +19 -0
  125. package/templates/astro/src/pages/[locale]/projects/[slug].astro +35 -0
  126. package/templates/astro/src/pages/[locale]/projects/index.astro +19 -0
  127. package/templates/astro/src/pages/index.astro +5 -2
  128. package/templates/astro/src/pages/projects/[slug].astro +4 -2
  129. package/templates/astro/src/pages/projects/index.astro +5 -2
  130. package/templates/nextjs/.fimo/config.json +2 -1
  131. package/templates/nextjs/AGENTS.md +5 -0
  132. package/templates/nextjs/package.json +1 -1
  133. package/templates/nextjs/src/app/(default)/layout.tsx +10 -0
  134. package/templates/nextjs/src/app/[locale]/layout.tsx +22 -0
  135. package/templates/nextjs/src/app/[locale]/page.tsx +1 -0
  136. package/templates/nextjs/src/components/Document.tsx +26 -0
  137. package/templates/nextjs/src/components/FimoPreviewBridge.tsx +13 -0
  138. package/templates/nextjs/src/locales.ts +13 -0
  139. package/templates/react-router/.fimo/config.json +3 -6
  140. package/templates/react-router/AGENTS.md +4 -0
  141. package/templates/react-router/package.json +2 -2
  142. package/templates/react-router/pnpm-workspace.yaml +1 -3
  143. package/templates/react-router/react-router.config.ts +4 -10
  144. package/templates/react-router/src/pages/LocaleLayout.tsx +12 -0
  145. package/templates/react-router/src/root.tsx +2 -4
  146. package/templates/react-router/src/routes.ts +5 -3
  147. package/templates/sveltekit/.fimo/config.json +2 -1
  148. package/templates/sveltekit/AGENTS.md +5 -0
  149. package/templates/sveltekit/package.json +1 -1
  150. package/templates/sveltekit/src/app.html +1 -1
  151. package/templates/sveltekit/src/hooks.server.ts +11 -0
  152. package/templates/sveltekit/src/locales.ts +8 -0
  153. package/templates/sveltekit/src/params/locale.ts +5 -0
  154. package/templates/sveltekit/src/routes/+layout.server.ts +6 -1
  155. package/templates/sveltekit/src/routes/+layout.svelte +5 -0
  156. package/assets/skills/fimo-migration/references/inventory/coordinator.md +0 -40
  157. package/assets/skills/fimo-migration/references/inventory/locales/next-intl.md +0 -39
  158. package/assets/skills/fimo-migration/references/inventory/locales.md +0 -41
  159. package/assets/skills/fimo-migration/scripts/inventory/locales/next-intl.mjs +0 -459
  160. package/templates/nextjs/src/app/layout.tsx +0 -17
  161. /package/templates/nextjs/src/app/{page.tsx → (default)/page.tsx} +0 -0
  162. /package/templates/sveltekit/src/routes/{+page.svelte → [[locale=locale]]/+page.svelte} +0 -0
@@ -14,24 +14,156 @@ description: >-
14
14
  Move published URLs, exports, source repositories, CMS data, media, and forms
15
15
  into a real Fimo project without silently dropping source material.
16
16
 
17
- > **Experimental:** migration support is limited. Assess what can be preserved, explain unsupported parts, and never promise source-framework preservation.
17
+ > **Experimental:** migration support is limited. Assess what can be preserved,
18
+ > explain unsupported parts, record every gap as an owner-visible unresolved
19
+ > item, and do not promise behavior that the target cannot prove. When the CLI
20
+ > supports the source framework, preserve it explicitly and verify the runtime
21
+ > before importing data.
18
22
  >
19
23
  > Use the CLI invocation selected for this flow for every `fimo` command in the migration. Otherwise use `npx fimo@latest`; do not install it globally.
20
24
 
25
+ The first pass is a faithful migration, not a framework conversion. Detect the
26
+ source framework before creating the target and pass it explicitly to
27
+ `fimo migrate init`. For a Next.js source, use `--framework nextjs`; never rely
28
+ on the React Router default. The setup receipt must report the target runtime
29
+ framework, and a mismatch is a setup failure before any schemas, entries,
30
+ assets, labels, or forms are imported.
31
+
32
+ Keep third-party integrations when Fimo does not reproduce their behavior
33
+ end-to-end. Preserve the original code path and record required environment
34
+ variable names only; never read or copy secret values. A missing secret is a
35
+ follow-up for the owner, not permission to silently remove the integration.
36
+
37
+ ## Execution environment
38
+
39
+ Run this skill from a coding-agent process that has direct access to the
40
+ migration checkout. The process must be able to read and write source files,
41
+ run bounded shell scripts, spawn its own subagents, and invoke the selected
42
+ standalone Fimo CLI. The root agent owns the complete loop: fan out workers,
43
+ fan in their reports, repair what they missed, and validate the real target.
44
+
45
+ A plan, an evidence pack, or a generated report without source changes and
46
+ verified Fimo state is only a draft. Do not finish with an explanation when the
47
+ migration request requires an implementation.
48
+
49
+ ## CLI provenance
50
+
51
+ Run every `fimo` command in the migration through one released, pinned CLI
52
+ artifact, and record which one.
53
+
54
+ - Use the exact CLI invocation selected for this flow. If none was provided,
55
+ stop and request an exact released version or immutable package URL. Never
56
+ default to `latest` or another moving dist-tag, never install it globally,
57
+ and never switch artifacts mid-run.
58
+ - Never run the migration through a `file:`-linked workspace CLI from a Fimo
59
+ source checkout: the workspace binary skips the publish-time bundle and can
60
+ miss bundled workspace packages such as `@fimo/cli-kit`. When the migration
61
+ must exercise unreleased CLI changes, publish a pinned dev artifact from that
62
+ checkout first (`pnpm -F fimo publish-cli -- --id <task-name>`, or
63
+ `node scripts/remote-dev-publish-cli.mjs --id <task-name>` when the checkout
64
+ runs on a Dev Remote box) and use the exact package the publish recorded in
65
+ that checkout's `.fimo/dev.json`.
66
+ - Record the provenance in the migration report - the `fimo --version` output
67
+ plus the artifact source (an npm version, or the pinned artifact URL from
68
+ `.fimo/dev.json`).
69
+
70
+ ## Initialized target precondition
71
+
72
+ Before workers start, the root process must establish a real Fimo project and
73
+ environment, link the migration checkout to it, and prove the data plane is
74
+ reachable with a read such as `fimo schemas list -C <target> --env <env>` using
75
+ the selected pinned CLI. Give workers the project id, environment, exact CLI
76
+ invocation, and verification command. Generated `.fimo` JSON without a
77
+ successful platform read is not initialization.
78
+
79
+ For an existing non-empty application, reuse the CLI's real flow: create or
80
+ select the Fimo project with `fimo init`, then run
81
+ `fimo link <project-id> -C <target> --env <env>` and verify the data plane.
82
+ `fimo migrate init <url> <dir>` is only usable when the target directory is
83
+ empty or already linked.
84
+ If authentication, organization selection, project creation, environment
85
+ resolution, linking, or the verification read fails, stop before workers and
86
+ report the exact failed command and setup requirement.
87
+
21
88
  ## Core contract
22
89
 
90
+ - Migrate 1:1, not a compact approximation. Keep the source's route surface
91
+ and user-visible behavior: do not refactor routes merely to make the
92
+ migration easier, and do not replace many source pages with one generic
93
+ static shell. Every source page, content construct, array item, Markdown or
94
+ MDX block, imported component, and meaningful UI behavior ends with a
95
+ consuming target route or component, or with an explicit
96
+ unresolved/incompatible item in the text plan/report.
97
+ - The first migration produces a working Fimo app with minimal refactoring.
98
+ Source-backed migrations preserve the detected source framework, router,
99
+ runtime, provider structure, and configuration by default: React Router/Vite
100
+ stays React Router/Vite, and Next.js stays Next.js. Framework conversion is
101
+ always an explicit user choice. URL-only and rebuild migrations have no
102
+ source framework to preserve, so the user must choose the target framework
103
+ explicitly; do not silently inherit a scaffold default. An explicit
104
+ conversion is still a faithful first pass: the framework conversion worker
105
+ ports the source's APIs, loaders, hardcoded content, integrations, and
106
+ visible behavior into the new framework unchanged, and Fimo schemas,
107
+ payloads, imports, and code wiring happen later through the content workers
108
+ (`references/workers/content-execution.md`). If the framework or hosting
109
+ setup is unclear or unsupported, stop and ask instead of guessing,
110
+ converting it, or deleting provider-specific files.
111
+ - Inventory provider-specific files and rules before editing them. Classify each
112
+ as `preserved`, `replaced`, `safely-unnecessary-implementation-detail`, or
113
+ `unresolved`, with source evidence and affected behavior. Delete only after
114
+ proving redundancy or recording the user's acceptance of the loss.
115
+ - Preserve an existing third-party integration (email, marketing, payments,
116
+ analytics) unless Fimo reproduces its exact user-visible behavior end to
117
+ end. When behavior is not 1:1 - a Brevo newsletter flow, for example - keep
118
+ the original integration wired and record the credential environment keys it
119
+ needs by name, without reading secret values. A missing secret is a user
120
+ follow-up in the report, never a reason to delete behavior or to block
121
+ local build, evaluation, or QA checks.
23
122
  - Record every route, CMS record, media asset, form, locale, redirect, SEO
24
123
  field, and unsupported behavior as imported, deliberately ignored with a
25
124
  reason, or unresolved.
125
+ - When Fimo cannot support a source feature, do not silently drop or simplify
126
+ it. Preserve the original behavior when possible; otherwise leave the
127
+ existing source behavior or its documented fallback in place and record an
128
+ unresolved item with the source evidence, the owner action, and the
129
+ user-visible impact. Never claim completion while source content is
130
+ unwired.
26
131
  - Prefer source code and exports over inferred crawl data. Use a public URL as
27
132
  visual, SEO, route, and behavior evidence when better source material exists.
133
+ - Read local files and exports directly and public APIs without credentials.
134
+ Private APIs and CMSs require a user-provided export or a narrowly scoped
135
+ server-side credential. Never read credentials from browser code or copy
136
+ them into browser code, migration artifacts, or reports. Target-project
137
+ authentication does not grant source access. Missing access stops only that
138
+ data lane and becomes unresolved; never invent replacement content.
28
139
  - Model content before page code. Generated JSON is not imported content.
29
- - Keep migration evidence in the canonical ledger from
30
- `references/manifest.md`.
140
+ - Model editorial content Fimo-natively: blocks for structured or repeatable
141
+ sections, richtext for rich bodies, references for categories, authors,
142
+ related items, and repeated taxonomies, and singleton content types for
143
+ editable header, footer, navigation, and site settings. A `json` field is the
144
+ last resort for opaque or application-owned data and carries a recorded
145
+ reason. Better modeling never redesigns the site: preserve the source's
146
+ content shape and behavior, and record the source-to-Fimo mapping
147
+ (`references/content.md`).
148
+ - Media owns its alt text. Preserve the source alt on the media value and pass
149
+ it to asset metadata when the upload command supports it; never add a
150
+ standalone alt field to a content schema. Record the limitation when the
151
+ command cannot carry it (`references/media.md`).
152
+ - Every write is create-or-update, so any step can be rerun without duplicating
153
+ a schema, entry, asset, single, or label.
154
+ - Every decision cites the source file (and line when it matters) that proves
155
+ it. What no worker could prove stays unresolved with an owner action.
156
+ - Keep coordination evidence in the plain-text files
157
+ `.fimo/migration/migration-plan.md` and
158
+ `.fimo/migration/migration-report.md`. Use JSON only for actual Fimo
159
+ schema/content payloads that a data-plane command needs to import. Do not
160
+ create a target description, worker plan, decision registry, or JSON receipt
161
+ just to describe the filesystem or agent work.
31
162
  - Do not report completion until the QA gate passes or every failed check is
32
163
  present in the migration report.
33
- - Do not deploy while migrating. Import through the data-plane commands,
34
- verify locally, and propose one final owner-approved deployment.
164
+ - Import through the data-plane commands and verify locally before deployment.
165
+ Propose one preview deployment after a successful run, but deploy or publish
166
+ only after an explicit user request.
35
167
 
36
168
  ## Orient and route
37
169
 
@@ -41,70 +173,160 @@ into a real Fimo project without silently dropping source material.
41
173
  framework APIs.
42
174
  3. Classify the available evidence:
43
175
  - **source-backed**: source repository, export, downloaded HTML, CMS data,
44
- or media folder. Treat the source files as truth and run the relevant
45
- bounded inventory helpers when available. After the canonical manifest
46
- records `source.rootPath` and `source.inventoryPath`, run
47
- `fimo migrate inventory [project-root]` for deterministic framework,
48
- runtime, package, locale, and message-file evidence.
176
+ or media folder. The source files are truth; the workers read them
177
+ directly.
49
178
  - **url-only**: only a published URL. Run `fimo migrate <url> [dir]` to
50
179
  create the draft evidence pack.
51
180
  - **hybrid**: source material plus a public URL. Treat source material as
52
181
  truth and the URL as comparison evidence.
53
182
  4. Read `references/workflow.md` before implementation and create or update the
54
- canonical ledger.
55
- 5. Load only the framework and inventory references that apply:
183
+ plain-text migration plan.
184
+ 5. Load the references that apply:
185
+ - Coordinator ownership and dependency gates -> `references/workers.md`.
186
+ - Framework conversion worker -> `references/workers/framework.md`.
187
+ - Content planner -> `references/workers/content-planner.md`.
188
+ - Content data/code workers -> `references/workers/content-execution.md`.
189
+ - Independent validator -> `references/workers/validator.md`.
56
190
  - Next.js source -> `references/frameworks/nextjs.md`.
57
- - Locale or dictionary evidence -> `references/inventory/locales.md`.
58
- - Declared next-intl dependency ->
59
- `references/inventory/locales/next-intl.md`.
60
- - Deterministic inventory coordination ->
61
- `references/inventory/coordinator.md`.
191
+ - React Router/Vite source -> load the target project's `fimo-code`
192
+ `frameworks/react-router`, `frameworks/vite-react`, and
193
+ `frameworks/hosting` references as applicable.
194
+ - Next.js implementation -> load the target project's `fimo-code`
195
+ `frameworks/next` and `frameworks/hosting` references. Those references
196
+ describe available equivalents; verify hosting support instead of assuming
197
+ every Next.js rule or runtime behavior is automatic.
198
+ Framework, provider, and rendering-primitive rules live in the `fimo-code`
199
+ skill; this skill routes to them and does not restate them.
200
+
201
+ ## Target setup
202
+
203
+ The target is its own Fimo project directory. The client source checkout is
204
+ read-only evidence: never run setup inside it, never modify it, and never
205
+ hand-write a `.fimo/project.json` marker to fake a link.
206
+
207
+ `fimo migrate init` is the migration setup gate. For a source-backed migration
208
+ it validates the target and CLI auth, then delegates project selection and
209
+ creation to the standard `fimo init` flow (same options, no separate creation
210
+ path), and returns a setup receipt covering auth, the target link, the
211
+ migration directory, and readiness. It fails with a structured error when auth
212
+ is missing, the target is missing or invalid, or the project or organization
213
+ is inaccessible. Both forms need a real ID supplied by the owner — without
214
+ one, stop with an unresolved owner action instead of inventing an ID:
215
+
216
+ - Link an owner-supplied (empty) project:
217
+ `fimo migrate init <target-dir> --project-id <projectId> --framework <framework>`
218
+ - Create a new project in an owner-supplied organization:
219
+ `fimo migrate init <target-dir> --org <organizationId> --framework <framework>`
220
+
221
+ After setup, check `.fimo/config.json#runtime.framework` and the scaffold's
222
+ framework files before starting workers. A Next.js target must still have its
223
+ Next runtime/configuration (`next.config.*` and the source router shape), not a
224
+ React Router scaffold.
225
+
226
+ Setup scaffolds the target and pushes its initial commit; that is the only
227
+ remote write it performs — it never pushes schemas, uploads assets, or imports
228
+ entries. `fimo deploy` and `fimo publish` stay separate and are never run
229
+ automatically (see Completion and deployment).
230
+
231
+ ## Command surface
232
+
233
+ Plan-only commands operate on local artifacts and work before the target is
234
+ linked:
235
+
236
+ - `fimo migrate init <url> [dir]` — URL migrations only: crawl the live site
237
+ into the draft evidence pack.
238
+ - `fimo migrate inspect` — summarize the URL draft or an existing legacy ledger.
239
+ - `fimo migrate import` — print the import plan; it writes no data.
240
+ - `fimo migrate apply` / `fimo migrate refine` — URL-draft-only scaffold and
241
+ refinement handoff; they play no role in a source-backed migration. `apply`
242
+ must never run against an initialized non-React-Router target: it is the
243
+ legacy React Router scaffold path and must fail instead of downgrading a
244
+ Next.js (or another framework) project.
245
+ - `fimo migrate manifest` / `fimo migrate report` — legacy URL-draft helpers.
246
+ New source-backed migrations use the plain-text migration plan, worker
247
+ reports, and final migration report; they do not bootstrap another JSON
248
+ registry.
249
+
250
+ Commands that perform actual data writes, all requiring the linked target:
251
+
252
+ - `fimo schemas push`, `fimo assets upload`, `fimo entries create|update`,
253
+ `fimo singles update`, `fimo labels set|set-many`, `fimo forms push`.
254
+ - `fimo migrate init` (source-backed form): the project link/creation and
255
+ initial commit push described above.
256
+ - `fimo deploy` / `fimo publish` — owner-approved only.
62
257
 
63
258
  ## Migration loop
64
259
 
65
- 1. Prepare the deterministic inventory plan first. When independent workers
66
- are available, create one read-only subagent per planned lane; otherwise run
67
- the same lanes sequentially. Every worker returns its fragment, never a
68
- prose claim. Run reconcile after every fan-out, then use targeted file reads
69
- for evidence the inventory leaves unresolved. Use a validator worker that
70
- produced no fragments to compare the plan, source evidence, fragments, and
71
- unresolved claims. Reopen only affected lanes when validation finds a gap.
72
- 2. Normalize CMS, media, forms, routes, redirects, locales, and unsupported
73
- behavior into the canonical ledger.
74
- 3. Model content and references before writing pages.
75
- 4. Generate or update schemas, entries, media mappings, forms, routes, and
76
- application code with native Fimo contracts.
77
- 5. Import reviewed media, schemas, entries, and forms in the order required by
78
- `references/import-contract.md`.
79
- 6. Run the local QA gate in `references/qa.md`.
80
- 7. Write `.fimo/migration/migration-report.md` with coverage, counts,
81
- mappings, unresolved items, and next actions.
82
-
83
- Use the bundled deterministic helpers whenever their contract fits. If a
84
- helper cannot prove a source fact, follow the bounded fallback in the relevant
85
- inventory reference instead of treating the whole inventory as failed.
260
+ 1. Run `fimo migrate init` and inspect the initialized target before any worker
261
+ edits it. Choose the target framework through the same canonical option as
262
+ `fimo init`: pass the detected source framework for a source-backed
263
+ migration, the framework the user explicitly chose for a conversion, and —
264
+ for a URL-only or rebuild migration — the framework the user selected (ask
265
+ when they have not). `--template-root` is a development/test
266
+ override only; normal migration prompts must not select a framework by
267
+ copying an arbitrary template path. The target's real files and directories
268
+ are the authority for framework paths; do not invent a second `app/` or
269
+ `src/app/` tree from an example.
270
+ 2. Write a short `.fimo/migration/migration-plan.md` containing the chosen
271
+ framework, source/target paths, worker owners, important dependencies, and
272
+ known questions. Start the independent workers in `references/workers.md`:
273
+ runtime/config, routes/SEO, content planning, and locales when those surfaces
274
+ exist. When the user explicitly chose a framework conversion,
275
+ one framework conversion worker replaces the runtime and routes lanes, owns
276
+ all structural target code, and must pass the framework gate in
277
+ `references/workers/framework.md` before content data and code workers
278
+ start. Worker prompts and worker reports are plain text.
279
+ 3. The content planner reads every content-bearing source and consumer, writes
280
+ and pushes complete schemas, and writes the content import payloads required
281
+ by the Fimo CLI. It records source items, consumers, batches, and unresolved
282
+ behavior in the text plan; it does not create a second orchestration format.
283
+ 4. Once the content plan is ready, upload every planned asset and patch its
284
+ target payload references. After the asset gate passes (and, in conversion
285
+ mode, the framework gate), run data workers per schema/locale. Start content
286
+ code workers only after their imported records read back successfully, so
287
+ they can prove real values render through the native Fimo APIs.
288
+ 5. Fan in the workers' plain-text reports. Compare their claimed files with
289
+ `git diff`, their Fimo writes with read-back CLI queries, and their source
290
+ coverage with the content plan. Every source item must be migrated,
291
+ deliberately preserved, or listed as unresolved with an owner action. A
292
+ report that merely says “done” is not evidence.
293
+ 6. Validate against the real target with a validator that did not author the
294
+ changes and starts only after every other worker report is terminal: read
295
+ back schemas, entries, singles, labels, and assets through the CLI, build
296
+ the project, render the migrated routes, and verify hosting compatibility
297
+ (local startup, Fimo Preview embeddability, build). Record `browserProof`
298
+ when a browser is available; otherwise use deterministic
299
+ HTTP/header/process/log checks and mark visual proof unavailable. Then run
300
+ the QA gate in `references/qa.md`.
301
+ 7. Write `.fimo/migration/migration-report.md` with coverage, counts, mappings,
302
+ unresolved items, timings from worker reports, and next actions.
86
303
 
87
304
  ## References
88
305
 
89
306
  - `references/workflow.md` - phase order, source intake, URL artifacts, and
90
307
  implementation loop.
91
- - `references/manifest.md` - canonical migration ledger schema.
308
+ - `references/decision.md` - plain-text decision and schema guidance; no
309
+ decision JSON is required.
92
310
  - `references/content.md` - CMS, entries, references, and source value rules.
93
- - `references/media.md` - media inventory, upload, dedupe, and replacement.
311
+ - `references/media.md` - media obligations, upload, dedupe, and replacement.
94
312
  - `references/forms.md` - form classification and Fimo replacement.
95
313
  - `references/import-contract.md` - import obligations for media, entries, and
96
314
  forms.
97
315
  - `references/platforms.md` - platform-specific source-of-truth and rebuild
98
316
  notes.
99
317
  - `references/qa.md` - acceptance gate and report format.
100
- - `references/frameworks/nextjs.md` - Next.js source inventory routing.
101
- - `references/inventory/locales.md` - locale evidence and agent fallback.
102
- - `references/inventory/locales/next-intl.md` - next-intl strategy and support
103
- boundary.
104
- - `references/inventory/coordinator.md` - deterministic inventory fan-out,
105
- worker, and fan-in commands.
106
- - `scripts/build-canonical-manifest.mjs` - bootstrap the canonical ledger.
107
- - `scripts/write-migration-report.mjs` - update QA state and write the report.
318
+ - `references/frameworks/nextjs.md` - Next.js routes, config, locales, and
319
+ Markdown or MDX content.
320
+ - `references/workers.md` - coordinator schedule, ownership, and gates.
321
+ - `references/workers/framework.md` - explicit framework-conversion contract.
322
+ - `references/workers/content-planner.md` - discovery, schemas, payloads, and
323
+ handoff contract.
324
+ - `references/workers/content-execution.md` - data import and code-wiring
325
+ contracts.
326
+ - `references/workers/validator.md` - independent fan-in validation.
327
+ - Existing manifest/decision helper scripts are legacy compatibility tools for
328
+ older migration artifacts. Do not invoke them in a new migration unless the
329
+ user explicitly asks to replay an older artifact.
108
330
 
109
331
  ## Completion and deployment
110
332
 
@@ -117,6 +339,9 @@ Use one final status:
117
339
  a draft.
118
340
 
119
341
  Never call a migration complete when CMS entries, media mappings, forms, or
120
- route coverage are unknown. Never run `fimo deploy` or `fimo publish` as a
121
- preview or QA step. After local QA passes, propose one final deployment and run
122
- it only when the owner explicitly approves it in the current turn.
342
+ route coverage are unknown. Local QA remains the acceptance gate. If
343
+ `fimo migrate init` created a new Fimo project, run one `fimo deploy` after QA
344
+ and return its preview and dashboard links; skip it when the user said not to
345
+ deploy or `FIMO_MIGRATION_NO_DEPLOY=1` is set. For an existing linked project,
346
+ offer the deployment and wait for approval. Never run `fimo publish` without an
347
+ explicit request.
@@ -2,24 +2,72 @@
2
2
 
3
3
  Model CMS content before page implementation.
4
4
 
5
+ ## Editorial Modeling
6
+
7
+ Model editorial content the way an editor should see it in Fimo, and keep the
8
+ source's behavior and content shape. A better model never silently redesigns the
9
+ site: the same routes render the same content, in the same order, with the same
10
+ copy. Record the source-to-Fimo mapping - source file, frontmatter key, or
11
+ export column -> content type, field, block, or reference - in the canonical
12
+ manifest and the content plan.
13
+
14
+ - **Blocks first.** Repeatable or structured editorial sections (hero, feature
15
+ grid, FAQ, testimonial list, pricing tiers, a page's section stack) become a
16
+ `blocks` field with named variants; rich bodies become `richtext`. Blocks and
17
+ references are content-editable, so model the structure instead of flattening
18
+ a section stack into loose strings or one opaque value.
19
+ - **JSON is the last resort.** Use `json` only for opaque or
20
+ application-owned data that no Fimo-native model fits, and record the concise
21
+ reason in the content plan and the report. A `json` blob holding editorial
22
+ copy is unmodeled content, not a migrated model.
23
+ - **Global chrome is content.** Header, footer, navigation, and site settings an
24
+ owner edits become singleton content types (navigation items as blocks or
25
+ references, not one label per link). Labels stay for genuinely small UI copy
26
+ and reusable translations.
27
+ - **Names are editor-facing.** `heroHeading`, not `H1`; `features`, not
28
+ `field_04`; `Navigation`, not `NavigationEs`. Never name a content type,
29
+ field, or block variant after a markup tag, an HTML attribute, a locale code,
30
+ or a source column index, and group related fields in the order an editor
31
+ reads them.
32
+
33
+ ## Markdown/MDX is source evidence, not a runtime source
34
+
35
+ Markdown/MDX files in the source tree or under `.fimo/migration/` are evidence
36
+ for the migration, never the migrated app's runtime content source. Claiming
37
+ content was migrated requires that the content was pushed to Fimo and the
38
+ consuming pages read it back through the Fimo content APIs. A page still
39
+ reading `.md`/`.mdx` files at build or request time is unmigrated content, not
40
+ a covered item.
41
+
42
+ - Long prose bodies belong in `richtext` fields and must render through the
43
+ Fimo rich-text primitives, not a Markdown pipeline.
44
+ - Custom MDX/React components embedded in prose are application code: preserve
45
+ them as components rendered by the consuming page, or record them as
46
+ unresolved. Never silently drop them during HTML-to-richtext conversion.
47
+ - Split editable prose around executable React/MDX children. Keep the children
48
+ in their original render order and wire the surrounding text to Fimo; do not
49
+ flatten or replace executable nodes with one additive “Page content” block.
50
+
5
51
  ## Detecting Dynamic Collections (no CMS export)
6
52
 
7
53
  When there is no first-party CMS export (most url-only and website-builder
8
54
  migrations), dynamic content still exists and must be modeled. It shows up two
9
55
  ways:
10
56
 
11
- 1. **Repeated route groups** - many sibling routes share a path prefix
12
- (`/blog/*`, `/vr-games/*`, `/locations/*`). Each group is a collection.
13
- Ignore locale prefixes (`/en-be/`, `/fr/`): a locale segment is never a
14
- collection name.
15
- 2. **Repeated in-page blocks** - a single page renders an array of
16
- structurally-identical items: card grids, list rows, tiles, carousels, logo
17
- walls. Games, locations, team members, testimonials, pricing tiers, FAQs,
18
- news teasers, and feature lists are almost always collections even when the
19
- source renders them inside one page.
20
-
21
- After the source-faithful rebuild, treat **any hardcoded array of 3+ items with
22
- the same shape** as a collection candidate. Do not leave it hardcoded.
57
+ 1. **Repeated route groups** - many sibling routes may share a path prefix
58
+ (`/blog/*`, `/vr-games/*`, `/locations/*`). Treat the group as a collection
59
+ candidate and inspect the route modules, identity, and editability before
60
+ deciding. Ignore locale prefixes (`/en-be/`, `/fr/`): a locale segment is
61
+ never a collection name.
62
+ 2. **Repeated in-page sections** - a single page may render an array of
63
+ structurally-identical items: card grids, list rows, tiles, carousels, or
64
+ logo walls. Read the consuming code and source intent before deciding whether
65
+ the values are a collection, a `blocks` field on a single, labels, or
66
+ application-owned data.
67
+
68
+ Repetition is evidence, not an automatic threshold. Do not convert every array
69
+ or object into content, and do not leave a collection-shaped source structure
70
+ hardcoded after the worker has established that editors should manage it.
23
71
 
24
72
  For each candidate:
25
73
 
@@ -27,35 +75,67 @@ For each candidate:
27
75
  `location`/Locations, `newsPost`/News, `testimonial`/Testimonials,
28
76
  `pricingPlan`/Pricing). Never name a collection after a locale code or a
29
77
  generic page route (no `EnBe`, no `Page`).
30
- - infer fields from the item shape using the Field Mapping below.
78
+ - infer fields from the item shape using the Field Mapping below, while keeping
79
+ source-specific constraints and rationale in the plain-text migration plan.
31
80
  - push the schema, then create one entry per item.
32
81
  - upload each item's image with `fimo assets upload` and store the returned Fimo
33
82
  asset URL in the entry's `media` field (never the source URL or a local
34
83
  `public/` path).
35
84
  - wire the component to render from the collection (Fimo content
36
85
  query/primitives) with a seed/empty state. The hardcoded array is removed.
37
- - record source/generated/imported counts per content type in the manifest.
86
+ - record source/generated/imported counts per content type in the migration
87
+ plan/report.
38
88
 
39
- Genuinely one-off blocks (a single hero, the footer) stay static. If unsure
40
- whether a block is a collection, prefer modeling it as one when items share a
41
- clear repeated shape and could plausibly be edited or extended.
89
+ A genuinely one-off section with no editorial owner may stay in application
90
+ code, but shared chrome - header, footer, navigation, site settings - belongs in
91
+ a singleton content type. If the evidence is ambiguous, preserve the source
92
+ value and record the decision or unresolved question rather than forcing a
93
+ schema merely because a shape repeats.
42
94
 
43
95
  ## Field Mapping
44
96
 
45
- Use source headers, values, and repeated patterns:
97
+ Choose from source semantics and the editing experience, not the source
98
+ container type. An object or array is not by itself a reason to use generic
99
+ JSON.
100
+
101
+ - Editor-authored prose, Markdown, HTML, or other portable formatted content ->
102
+ `richtext`; convert it to the current Fimo richtext contract and render it
103
+ with the corresponding Fimo primitive.
104
+ - Repeatable editor-authored structures such as FAQs, cards, features, pricing
105
+ items, testimonials, and page sections -> `blocks`, with nested richtext,
106
+ media, or references where their semantics require them.
107
+ - Reusable, independently editable categories, tags, authors, and similar
108
+ concepts -> `reference`, or blocks containing references, only when stable
109
+ source records or clear independent management prove the relationship.
110
+ - Opaque or unconstrained metadata, third-party payloads, and intentionally
111
+ non-editor-authored data -> generic `json`, with a concise rationale in the
112
+ content plan and worker report.
113
+
114
+ Then use source headers, values, and repeated patterns:
46
115
 
47
116
  - title/name/heading -> `string`
48
117
  - slug/path/url/permalink -> `string`
49
- - body/content/post/html/description -> `richtext`
118
+ - body/content/post/html/description -> `richtext` when editor-authored prose
50
119
  - excerpt/summary/dek -> `text`
51
- - image/photo/thumbnail/media/asset/file -> `media`
52
- - date/published/created/updated/event time -> `datetime`
120
+ - image/photo/thumbnail/media/asset/file -> `media`, carrying the source alt on
121
+ the media value; never add a separate alt field (`references/media.md`)
122
+ - date/published/created/updated -> `date`; use `datetime` only when the crawled
123
+ values carry a time and a UTC offset, which `datetime` requires
124
+ - event start/end time -> `datetime`
53
125
  - price/amount/rating/order/count -> `number`
54
126
  - featured/draft/published/enabled/archived -> `boolean`
55
- - category/tag/author/reference -> `reference` only when verified, otherwise
56
- `string` or tag-like text
57
-
58
- If unsure, preserve the raw value in the migration artifacts and add a note.
127
+ - repeated section/section stack/nested item list -> `blocks` with one named
128
+ variant per distinct section shape
129
+ - category/tag/author/related item/shared entity -> `reference` to the content
130
+ type that models it (see References below)
131
+ - structured data with no Fimo-native equivalent -> `json`, with the reason
132
+ recorded
133
+
134
+ Keep media as `media`, including inside blocks, and preserve proven relationship
135
+ targets, direction, and cardinality. Do not turn a fixed enum, application-owned
136
+ taxonomy, or accidental string match into a reference. If unsure, preserve the
137
+ exact raw value in the migration artifacts and record the mapping as unresolved
138
+ or incompatible rather than losing content.
59
139
 
60
140
  ## Entries
61
141
 
@@ -65,33 +145,37 @@ For every content type:
65
145
  - preserve slugs
66
146
  - preserve SEO title, description, share image, canonical URL when available
67
147
  - preserve publish status and dates
68
- - preserve authors, categories, and tags
148
+ - preserve authors, categories, and tags as references to their content types
149
+ - preserve each media value's source alt text on the media value itself
69
150
  - convert rich HTML to the current Fimo rich text representation
70
151
  - keep source count, generated count, imported count, and skipped count in the
71
- manifest
152
+ migration plan/report
72
153
 
73
154
  Do not wire a page to remote Fimo content until the matching schema exists and
74
155
  the page has a seed/empty state for local development.
75
156
 
76
157
  ## References
77
158
 
78
- Create references only when:
79
-
80
- - exports contain stable reference IDs
81
- - repeated values clearly match another exported collection
82
- - the user confirms the relationship
159
+ Model categories, tags, authors, related items, shared entities, and repeated
160
+ taxonomies as `reference` fields pointing at their own content type. An editor
161
+ picks an entry; they do not retype a string, maintain a list of raw IDs, or edit
162
+ an opaque JSON array. When the source has no schema for that entity, infer a
163
+ clean editor-facing one from the values themselves - a `Category` with `name`
164
+ and `slug` - instead of leaving the value hardcoded.
83
165
 
84
166
  Use a two-pass import for references:
85
167
 
86
168
  1. import all referenced entries with source IDs and slugs
87
169
  2. resolve reference fields to target IDs/slugs
88
170
 
89
- If reference confidence is low, keep a string/tag field and record an unresolved
90
- item.
171
+ The source still bounds the model. A repeated value is proof of a shared entity;
172
+ it is not proof of a link the source never makes. Keep free text that has no
173
+ shared identity as a string, and leave an unproven relationship unresolved with
174
+ an owner action rather than synthesizing an ID.
91
175
 
92
176
  ## Skips
93
177
 
94
- Skipped fields or entries require a manifest note with:
178
+ Skipped fields or entries require a note in the migration plan/report with:
95
179
 
96
180
  - source location
97
181
  - reason