fimo 0.17.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.
- package/assets/astro/components/DateTime.astro +22 -0
- package/assets/astro/components/index.d.ts +1 -0
- package/assets/astro/components/index.js +1 -0
- package/assets/content-templates/shared/types.eta +2 -0
- package/assets/skills/fimo-cli/SKILL.md +3 -2
- package/assets/skills/fimo-cli/references/content.md +2 -2
- package/assets/skills/fimo-cli/references/deploy.md +2 -0
- package/assets/skills/fimo-cli/references/init.md +11 -4
- package/assets/skills/fimo-cli/references/locales.md +38 -14
- package/assets/skills/fimo-cli/references/pages.md +70 -0
- package/assets/skills/fimo-cli/references/webhooks.md +1 -1
- package/assets/skills/fimo-code/SKILL.md +11 -0
- package/assets/skills/fimo-code/assets/react-router-locales/LocaleLayout.tsx +12 -0
- package/assets/skills/fimo-code/assets/react-router-locales/routes.ts +7 -6
- package/assets/skills/fimo-code/references/best-practices/astro.md +47 -0
- package/assets/skills/fimo-code/references/best-practices/next.md +42 -0
- package/assets/skills/fimo-code/references/best-practices/sveltekit.md +17 -0
- package/assets/skills/fimo-code/references/content/richtext.md +5 -0
- package/assets/skills/fimo-code/references/content/schema.md +4 -1
- package/assets/skills/fimo-code/references/frameworks/astro.md +5 -3
- package/assets/skills/fimo-code/references/frameworks/hosting.md +5 -2
- package/assets/skills/fimo-code/references/frameworks/next/app-router.md +6 -0
- package/assets/skills/fimo-code/references/frameworks/next/locales.md +12 -2
- package/assets/skills/fimo-code/references/frameworks/next.md +7 -0
- package/assets/skills/fimo-code/references/frameworks/react-router.md +15 -7
- package/assets/skills/fimo-code/references/frameworks/sveltekit.md +15 -8
- package/assets/skills/fimo-code/references/labels.md +9 -1
- package/assets/skills/fimo-code/references/locales.md +8 -2
- package/assets/skills/fimo-code/references/migrations/react-router-route-ownership.md +93 -0
- package/assets/skills/fimo-code/references/ui.md +21 -2
- package/assets/skills/fimo-migration/SKILL.md +276 -51
- package/assets/skills/fimo-migration/references/content.md +119 -35
- package/assets/skills/fimo-migration/references/decision.md +72 -0
- package/assets/skills/fimo-migration/references/forms.md +38 -6
- package/assets/skills/fimo-migration/references/frameworks/nextjs.md +179 -23
- package/assets/skills/fimo-migration/references/import-contract.md +71 -19
- package/assets/skills/fimo-migration/references/manifest.md +11 -161
- package/assets/skills/fimo-migration/references/media.md +33 -1
- package/assets/skills/fimo-migration/references/platforms.md +26 -2
- package/assets/skills/fimo-migration/references/qa.md +167 -13
- package/assets/skills/fimo-migration/references/workers/content-execution.md +39 -0
- package/assets/skills/fimo-migration/references/workers/content-planner.md +64 -0
- package/assets/skills/fimo-migration/references/workers/framework.md +37 -0
- package/assets/skills/fimo-migration/references/workers/validator.md +25 -0
- package/assets/skills/fimo-migration/references/workers.md +82 -0
- package/assets/skills/fimo-migration/references/workflow.md +140 -192
- package/assets/skills/fimo-migration/scripts/apply-decision.mjs +534 -0
- package/assets/skills/fimo-migration/scripts/build-canonical-manifest.mjs +7 -4
- package/assets/skills/fimo-migration/scripts/write-migration-report.mjs +191 -4
- package/assets/skills/fimo-studio/references/cms.md +25 -7
- package/assets/skills/fimo-studio/references/webhooks.md +1 -1
- package/assets/sveltekit/components/DateTime.svelte +35 -0
- package/assets/sveltekit/components/FimoProvider.svelte +2 -2
- package/assets/sveltekit/components/index.d.ts +1 -0
- package/assets/sveltekit/components/index.js +1 -0
- package/dist/build/next/config.d.ts +4 -1
- package/dist/build/next/config.js +21 -5
- package/dist/build/sveltekit/vite.d.ts +3 -4
- package/dist/build/sveltekit/vite.js +3 -4
- package/dist/build/vite/plugins/runtime-env.d.ts +2 -1
- package/dist/build/vite/plugins/runtime-env.js +14 -10
- package/dist/cli/bundle.json +2 -2
- package/dist/cli/index.js +76 -78
- package/dist/runtime/app/FimoProviders.js +25 -14
- package/dist/runtime/app/prefetch.d.ts +3 -1
- package/dist/runtime/app/prefetch.js +11 -55
- package/dist/runtime/astro/preview.js +7 -9
- package/dist/runtime/content/client/internal.js +1 -0
- package/dist/runtime/i18n/locale.d.ts +4 -0
- package/dist/runtime/i18n/locale.js +14 -14
- package/dist/runtime/next/client-runtime.js +5 -1
- package/dist/runtime/next/client.d.ts +3 -2
- package/dist/runtime/next/client.js +2 -1
- package/dist/runtime/next/labels.d.ts +2 -2
- package/dist/runtime/next/labels.js +2 -2
- package/dist/runtime/next/preview.d.ts +13 -0
- package/dist/runtime/next/preview.js +34 -0
- package/dist/runtime/next/primitives/server.d.ts +2 -0
- package/dist/runtime/next/primitives/server.js +8 -0
- package/dist/runtime/next/provider.d.ts +5 -0
- package/dist/runtime/next/provider.js +17 -3
- package/dist/runtime/next/server-runtime.js +4 -1
- package/dist/runtime/next/server.d.ts +1 -1
- package/dist/runtime/next/server.js +1 -1
- package/dist/runtime/paths/get-fimo-paths.d.ts +6 -5
- package/dist/runtime/paths/get-fimo-paths.js +43 -42
- package/dist/runtime/preview/location.d.ts +19 -2
- package/dist/runtime/preview/location.js +16 -2
- package/dist/runtime/primitives/index.d.ts +1 -0
- package/dist/runtime/primitives/index.js +1 -0
- package/dist/runtime/react/primitives/editable/DateTime.d.ts +4 -0
- package/dist/runtime/react/primitives/editable/DateTime.js +13 -0
- package/dist/runtime/react/primitives/renderers/DateRenderer.d.ts +7 -1
- package/dist/runtime/react/primitives/renderers/DateRenderer.js +11 -8
- package/dist/runtime/react-router/{routes.d.ts → legacy/routes.d.ts} +6 -1
- package/dist/runtime/react-router/{routes.js → legacy/routes.js} +22 -7
- package/dist/runtime/routes/contract.d.ts +116 -0
- package/dist/runtime/routes/contract.js +377 -0
- package/dist/runtime/routes/index.d.ts +3 -0
- package/dist/runtime/routes/index.js +3 -0
- package/dist/runtime/routing/AppRoutesProvider.js +4 -3
- package/dist/runtime/seo/resolver.d.ts +5 -0
- package/dist/runtime/seo/resolver.js +10 -42
- package/dist/runtime/shared/fimo-config.types.d.ts +34 -8
- package/dist/runtime/shared/preview-location.d.ts +1 -22
- package/dist/runtime/shared/preview-location.js +5 -93
- package/dist/runtime/sveltekit/preview.d.ts +12 -3
- package/dist/runtime/sveltekit/preview.js +13 -8
- package/dist/scripts/sync-forms.js +1 -1
- package/dist/scripts/sync-schemas.js +1 -4
- package/dist/scripts/validate-fimo-config.js +5 -1
- package/dist/scripts/validate-page-registry.d.ts +2 -0
- package/dist/scripts/validate-page-registry.js +167 -0
- package/dist/scripts/validate-route-metadata.js +132 -41
- package/package.json +7 -3
- package/templates/astro/.fimo/config.json +13 -5
- package/templates/astro/AGENTS.md +5 -1
- package/templates/astro/astro.config.mjs +7 -0
- package/templates/astro/pnpm-workspace.yaml +0 -3
- package/templates/astro/src/components/ProjectOverview.astro +9 -6
- package/templates/astro/src/layouts/Base.astro +1 -1
- package/templates/astro/src/locales.ts +4 -0
- package/templates/astro/src/pages/[locale]/index.astro +19 -0
- package/templates/astro/src/pages/[locale]/projects/[slug].astro +35 -0
- package/templates/astro/src/pages/[locale]/projects/index.astro +19 -0
- package/templates/astro/src/pages/index.astro +5 -2
- package/templates/astro/src/pages/projects/[slug].astro +4 -2
- package/templates/astro/src/pages/projects/index.astro +5 -2
- package/templates/nextjs/.fimo/config.json +2 -1
- package/templates/nextjs/AGENTS.md +5 -0
- package/templates/nextjs/src/app/(default)/layout.tsx +10 -0
- package/templates/nextjs/src/app/[locale]/layout.tsx +22 -0
- package/templates/nextjs/src/app/[locale]/page.tsx +1 -0
- package/templates/nextjs/src/components/Document.tsx +26 -0
- package/templates/nextjs/src/components/FimoPreviewBridge.tsx +13 -0
- package/templates/nextjs/src/locales.ts +13 -0
- package/templates/react-router/.fimo/config.json +3 -6
- package/templates/react-router/AGENTS.md +4 -0
- package/templates/react-router/package.json +1 -1
- package/templates/react-router/pnpm-workspace.yaml +1 -3
- package/templates/react-router/react-router.config.ts +4 -10
- package/templates/react-router/src/pages/LocaleLayout.tsx +12 -0
- package/templates/react-router/src/root.tsx +2 -4
- package/templates/react-router/src/routes.ts +5 -3
- package/templates/sveltekit/.fimo/config.json +2 -1
- package/templates/sveltekit/AGENTS.md +5 -0
- package/templates/sveltekit/src/app.html +1 -1
- package/templates/sveltekit/src/hooks.server.ts +11 -0
- package/templates/sveltekit/src/locales.ts +8 -0
- package/templates/sveltekit/src/params/locale.ts +5 -0
- package/templates/sveltekit/src/routes/+layout.server.ts +6 -1
- package/templates/sveltekit/src/routes/+layout.svelte +5 -0
- package/assets/skills/fimo-migration/references/inventory/coordinator.md +0 -40
- package/assets/skills/fimo-migration/references/inventory/locales/next-intl.md +0 -39
- package/assets/skills/fimo-migration/references/inventory/locales.md +0 -41
- package/assets/skills/fimo-migration/scripts/inventory/locales/next-intl.mjs +0 -459
- package/templates/nextjs/src/app/layout.tsx +0 -17
- /package/templates/nextjs/src/app/{page.tsx → (default)/page.tsx} +0 -0
- /package/templates/sveltekit/src/routes/{+page.svelte → [[locale=locale]]/+page.svelte} +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Migration decisions
|
|
2
|
+
|
|
3
|
+
Migration decisions are plain text. Put them in
|
|
4
|
+
`.fimo/migration/migration-plan.md` and the relevant worker report. Do not
|
|
5
|
+
create `.fimo/migration/decision.json`, a target metadata file, or a second
|
|
6
|
+
decision registry.
|
|
7
|
+
|
|
8
|
+
The decision must say, in ordinary language:
|
|
9
|
+
|
|
10
|
+
- what the source construct is;
|
|
11
|
+
- where it is proven in the source;
|
|
12
|
+
- whether it becomes collection content, a single, a label, or
|
|
13
|
+
application-owned code;
|
|
14
|
+
- which schema/payload and consuming files are involved;
|
|
15
|
+
- what was preserved, replaced, or left unresolved; and
|
|
16
|
+
- who or what must do the next action.
|
|
17
|
+
|
|
18
|
+
The owning worker may write schemas, content payloads, entries, assets, singles,
|
|
19
|
+
and labels directly through the normal Fimo CLI/API contracts. The text plan is
|
|
20
|
+
the handoff; it is not an approval queue and it is not required to replay a
|
|
21
|
+
completed migration.
|
|
22
|
+
|
|
23
|
+
## Labels
|
|
24
|
+
|
|
25
|
+
A label is UI-visible copy presented to a visitor or user: navigation text,
|
|
26
|
+
headings, buttons, form labels, validation and error text, calls to action,
|
|
27
|
+
visible empty states, and visible translated copy.
|
|
28
|
+
|
|
29
|
+
Do not classify every string as a label. Object keys, route segments, CSS
|
|
30
|
+
tokens, analytics event names, internal identifiers, prices and other data
|
|
31
|
+
values, application settings, and assistive-only attribute text remain in
|
|
32
|
+
application code unless the source proves they are editor-managed content.
|
|
33
|
+
Record the source file and consuming UI for each label.
|
|
34
|
+
|
|
35
|
+
## Schema decisions
|
|
36
|
+
|
|
37
|
+
Write the complete valid Fimo schema that the source justifies. For every field,
|
|
38
|
+
decide its Fimo type, requiredness, default, string options, uniqueness,
|
|
39
|
+
locale-sharing behavior, media multiplicity/MIME constraints, and reference
|
|
40
|
+
target/cardinality when the source proves them. The schema JSON is an actual
|
|
41
|
+
Fimo artifact and may be pushed by the content planner; it is not a report
|
|
42
|
+
about the agent's reasoning.
|
|
43
|
+
|
|
44
|
+
Choose field types from source semantics and editor experience, following
|
|
45
|
+
`references/content.md`: use richtext for portable editorial prose, blocks for
|
|
46
|
+
structured or repeatable editorial sections, media for assets, and references
|
|
47
|
+
for independently managed records proven by the source. Use JSON only for
|
|
48
|
+
opaque or application-owned data that has no Fimo-native model, and record why.
|
|
49
|
+
|
|
50
|
+
Requiredness and defaults come from the source contract, such as a CMS schema,
|
|
51
|
+
collection configuration, validation contract, or type declaration. A field is
|
|
52
|
+
not required merely because the sampled files fill it. Use only source-declared
|
|
53
|
+
or safe technical defaults such as an empty list, `false`, or absent. Never
|
|
54
|
+
invent human-readable copy as a default.
|
|
55
|
+
|
|
56
|
+
Preserve the raw value and explain the uncertainty in the text plan when a
|
|
57
|
+
mapping is unclear. Validate every schema against the actual Fimo CLI/content
|
|
58
|
+
schema contract and use its generated clients, renderers, and primitives.
|
|
59
|
+
|
|
60
|
+
## Mapping rules
|
|
61
|
+
|
|
62
|
+
- Markdown collections become one content type plus one document per slug.
|
|
63
|
+
- Localized documents become one document with one payload per locale.
|
|
64
|
+
- Local assets referenced by content become media-library uploads, and the
|
|
65
|
+
content payload references the uploaded asset. Media owns its alt text; do
|
|
66
|
+
not add a parallel alt field to the content schema.
|
|
67
|
+
- Routes map source route modules to target route modules.
|
|
68
|
+
- References are created only from stable source identity or a confirmed
|
|
69
|
+
mapping.
|
|
70
|
+
- A custom or executable construct is unresolved only when it genuinely cannot
|
|
71
|
+
be carried over. Record its exact source location, why it is not portable,
|
|
72
|
+
and a suggested action. Never silently remove it.
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
# Forms
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Preserve the behavior a visitor sees. Replace a form with a Fimo form only when
|
|
4
|
+
Fimo reproduces the source form's user-visible behavior end to end; otherwise
|
|
5
|
+
keep the original integration wired and record what it needs.
|
|
5
6
|
|
|
6
7
|
## Classify
|
|
7
8
|
|
|
8
|
-
Use `fimo-native` when
|
|
9
|
-
|
|
9
|
+
Use `fimo-native` only when Fimo genuinely reproduces the source form's
|
|
10
|
+
user-visible behavior end to end: a simple contact, newsletter, lead capture,
|
|
11
|
+
RSVP, or quote request form whose submit, validation, and success/error flow a
|
|
12
|
+
Fimo form matches 1:1.
|
|
10
13
|
|
|
11
|
-
Use `third-party` when the form posts to Mailchimp, HubSpot, Typeform,
|
|
12
|
-
Zapier, Airtable, payment providers, or another external backend.
|
|
14
|
+
Use `third-party` when the form posts to Brevo, Mailchimp, HubSpot, Typeform,
|
|
15
|
+
Formspree, Zapier, Airtable, payment providers, or another external backend.
|
|
16
|
+
When the external behavior is not 1:1 reproducible - a Brevo double-opt-in
|
|
17
|
+
newsletter flow, for example - keeping the original integration wired is the
|
|
18
|
+
correct terminal state, not a migration failure.
|
|
13
19
|
|
|
14
20
|
Use `unsupported` when the form depends on auth, checkout, dynamic pricing,
|
|
15
21
|
multi-step state, file workflows not supported by the current project, custom JS,
|
|
@@ -43,6 +49,32 @@ For `fimo-native` forms:
|
|
|
43
49
|
Do not claim live submission parity until the form has been pushed/imported and
|
|
44
50
|
rendered by the site.
|
|
45
51
|
|
|
52
|
+
## Definition Versus Wiring
|
|
53
|
+
|
|
54
|
+
Importing the Fimo form definition and wiring the source form UI are two
|
|
55
|
+
different obligations; report them separately.
|
|
56
|
+
|
|
57
|
+
- The definition (`src/forms/*.json`, pushed to Fimo) covers what the form
|
|
58
|
+
collects: fields, options, required flags.
|
|
59
|
+
- The wiring covers the behavior the visitor sees around the form: the source
|
|
60
|
+
page's markup, conditional pricing, availability rules, client-side
|
|
61
|
+
validation, and the submit/success/error flow. Preserve that local behavior
|
|
62
|
+
in the application code where possible; pushing the definition does not
|
|
63
|
+
migrate it.
|
|
64
|
+
- A third-party integration may be explicitly deferred as an unresolved item
|
|
65
|
+
with the source action and an owner decision, but a form is never reported
|
|
66
|
+
as migrated while its local behavior is missing or its integration was
|
|
67
|
+
silently dropped.
|
|
68
|
+
|
|
69
|
+
## Credentials And Secrets
|
|
70
|
+
|
|
71
|
+
Record the credential environment keys a preserved integration needs by name
|
|
72
|
+
(`BREVO_API_KEY`, not its value). Never read secret values or copy them into
|
|
73
|
+
migration artifacts. A missing secret is a user follow-up in the report: the
|
|
74
|
+
integration stays wired, local build, evaluation, and QA checks still run with
|
|
75
|
+
the integration inert, and the behavior is never deleted because its secret is
|
|
76
|
+
unavailable.
|
|
77
|
+
|
|
46
78
|
## Unsupported Or Third-Party Forms
|
|
47
79
|
|
|
48
80
|
Create an unresolved item with:
|
|
@@ -1,26 +1,182 @@
|
|
|
1
|
-
# Next.js source
|
|
1
|
+
# Next.js source
|
|
2
2
|
|
|
3
|
-
Load this reference when the migration source is a Next.js application
|
|
4
|
-
|
|
3
|
+
Load this reference when the migration source is a Next.js application or the
|
|
4
|
+
user explicitly chose Next.js as a conversion target. It describes what each
|
|
5
|
+
worker must read in that source; use the target project's `fimo-code`
|
|
5
6
|
framework guidance when implementing the migrated application.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
8
|
+
A Next.js source stays a Next.js target. Keep the detected router flavor,
|
|
9
|
+
`next.config.*`, middleware, and runtime configuration; do not convert the app
|
|
10
|
+
to React Router or another framework to simplify the migration. When framework
|
|
11
|
+
detection is ambiguous, stop and ask. A non-Next.js source converts to Next.js
|
|
12
|
+
only when the user explicitly chooses it.
|
|
13
|
+
|
|
14
|
+
## Next.js as a conversion target
|
|
15
|
+
|
|
16
|
+
When the user explicitly chose converting another framework (for example React
|
|
17
|
+
Router/Vite) to Next.js, the framework conversion worker in
|
|
18
|
+
`references/workers.md` owns the target. It inspects the app tree that
|
|
19
|
+
`fimo migrate init` actually created, keeps that single tree, and rebuilds the
|
|
20
|
+
source routes, 404, redirects, headers, middleware, sitemap/robots/OG
|
|
21
|
+
structure, and locale routing structure inside it. It ports the source's own
|
|
22
|
+
loaders, APIs, hardcoded content, and integrations unchanged; Fimo wiring
|
|
23
|
+
happens later through the content workers. The conversion must pass the
|
|
24
|
+
framework gate before content data and code workers start.
|
|
25
|
+
|
|
26
|
+
Use package versions to prioritize likely shapes, not as proof of the source.
|
|
27
|
+
Projects backport, customize, and combine conventions across versions; accept a
|
|
28
|
+
claim only when its source evidence supports it.
|
|
29
|
+
|
|
30
|
+
## Runtime and routes
|
|
31
|
+
|
|
32
|
+
1. Record the installed Next.js, content, and internationalization package
|
|
33
|
+
declarations. A data-source package is a retrieval clue for the content
|
|
34
|
+
worker, nothing more.
|
|
35
|
+
2. Identify App Router, Pages Router, or a mixed tree.
|
|
36
|
+
3. Read `next.config.*`, request configuration, middleware or proxy files,
|
|
37
|
+
navigation helpers, and route segments before changing them. Map every
|
|
38
|
+
source route to a target route module, a redirect, or an unresolved item.
|
|
39
|
+
4. Inventory `redirects()`, `rewrites()`, `headers()`, route handlers,
|
|
40
|
+
middleware, cache/revalidation calls, and provider adapters separately.
|
|
41
|
+
Preserve each rule until its behavior is replaced and verified. Record the
|
|
42
|
+
disposition of every rule; do not delete a whole provider file because some
|
|
43
|
+
rules became redundant.
|
|
44
|
+
|
|
45
|
+
## Equivalents and hosting boundary
|
|
46
|
+
|
|
47
|
+
Load the target project's `fimo-code` `frameworks/next` and
|
|
48
|
+
`frameworks/hosting` references before implementing. Use normal Next.js
|
|
49
|
+
equivalents when they fit the accepted contract:
|
|
50
|
+
|
|
51
|
+
- route modules and route handlers for routes, feeds, negotiated responses, and
|
|
52
|
+
special text/XML files;
|
|
53
|
+
- `not-found` and `notFound()` for framework-owned 404 behavior;
|
|
54
|
+
- metadata APIs and OG/Twitter image routes for SEO and social output;
|
|
55
|
+
- `redirects()`, `rewrites()`, `headers()`, middleware, or response headers for
|
|
56
|
+
rules that the chosen runtime actually executes; and
|
|
57
|
+
- Next.js fetch/cache/revalidation APIs only when freshness is an observable
|
|
58
|
+
requirement rather than copied provider machinery.
|
|
59
|
+
|
|
60
|
+
These are application-level options, not guarantees that Fimo hosting supports
|
|
61
|
+
every header, redirect, route handler, cache mode, edge API, or middleware
|
|
62
|
+
behavior. Verify the chosen host/runtime. If support cannot be established,
|
|
63
|
+
preserve the existing deployment path or record the behavior unresolved and ask
|
|
64
|
+
the user; do not promise equivalence from code shape alone.
|
|
65
|
+
|
|
66
|
+
### Port Cloudflare behavior
|
|
67
|
+
|
|
68
|
+
Do not mark a rule unresolved merely because it came from a Cloudflare Worker:
|
|
69
|
+
port static redirects, rewrites, headers, and asset cache headers to the real
|
|
70
|
+
`next.config.*`, then verify each with a request. Put dynamic behavior in
|
|
71
|
+
middleware or route handlers, and use Next.js cache/revalidation APIs when they
|
|
72
|
+
replace observable freshness. Cloudflare-only Cache API, bindings, `waitUntil`,
|
|
73
|
+
and purge calls need a verified host equivalent or remain explicitly unresolved.
|
|
74
|
+
|
|
75
|
+
Give every worker rule a `preserved`, `replaced`,
|
|
76
|
+
`safely-unnecessary-implementation-detail`, or `unresolved` disposition with
|
|
77
|
+
its target file and request-level proof.
|
|
78
|
+
|
|
79
|
+
## SEO, OG, and social
|
|
80
|
+
|
|
81
|
+
The routes/SEO worker owns the source's existing SEO and social surface:
|
|
82
|
+
`metadata` exports, `generateMetadata`, `opengraph-image.*` and
|
|
83
|
+
`twitter-image.*` route files, dynamic OG image routes built on
|
|
84
|
+
`ImageResponse`, canonical URLs, robots, and sitemap generation. Preserve each
|
|
85
|
+
behavior in place; when one cannot be preserved, record an explicit gap with
|
|
86
|
+
the affected routes instead of shipping pages that silently lost their share
|
|
87
|
+
metadata.
|
|
88
|
+
|
|
89
|
+
## Build-time and browser runtime
|
|
90
|
+
|
|
91
|
+
The Next server runtime reads `FIMO_CONTENT_API_URL`; client components and
|
|
92
|
+
generated client hooks read `NEXT_PUBLIC_FIMO_API_URL`. For a local production
|
|
93
|
+
build or migration acceptance run, expose both names and point them at the
|
|
94
|
+
same tenant content URL. `FIMO_API_URL` is the management/CLI API and is not a
|
|
95
|
+
substitute for either content API variable.
|
|
96
|
+
|
|
97
|
+
`withFimo` derives these aliases during `next dev` when the project is linked,
|
|
98
|
+
so local development does not need hand-written values. A production build,
|
|
99
|
+
however, compiles `NEXT_PUBLIC_*` values into the browser bundle and the
|
|
100
|
+
adapter intentionally does not inject them outside the development phase.
|
|
101
|
+
For `next build`/`next start`, set temporary values in the shell or an ignored
|
|
102
|
+
`.env.local`; never commit secret values. In either mode, exercise at least one
|
|
103
|
+
client-side data read after startup.
|
|
104
|
+
|
|
105
|
+
## Preview embedding and response headers
|
|
106
|
+
|
|
107
|
+
Fimo Preview loads the app in an iframe and drives it over the postMessage
|
|
108
|
+
preview bridge, so development/preview responses must let the preview origin
|
|
109
|
+
frame the app.
|
|
110
|
+
|
|
111
|
+
- `withFimo` consumes `FIMO_PREVIEW_ALLOWED_ORIGINS` (platform-supplied,
|
|
112
|
+
comma-separated `**.<domain>` patterns) only to extend `allowedDevOrigins`
|
|
113
|
+
during `next dev`. It does not add, remove, or rewrite response headers;
|
|
114
|
+
wrapping the config never fixes a framing block by itself.
|
|
115
|
+
- When the source `headers()` sends `X-Frame-Options` or a CSP
|
|
116
|
+
`frame-ancestors` directive, keep `X-Content-Type-Options`,
|
|
117
|
+
`Strict-Transport-Security`, and `Referrer-Policy` unchanged, and translate
|
|
118
|
+
the framing block in the migrated config. For a hosted/remote preview, while
|
|
119
|
+
`FIMO_PREVIEW_ALLOWED_ORIGINS` is set, omit `X-Frame-Options` and send
|
|
120
|
+
`Content-Security-Policy: frame-ancestors 'self' https://*.<domain>` derived
|
|
121
|
+
from each `**.<domain>` entry. For local `next dev`, when the platform
|
|
122
|
+
variable is absent, omit the framing block only while
|
|
123
|
+
`process.env.NODE_ENV !== 'production'`; keep the source framing policy in
|
|
124
|
+
production. Never hardcode a preview provider domain.
|
|
125
|
+
- Record every translated or dropped header in the runtime report's Hosting
|
|
126
|
+
section.
|
|
127
|
+
|
|
128
|
+
Without a browser, verify embeddability deterministically: with the variable
|
|
129
|
+
set, request a route from the running dev server and assert the response
|
|
130
|
+
headers carry no unconditional framing block, then mark visual proof
|
|
131
|
+
unavailable in the QA report.
|
|
132
|
+
|
|
133
|
+
## Locales
|
|
134
|
+
|
|
135
|
+
Keep these claims separate, and treat any one of them as unproven until its
|
|
136
|
+
source says so: dictionary locale candidates, configured locales, the default
|
|
137
|
+
locale, publicly routable locales, and localized pathnames. A dictionary file
|
|
138
|
+
never proves route reachability.
|
|
139
|
+
|
|
140
|
+
When `package.json` declares next-intl, the locales worker reads the actual
|
|
141
|
+
message files, `defineRouting` values, middleware, request helpers, and call
|
|
142
|
+
sites directly. A dictionary filename is evidence for a message locale, not
|
|
143
|
+
proof that the locale is routable. If the source uses another library or a
|
|
144
|
+
custom store, follow its imports and reads in the same worker. The worker may
|
|
145
|
+
write a short bounded temporary extractor when that is faster, but it owns the
|
|
146
|
+
interpretation and must record the source evidence and any unresolved claim.
|
|
147
|
+
|
|
148
|
+
## Markdown, MDX, and inline content
|
|
149
|
+
|
|
150
|
+
The content planner reads the content itself: file locations and formats,
|
|
151
|
+
frontmatter keys and values, locale-shaped filenames or directories, route and
|
|
152
|
+
component modules that consume them, hardcoded arrays and object literals, and
|
|
153
|
+
local asset references under `public/`. It records every consuming source and
|
|
154
|
+
target module in `affectedFiles` before code workers start. Nested frontmatter,
|
|
155
|
+
mixed locale conventions, missing local assets, and unproven route references
|
|
156
|
+
need a decision from the source, not a guess.
|
|
157
|
+
|
|
158
|
+
Map what the source proves: a directory of Markdown files with several slugs may
|
|
159
|
+
be one collection, locale-suffixed files may be locale payloads of one
|
|
160
|
+
document, and a `public/` reference may become a media upload. The content
|
|
161
|
+
planner decides the destination from the consuming route and data shape, rather
|
|
162
|
+
than using a filename or extension as an automatic classification.
|
|
163
|
+
|
|
164
|
+
Create one source item per Markdown/MDX document and per independently handled
|
|
165
|
+
construct inside it. Portable prose and an executable MDX component are
|
|
166
|
+
different items even when they share one file. Read the custom component, its
|
|
167
|
+
import, and its data path; assign it to a code batch when it can be rebuilt with
|
|
168
|
+
native Fimo content, otherwise record it unresolved before data import begins.
|
|
169
|
+
Never remove JSX from the richtext payload without representing that JSX as its
|
|
170
|
+
own migrated or unresolved source item.
|
|
171
|
+
|
|
172
|
+
For a hardcoded content array, create one source item per object and preserve
|
|
173
|
+
observable order explicitly. The matching data batch count must equal the
|
|
174
|
+
source item count. A schema and query with zero planned entry items is an
|
|
175
|
+
incomplete handoff.
|
|
176
|
+
|
|
177
|
+
Use a temporary read-only extractor only when it reduces repeated work. Parsing
|
|
178
|
+
frontmatter or a large literal array can be useful; a general Next.js AST parser
|
|
179
|
+
is not required. Record the mapping in the text content plan and worker report.
|
|
180
|
+
|
|
181
|
+
Content that is not file-backed follows the content planner's discovery branches
|
|
182
|
+
in `references/workers.md`; preserve every provider gap as unresolved evidence.
|
|
@@ -8,6 +8,13 @@ but it is not complete until the relevant Fimo project contains the imported
|
|
|
8
8
|
assets, schemas, entries, and forms, or the gaps are owner-visible unresolved
|
|
9
9
|
items.
|
|
10
10
|
|
|
11
|
+
Every data-plane write in this contract targets the linked project from
|
|
12
|
+
workflow Phase 0. Local artifacts never require the link — `fimo migrate
|
|
13
|
+
import` only prints the import plan (it writes no data) and warns in an
|
|
14
|
+
unlinked directory — running the printed commands is what needs the link.
|
|
15
|
+
When no owner-supplied target exists, the writes stay unresolved owner
|
|
16
|
+
actions; do not fake a link to make them pass.
|
|
17
|
+
|
|
11
18
|
## Media Files
|
|
12
19
|
|
|
13
20
|
Discovery must include:
|
|
@@ -17,13 +24,17 @@ Discovery must include:
|
|
|
17
24
|
- CMS media fields
|
|
18
25
|
- SEO/share images
|
|
19
26
|
- downloadable files linked from pages or entries
|
|
27
|
+
- every schema media field, including empty or unresolved source values
|
|
28
|
+
- image nodes nested anywhere in richtext or Tiptap payloads
|
|
20
29
|
|
|
21
30
|
Import requirements:
|
|
22
31
|
|
|
23
|
-
- every imported asset records a Fimo target asset ID or URL in
|
|
24
|
-
|
|
32
|
+
- every imported asset records a Fimo target asset ID or URL in the worker and
|
|
33
|
+
migration reports
|
|
25
34
|
- every failed asset has an unresolved item with references to the affected
|
|
26
35
|
route or entry
|
|
36
|
+
- every planner media obligation has an uploaded mapping, an explicit
|
|
37
|
+
unresolved/unsupported disposition, or a proven duplicate mapping
|
|
27
38
|
- CMS media fields are rewritten after upload; source URLs are not left in
|
|
28
39
|
editable entry payloads unless explicitly unresolved
|
|
29
40
|
|
|
@@ -46,10 +57,14 @@ Discovery must include:
|
|
|
46
57
|
|
|
47
58
|
Import requirements:
|
|
48
59
|
|
|
49
|
-
- schemas are pushed before
|
|
60
|
+
- schemas are validated and pushed before media or content writes
|
|
61
|
+
- `fimo schemas push` reconciles an ambiguous 504 by reading every requested
|
|
62
|
+
schema back. A complete match counts as committed; when all are absent it
|
|
63
|
+
retries once; mixed, mismatched, or still-absent state stops for review
|
|
64
|
+
instead of replaying another blind write.
|
|
50
65
|
- entries are created or updated in Fimo, not only written as seed JSON
|
|
51
66
|
- source count, generated count, imported count, skipped count, and unresolved
|
|
52
|
-
count are recorded per content type
|
|
67
|
+
count are recorded per content type in the text plan/report
|
|
53
68
|
- references are resolved in a second pass only when stable IDs or confirmed
|
|
54
69
|
mappings exist
|
|
55
70
|
|
|
@@ -72,32 +87,69 @@ Discovery must include:
|
|
|
72
87
|
|
|
73
88
|
Import requirements:
|
|
74
89
|
|
|
75
|
-
-
|
|
76
|
-
to
|
|
77
|
-
- third-party
|
|
78
|
-
|
|
90
|
+
- a form becomes `src/forms/*.json` and is pushed to Fimo only when the Fimo
|
|
91
|
+
form reproduces the source form's user-visible behavior end to end
|
|
92
|
+
- a third-party form whose behavior is not 1:1 reproducible keeps its original
|
|
93
|
+
integration wired, with the required credential environment keys recorded by
|
|
94
|
+
name (never their values) and any missing secret reported as a user
|
|
95
|
+
follow-up
|
|
96
|
+
- unsupported forms are recorded with source action, reason, and owner action
|
|
79
97
|
- the report records form count, Fimo-native count, third-party count, and
|
|
80
98
|
unsupported/unresolved count
|
|
81
99
|
|
|
82
100
|
Acceptance:
|
|
83
101
|
|
|
84
|
-
- every visible source form is represented by a Fimo form,
|
|
85
|
-
unsupported/unresolved item
|
|
102
|
+
- every visible source form is represented by a Fimo form, a preserved
|
|
103
|
+
third-party integration, or an unsupported/unresolved item
|
|
86
104
|
- no page keeps a broken form UI that appears live
|
|
87
105
|
|
|
106
|
+
Historical form submissions do not have a write contract. The current
|
|
107
|
+
form-submissions CLI is read-only, so never claim that old submissions were
|
|
108
|
+
imported. Preserve the source export and record historical submission import as
|
|
109
|
+
unsupported with an owner action until a dedicated import contract exists.
|
|
110
|
+
|
|
111
|
+
## Pagination And Batching
|
|
112
|
+
|
|
113
|
+
The data-plane commands are paginated and capped. Read the limits instead of
|
|
114
|
+
assuming one request covers everything:
|
|
115
|
+
|
|
116
|
+
- `fimo entries list` and `fimo assets list` return 20 items by default and at
|
|
117
|
+
most 100 per request (`--limit`, `--offset`). The response carries `total`
|
|
118
|
+
and `hasMore`; page until `hasMore` is false before treating a listing as
|
|
119
|
+
complete.
|
|
120
|
+
- `fimo entries bulk-create` chunks at 100 entries by default. Migration data
|
|
121
|
+
workers use `--upsert-by slug`; the identity includes locale, the command
|
|
122
|
+
rereads after an ambiguous 504 before retrying absent entries, and its
|
|
123
|
+
receipt aggregates per-chunk created/updated/conflict counts. Use
|
|
124
|
+
`--chunk-size` only when the transport supports a different bounded size
|
|
125
|
+
(maximum 1,000). `bulk-update` and `bulk-delete` remain capped at 1,000.
|
|
126
|
+
- `fimo labels set-many` sends its whole `--file`/`--data` payload in one
|
|
127
|
+
request; keep one payload per worker batch so a retry replays a bounded set.
|
|
128
|
+
|
|
129
|
+
Listing existing Fimo entries or assets serves idempotency, retry, and fan-in
|
|
130
|
+
reconciliation only - confirming what a rerun must update instead of create.
|
|
131
|
+
The source of the content is always the source tree or export, never a listing
|
|
132
|
+
of what already exists in Fimo.
|
|
133
|
+
|
|
88
134
|
## Minimum Import Loop
|
|
89
135
|
|
|
90
136
|
For each migration, agents should run this loop:
|
|
91
137
|
|
|
92
|
-
1.
|
|
93
|
-
2.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
138
|
+
1. Read the text migration plan and the initialized target.
|
|
139
|
+
2. Have the owning workers define complete schemas/forms and write them through
|
|
140
|
+
the normal Fimo contracts.
|
|
141
|
+
3. Validate and push schemas before dependent content writes.
|
|
142
|
+
4. Upload media.
|
|
143
|
+
5. Import entries, then resolve proven references against stable target IDs.
|
|
144
|
+
6. Update singles and apply labels.
|
|
145
|
+
7. Handle form definitions through their separate supported contract; do not
|
|
146
|
+
import historical submissions.
|
|
147
|
+
8. Write target IDs, counts, failures, and unresolved items into worker and
|
|
148
|
+
migration reports.
|
|
149
|
+
|
|
150
|
+
The data-plane dependency order remains `schemas`, `media`,
|
|
151
|
+
`entries/references`, `singles`, and `labels`. It is a simple execution order,
|
|
152
|
+
not a reason to add another orchestrator.
|
|
101
153
|
|
|
102
154
|
If any step cannot be completed, write an unresolved item immediately with the
|
|
103
155
|
source evidence and owner action needed.
|
|
@@ -1,164 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Legacy migration manifest
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
New migrations do not create a canonical `manifest.json`. The coordinator uses
|
|
4
|
+
the readable `.fimo/migration/migration-plan.md` and
|
|
5
|
+
`.fimo/migration/migration-report.md` instead.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Older URL-only migrations may contain `.fimo/migrations/current/manifest.json`.
|
|
8
|
+
Read it as source evidence when useful, but do not copy it into another
|
|
9
|
+
registry or ask workers to keep it synchronized.
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"mode": "url-only|source-backed|hybrid",
|
|
13
|
-
"platform": "webflow|framer|squarespace|wix|wordpress|carrd|custom|unknown",
|
|
14
|
-
"publicUrl": "https://example.com",
|
|
15
|
-
"rootPath": "../source",
|
|
16
|
-
"inventoryPath": ".fimo/migration/inventory.json",
|
|
17
|
-
"sourceLedgers": []
|
|
18
|
-
},
|
|
19
|
-
"artifacts": {
|
|
20
|
-
"code": [],
|
|
21
|
-
"cms": [],
|
|
22
|
-
"media": [],
|
|
23
|
-
"forms": [],
|
|
24
|
-
"screenshots": [],
|
|
25
|
-
"other": []
|
|
26
|
-
},
|
|
27
|
-
"routes": [],
|
|
28
|
-
"contentTypes": [],
|
|
29
|
-
"entries": [],
|
|
30
|
-
"media": [],
|
|
31
|
-
"forms": [],
|
|
32
|
-
"redirects": [],
|
|
33
|
-
"locales": [],
|
|
34
|
-
"seo": [],
|
|
35
|
-
"unsupported": [],
|
|
36
|
-
"unresolved": [],
|
|
37
|
-
"qa": {
|
|
38
|
-
"status": "not-run|passed|failed|passed-with-unresolved",
|
|
39
|
-
"checks": []
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Required Item Fields
|
|
45
|
-
|
|
46
|
-
Every route, content type, entry batch, media asset, form, redirect, locale, SEO
|
|
47
|
-
item, unsupported item, and unresolved item should include:
|
|
48
|
-
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"id": "stable-human-readable-id",
|
|
52
|
-
"status": "discovered|planned|generated|imported|verified|ignored|unsupported|unresolved",
|
|
53
|
-
"sourceFiles": [],
|
|
54
|
-
"sourceUrls": [],
|
|
55
|
-
"targetFiles": [],
|
|
56
|
-
"confidence": 1,
|
|
57
|
-
"notes": []
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Use honest confidence. Inferred content from crawled pages is lower confidence
|
|
62
|
-
than first-party CSV/XML/JSON exports.
|
|
63
|
-
|
|
64
|
-
## Content Type Item
|
|
65
|
-
|
|
66
|
-
```json
|
|
67
|
-
{
|
|
68
|
-
"id": "blog-post",
|
|
69
|
-
"uid": "BlogPost",
|
|
70
|
-
"name": "Blog Posts",
|
|
71
|
-
"status": "planned",
|
|
72
|
-
"sourceFiles": ["exports/blog.csv"],
|
|
73
|
-
"targetFiles": ["src/schemas/BlogPost.json"],
|
|
74
|
-
"sourceCount": 42,
|
|
75
|
-
"plannedCount": 42,
|
|
76
|
-
"importedCount": 0,
|
|
77
|
-
"fields": {
|
|
78
|
-
"title": { "type": "string", "source": "Name" },
|
|
79
|
-
"body": { "type": "richtext", "source": "Post Body" },
|
|
80
|
-
"coverImage": { "type": "media", "source": "Main Image" },
|
|
81
|
-
"publishedAt": { "type": "datetime", "source": "Published On" }
|
|
82
|
-
},
|
|
83
|
-
"references": []
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
> **Do not put reserved names in `fields`.** `id`, `documentId`, `slug`, `locale`,
|
|
88
|
-
> `createdAt`, `updatedAt`, and `__fimo` are built-in entry metadata — declaring them as
|
|
89
|
-
> schema fields makes `fimo schemas push` fail with a 400. Map a source "Slug" column onto
|
|
90
|
-
> the entry's built-in `slug` (inside `data`) at import time, not onto a schema field.
|
|
91
|
-
|
|
92
|
-
## Entry Batch Item
|
|
93
|
-
|
|
94
|
-
```json
|
|
95
|
-
{
|
|
96
|
-
"id": "blog-post-entries",
|
|
97
|
-
"contentType": "BlogPost",
|
|
98
|
-
"status": "generated",
|
|
99
|
-
"sourceFiles": ["exports/blog.csv"],
|
|
100
|
-
"targetFiles": [".fimo/migration/entries/BlogPost.json"],
|
|
101
|
-
"sourceCount": 42,
|
|
102
|
-
"generatedCount": 42,
|
|
103
|
-
"importedCount": 0,
|
|
104
|
-
"skipped": []
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Media Item
|
|
109
|
-
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"id": "media-hero-jpg",
|
|
113
|
-
"status": "imported",
|
|
114
|
-
"sourceUrl": "https://example.com/hero.jpg",
|
|
115
|
-
"sourcePath": "assets/hero.jpg",
|
|
116
|
-
"targetAssetId": "asset_123",
|
|
117
|
-
"targetUrl": "https://...",
|
|
118
|
-
"sha256": "optional",
|
|
119
|
-
"contentType": "image/jpeg",
|
|
120
|
-
"bytes": 123456,
|
|
121
|
-
"width": 1600,
|
|
122
|
-
"height": 900,
|
|
123
|
-
"alt": "Hero image",
|
|
124
|
-
"referencedBy": ["route:/", "entry:BlogPost/welcome"],
|
|
125
|
-
"uploadError": null
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Form Item
|
|
130
|
-
|
|
131
|
-
```json
|
|
132
|
-
{
|
|
133
|
-
"id": "contact",
|
|
134
|
-
"name": "contact",
|
|
135
|
-
"status": "generated",
|
|
136
|
-
"classification": "fimo-native|third-party|unsupported",
|
|
137
|
-
"sourceFiles": ["contact.html"],
|
|
138
|
-
"targetFiles": ["src/forms/contact.json"],
|
|
139
|
-
"action": "https://formspree.io/...",
|
|
140
|
-
"method": "post",
|
|
141
|
-
"fields": [],
|
|
142
|
-
"unsupportedReason": null
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Unresolved Item
|
|
147
|
-
|
|
148
|
-
```json
|
|
149
|
-
{
|
|
150
|
-
"id": "mailchimp-newsletter-action",
|
|
151
|
-
"area": "forms",
|
|
152
|
-
"severity": "medium",
|
|
153
|
-
"status": "unresolved",
|
|
154
|
-
"message": "Newsletter form posts to Mailchimp and requires integration credentials.",
|
|
155
|
-
"suggestedAction": "Create a Fimo form or configure a Mailchimp integration with the owner."
|
|
156
|
-
}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
## Rules
|
|
160
|
-
|
|
161
|
-
- Prefer stable source IDs over generated IDs.
|
|
162
|
-
- Preserve original field names in `source`; use clean Fimo field IDs in schemas.
|
|
163
|
-
- Never delete unresolved items just to make the report cleaner.
|
|
164
|
-
- Update item statuses as work progresses.
|
|
11
|
+
JSON remains appropriate for actual Fimo artifacts: schema files and the
|
|
12
|
+
content payloads passed to data-plane commands. It is not needed to describe
|
|
13
|
+
worker ownership, target paths, decisions, timings, or QA status. Put those in
|
|
14
|
+
plain-text plans, worker reports, and the final migration report.
|