fimo 0.9.0-experimental.1 → 0.9.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 (205) hide show
  1. package/assets/skills/fimo/SKILL.md +17 -54
  2. package/assets/skills/fimo-cli/SKILL.md +15 -15
  3. package/assets/skills/fimo-cli/references/agent-setup.md +36 -53
  4. package/assets/skills/fimo-cli/references/agents.md +4 -4
  5. package/assets/skills/fimo-cli/references/content.md +2 -2
  6. package/assets/skills/fimo-cli/references/deploy.md +1 -1
  7. package/assets/skills/fimo-cli/references/forms.md +1 -1
  8. package/assets/skills/fimo-cli/references/init.md +16 -24
  9. package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +14 -11
  10. package/assets/skills/fimo-cli/references/projects.md +1 -1
  11. package/assets/skills/fimo-cli/references/support.md +11 -9
  12. package/assets/skills/fimo-cli/references/webhooks.md +3 -1
  13. package/assets/skills/fimo-code/SKILL.md +67 -0
  14. package/assets/skills/fimo-migration/SKILL.md +2 -22
  15. package/assets/skills/fimo-migration/references/content.md +0 -24
  16. package/assets/skills/fimo-migration/references/manifest.md +0 -35
  17. package/assets/skills/fimo-migration/references/qa.md +2 -24
  18. package/assets/skills/fimo-migration/references/workflow.md +1 -12
  19. package/assets/skills/fimo-studio/references/visual-editing.md +3 -5
  20. package/assets/skills/fimo-studio/references/webhooks.md +1 -1
  21. package/dist/build/vite/plugins/translations.d.ts +8 -2
  22. package/dist/build/vite/plugins/translations.js +121 -3
  23. package/dist/cli/bundle.json +2 -2
  24. package/dist/cli/index.js +311 -1209
  25. package/dist/runtime/app/FimoProviders.d.ts +11 -1
  26. package/dist/runtime/app/FimoProviders.js +23 -2
  27. package/dist/runtime/content/client/createContentClient.js +2 -1
  28. package/dist/runtime/i18n/FimoLocaleContext.js +0 -1
  29. package/dist/runtime/primitives/lib/useFimoLiveValue.d.ts +3 -5
  30. package/dist/runtime/primitives/lib/useFimoLiveValue.js +4 -11
  31. package/dist/runtime/primitives/translations.d.ts +27 -1
  32. package/dist/runtime/primitives/translations.js +85 -7
  33. package/dist/runtime/shared/fimo-config.server.js +0 -1
  34. package/dist/runtime/shared/fimo-config.types.d.ts +0 -2
  35. package/dist/scripts/extract-translations.js +11 -16
  36. package/dist/scripts/lib/validation-report.d.ts +0 -1
  37. package/dist/scripts/lib/validation-report.js +0 -3
  38. package/dist/scripts/validate-route-metadata.js +0 -11
  39. package/package.json +4 -84
  40. package/release.json +2 -2
  41. package/scripts/postinstall.mjs +11 -65
  42. package/templates/react-router/AGENTS.md +44 -0
  43. package/templates/react-router/CLAUDE.md +5 -0
  44. package/templates/react-router/package.json +1 -1
  45. package/assets/agents-starter/AGENTS.md +0 -66
  46. package/assets/skills/fimo-migration/references/wrap.md +0 -617
  47. package/dist/runtime/astro/index.d.ts +0 -2
  48. package/dist/runtime/astro/index.js +0 -3
  49. package/dist/runtime/astro/server.d.ts +0 -3
  50. package/dist/runtime/astro/server.js +0 -6
  51. package/dist/runtime/next/FimoNextProviders.d.ts +0 -24
  52. package/dist/runtime/next/FimoNextProviders.js +0 -20
  53. package/dist/runtime/next/FimoNextScripts.d.ts +0 -10
  54. package/dist/runtime/next/FimoNextScripts.js +0 -19
  55. package/dist/runtime/next/index.d.ts +0 -14
  56. package/dist/runtime/next/index.js +0 -14
  57. package/dist/runtime/next/server.d.ts +0 -2
  58. package/dist/runtime/next/server.js +0 -4
  59. package/dist/runtime/nuxt/composables.d.ts +0 -9
  60. package/dist/runtime/nuxt/composables.js +0 -57
  61. package/dist/runtime/nuxt/index.d.ts +0 -3
  62. package/dist/runtime/nuxt/index.js +0 -6
  63. package/dist/runtime/nuxt/server.d.ts +0 -3
  64. package/dist/runtime/nuxt/server.js +0 -6
  65. package/dist/runtime/primitives/labels-hook.d.ts +0 -33
  66. package/dist/runtime/primitives/labels-hook.js +0 -41
  67. package/dist/runtime/primitives/labels-store.d.ts +0 -12
  68. package/dist/runtime/primitives/labels-store.js +0 -60
  69. package/dist/runtime/react/FimoSpaProviders.d.ts +0 -36
  70. package/dist/runtime/react/FimoSpaProviders.js +0 -63
  71. package/dist/runtime/react/index.d.ts +0 -33
  72. package/dist/runtime/react/index.js +0 -39
  73. package/dist/runtime/remix/FimoRemixProviders.d.ts +0 -16
  74. package/dist/runtime/remix/FimoRemixProviders.js +0 -12
  75. package/dist/runtime/remix/FimoRemixScripts.d.ts +0 -10
  76. package/dist/runtime/remix/FimoRemixScripts.js +0 -19
  77. package/dist/runtime/remix/index.d.ts +0 -12
  78. package/dist/runtime/remix/index.js +0 -11
  79. package/dist/runtime/remix/server.d.ts +0 -2
  80. package/dist/runtime/remix/server.js +0 -2
  81. package/dist/runtime/shared/display-routes.d.ts +0 -14
  82. package/dist/runtime/shared/display-routes.js +0 -25
  83. package/dist/runtime/shared/i18n-messages.d.ts +0 -29
  84. package/dist/runtime/shared/i18n-messages.js +0 -79
  85. package/dist/runtime/shared/labels-fetch.pure.d.ts +0 -17
  86. package/dist/runtime/shared/labels-fetch.pure.js +0 -71
  87. package/dist/runtime/shared/labels-fetch.server.d.ts +0 -7
  88. package/dist/runtime/shared/labels-fetch.server.js +0 -97
  89. package/dist/runtime/shared/labels-t.pure.d.ts +0 -2
  90. package/dist/runtime/shared/labels-t.pure.js +0 -10
  91. package/dist/runtime/strapi/client.d.ts +0 -30
  92. package/dist/runtime/strapi/client.js +0 -89
  93. package/dist/runtime/strapi/index.d.ts +0 -5
  94. package/dist/runtime/strapi/index.js +0 -6
  95. package/dist/runtime/strapi/reshape.d.ts +0 -46
  96. package/dist/runtime/strapi/reshape.js +0 -114
  97. package/dist/runtime/svelte/index.d.ts +0 -3
  98. package/dist/runtime/svelte/index.js +0 -7
  99. package/dist/runtime/svelte/server.d.ts +0 -3
  100. package/dist/runtime/svelte/server.js +0 -6
  101. package/dist/runtime/vue/index.d.ts +0 -3
  102. package/dist/runtime/vue/index.js +0 -5
  103. package/dist/runtime/vue/server.d.ts +0 -3
  104. package/dist/runtime/vue/server.js +0 -6
  105. package/dist/runtime/wrapped/FimoFileLink.d.ts +0 -17
  106. package/dist/runtime/wrapped/FimoFileLink.js +0 -19
  107. package/dist/runtime/wrapped/FimoMediaImage.d.ts +0 -14
  108. package/dist/runtime/wrapped/FimoMediaImage.js +0 -20
  109. package/dist/runtime/wrapped/FimoMediaVideo.d.ts +0 -14
  110. package/dist/runtime/wrapped/FimoMediaVideo.js +0 -20
  111. package/dist/runtime/wrapped/FimoRichTextBlock.d.ts +0 -23
  112. package/dist/runtime/wrapped/FimoRichTextBlock.js +0 -22
  113. package/dist/runtime/wrapped/FimoText.d.ts +0 -22
  114. package/dist/runtime/wrapped/FimoText.js +0 -20
  115. package/dist/runtime/wrapped/WrappedContentContext.d.ts +0 -28
  116. package/dist/runtime/wrapped/WrappedContentContext.js +0 -30
  117. package/dist/runtime/wrapped/WrappedProviders.d.ts +0 -33
  118. package/dist/runtime/wrapped/WrappedProviders.js +0 -101
  119. package/dist/runtime/wrapped/dom.d.ts +0 -4
  120. package/dist/runtime/wrapped/dom.js +0 -23
  121. package/dist/runtime/wrapped/server.d.ts +0 -77
  122. package/dist/runtime/wrapped/server.js +0 -237
  123. package/dist/scripts/apply-wrap-templates.d.ts +0 -61
  124. package/dist/scripts/apply-wrap-templates.js +0 -132
  125. package/dist/scripts/apply-wrap.d.ts +0 -46
  126. package/dist/scripts/apply-wrap.js +0 -278
  127. package/dist/scripts/cms/discover.d.ts +0 -2
  128. package/dist/scripts/cms/discover.js +0 -17
  129. package/dist/scripts/cms/example-content.d.ts +0 -33
  130. package/dist/scripts/cms/example-content.js +0 -162
  131. package/dist/scripts/cms/strapi/detect.d.ts +0 -2
  132. package/dist/scripts/cms/strapi/detect.js +0 -186
  133. package/dist/scripts/cms/strapi/index.d.ts +0 -3
  134. package/dist/scripts/cms/strapi/index.js +0 -25
  135. package/dist/scripts/cms/strapi/list-source.d.ts +0 -17
  136. package/dist/scripts/cms/strapi/list-source.js +0 -90
  137. package/dist/scripts/cms/strapi/schema-map.d.ts +0 -9
  138. package/dist/scripts/cms/strapi/schema-map.js +0 -277
  139. package/dist/scripts/cms/strapi/shapes.d.ts +0 -23
  140. package/dist/scripts/cms/strapi/shapes.js +0 -38
  141. package/dist/scripts/cms/strapi/touchpoints.d.ts +0 -31
  142. package/dist/scripts/cms/strapi/touchpoints.js +0 -145
  143. package/dist/scripts/cms/strapi/wire-client.d.ts +0 -15
  144. package/dist/scripts/cms/strapi/wire-client.js +0 -107
  145. package/dist/scripts/cms/strapi/wiring.d.ts +0 -17
  146. package/dist/scripts/cms/strapi/wiring.js +0 -46
  147. package/dist/scripts/cms/types.d.ts +0 -145
  148. package/dist/scripts/cms/types.js +0 -11
  149. package/dist/scripts/detect-framework.d.ts +0 -39
  150. package/dist/scripts/detect-framework.js +0 -133
  151. package/dist/scripts/draft-rows.d.ts +0 -19
  152. package/dist/scripts/draft-rows.js +0 -135
  153. package/dist/scripts/draft-schemas.d.ts +0 -27
  154. package/dist/scripts/draft-schemas.js +0 -188
  155. package/dist/scripts/frameworks/astro/routes.d.ts +0 -3
  156. package/dist/scripts/frameworks/astro/routes.js +0 -55
  157. package/dist/scripts/frameworks/astro/template-style.d.ts +0 -7
  158. package/dist/scripts/frameworks/astro/template-style.js +0 -19
  159. package/dist/scripts/frameworks/discover.d.ts +0 -70
  160. package/dist/scripts/frameworks/discover.js +0 -178
  161. package/dist/scripts/frameworks/next/rewire.d.ts +0 -30
  162. package/dist/scripts/frameworks/next/rewire.js +0 -258
  163. package/dist/scripts/frameworks/next/routes.d.ts +0 -17
  164. package/dist/scripts/frameworks/next/routes.js +0 -134
  165. package/dist/scripts/frameworks/next/wiring.d.ts +0 -33
  166. package/dist/scripts/frameworks/next/wiring.js +0 -186
  167. package/dist/scripts/frameworks/nuxt/routes.d.ts +0 -3
  168. package/dist/scripts/frameworks/nuxt/routes.js +0 -54
  169. package/dist/scripts/frameworks/nuxt/template-style.d.ts +0 -9
  170. package/dist/scripts/frameworks/nuxt/template-style.js +0 -27
  171. package/dist/scripts/frameworks/remix/routes.d.ts +0 -3
  172. package/dist/scripts/frameworks/remix/routes.js +0 -50
  173. package/dist/scripts/frameworks/support.d.ts +0 -75
  174. package/dist/scripts/frameworks/support.js +0 -165
  175. package/dist/scripts/frameworks/sveltekit/routes.d.ts +0 -3
  176. package/dist/scripts/frameworks/sveltekit/routes.js +0 -50
  177. package/dist/scripts/frameworks/sveltekit/template-style.d.ts +0 -9
  178. package/dist/scripts/frameworks/sveltekit/template-style.js +0 -54
  179. package/dist/scripts/frameworks/vite/routes.d.ts +0 -15
  180. package/dist/scripts/frameworks/vite/routes.js +0 -93
  181. package/dist/scripts/frameworks/vite/wiring.d.ts +0 -10
  182. package/dist/scripts/frameworks/vite/wiring.js +0 -99
  183. package/dist/scripts/i18n-namespace.d.ts +0 -27
  184. package/dist/scripts/i18n-namespace.js +0 -155
  185. package/dist/scripts/render-parity/capture.d.ts +0 -56
  186. package/dist/scripts/render-parity/capture.js +0 -366
  187. package/dist/scripts/render-parity/compare.d.ts +0 -59
  188. package/dist/scripts/render-parity/compare.js +0 -0
  189. package/dist/scripts/render-parity/normalize-html.d.ts +0 -13
  190. package/dist/scripts/render-parity/normalize-html.js +0 -223
  191. package/dist/scripts/render-parity/types.d.ts +0 -41
  192. package/dist/scripts/render-parity/types.js +0 -1
  193. package/dist/scripts/scan-wrappable.d.ts +0 -196
  194. package/dist/scripts/scan-wrappable.js +0 -1232
  195. /package/assets/skills/{fimo → fimo-code}/assets/react-router-locales/navigation.tsx +0 -0
  196. /package/assets/skills/{fimo → fimo-code}/assets/react-router-locales/routes.ts +0 -0
  197. /package/assets/skills/{fimo → fimo-code}/references/assets.md +0 -0
  198. /package/assets/skills/{fimo → fimo-code}/references/content.md +0 -0
  199. /package/assets/skills/{fimo → fimo-code}/references/design.md +0 -0
  200. /package/assets/skills/{fimo → fimo-code}/references/forms.md +0 -0
  201. /package/assets/skills/{fimo → fimo-code}/references/labels.md +0 -0
  202. /package/assets/skills/{fimo → fimo-code}/references/locales.md +0 -0
  203. /package/assets/skills/{fimo → fimo-code}/references/setup-plain-vite.md +0 -0
  204. /package/assets/skills/{fimo → fimo-code}/references/setup-react-router.md +0 -0
  205. /package/assets/skills/{fimo → fimo-code}/references/ui.md +0 -0
@@ -29,7 +29,7 @@ fimo projects rename <name> [projectId] [-C <dir>] # local-only: set seo.siteN
29
29
  fimo clone [projectId] [dir] [--env <name>] # same as `fimo projects clone`
30
30
  ```
31
31
 
32
- Use the top-level shortcut for the common "get this project onto my machine" workflow. After clone succeeds, `cd` into the printed directory and load the newly written project context (`AGENTS.md` plus the installed project skill) before generating code.
32
+ Use the top-level shortcut for the common "get this project onto my machine" workflow. After clone succeeds, `cd` into the printed directory, `Read` the project's `AGENTS.md`, and load the code skill with `npx fimo@latest skills get fimo-code` before generating code.
33
33
 
34
34
  ## Top-level shortcuts (current project)
35
35
 
@@ -4,20 +4,22 @@
4
4
 
5
5
  `fimo support report` sends a project-scoped problem to Fimo support. It automatically includes the project, current environment, and CLI version so support can start investigating without asking the user to repeat that context.
6
6
 
7
- ## When to offer it
7
+ ## When to prepare it
8
8
 
9
- Offer to report when:
9
+ Prepare a report proactively when:
10
10
 
11
11
  - A Fimo command, API, preview, deploy, sandbox, or platform operation repeatedly fails or returns an unexpected response.
12
12
  - A documented or previously working API or CLI argument is rejected, ignored, or behaves differently from its contract.
13
13
  - A supported operation only works through an undocumented workaround or an unnecessarily complex sequence.
14
14
  - A Fimo API repeatedly times out or is abnormally slow enough to disrupt the workflow.
15
- - A missing Fimo capability blocks completion, forces a fragile or heavily manual workaround, or would materially accelerate recurring work. Bulk creation replacing many single-item calls is a good example.
15
+ - A confirmed missing Fimo capability blocks completion or forces a fragile or heavily manual workaround.
16
16
  - The remaining problem or capability gap appears to be in Fimo rather than the user's application code.
17
17
 
18
18
  For failures, read the error and try one safe, relevant recovery step before reporting. Feature requests do not need a failed recovery attempt; confirm that the capability is actually absent.
19
19
 
20
- Do not report ordinary application bugs, small conveniences, vague wishlist items, one-off latency, or failures you have not inspected. A clearly documented unsupported capability is still worth reporting when its absence crosses the blocking or material-acceleration threshold above; describe it as a feature request rather than a bug.
20
+ Do not interrupt the user's main work to prepare a report. Complete it, use a safe workaround, or preserve progress first. Then use the built-in `supportReport` tool without waiting for the user to request it. Do not stop after merely describing the Fimo problem or gap.
21
+
22
+ Do not report ordinary application bugs, small conveniences, vague wishlist items, one-off latency, speculative gaps, or failures you have not inspected. A clearly documented unsupported capability is still worth reporting when its absence crosses the blocking threshold above; describe it as a feature request rather than a bug.
21
23
 
22
24
  ## What to write
23
25
 
@@ -33,22 +35,22 @@ Keep the report factual and short:
33
35
 
34
36
  Do not include secrets, environment values, raw shell history, hidden reasoning, full source files, or unrelated conversation history.
35
37
 
36
- ## Required approval
38
+ ## Sending
39
+
40
+ Agents should use the built-in `supportReport` tool after the main work is complete or safely preserved. The tool submits through this CLI command and records the normal tool activity in chat.
37
41
 
38
- Prepare the report, then preview the complete payload without sending it:
42
+ To inspect the exact CLI payload manually without sending it:
39
43
 
40
44
  ```bash
41
45
  fimo support report --message-file /tmp/fimo-support-report.md --preview --json
42
46
  ```
43
47
 
44
- Show the user the exact `data.message` from that output. Submit only after the user explicitly approves it:
48
+ To send non-interactively:
45
49
 
46
50
  ```bash
47
51
  fimo support report --message-file /tmp/fimo-support-report.md --yes --json
48
52
  ```
49
53
 
50
- `--yes` means the report has already been reviewed and approved. Never pass it preemptively or report automatically.
51
-
52
54
  For a person using an interactive terminal:
53
55
 
54
56
  ```bash
@@ -47,7 +47,7 @@ Omit `--body` to send this full envelope. Prefer that default when the receiver
47
47
  Store credentials as project secrets, never literal header flags:
48
48
 
49
49
  ```bash
50
- printf '%s' "$RESEND_API_KEY" | fimo secrets set RESEND_API_KEY --stdin
50
+ printf '%s' "$RESEND_API_KEY" | fimo secrets add RESEND_API_KEY --stdin
51
51
 
52
52
  fimo webhooks create waitlist-resend \
53
53
  --event form.submitted \
@@ -57,6 +57,8 @@ fimo webhooks create waitlist-resend \
57
57
  --body '{"email":"{{ event.data.submission.data.email }}"}'
58
58
  ```
59
59
 
60
+ `fimo secrets add` refuses to replace an existing value. Use `fimo secrets update` for an intentional rotation.
61
+
60
62
  Header sources:
61
63
 
62
64
  - `Name=secret:KEY`: secret is the complete value
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: fimo-code
3
+ description: >-
4
+ How to write code in a Fimo project — the npm package surface. Load when
5
+ writing JSX that renders schema content, defining schemas or forms (JSON),
6
+ using `t()` for labels, plugging media into `fimo/ui` components,
7
+ or applying the project's code conventions. CLI commands and workflows
8
+ (push, deploy, sync, etc.) live in the `fimo-cli` skill.
9
+ ---
10
+
11
+ # Fimo
12
+
13
+ You are writing code in a Fimo project — a content + media + forms + analytics platform for React websites with a CMS dashboard. This skill describes the **`fimo` npm package surface** as installed in this specific project: what's exported from `fimo`, `fimo/ui`, `fimo/vite`; the JSON shapes you write; the generated React Query hooks and Zod schemas you import; and the code conventions for using them.
14
+
15
+ This skill is version-locked to this project's installed `fimo` package — the shapes here match what your code can actually use.
16
+
17
+ For CLI commands and workflows (creating a project, pushing schemas/forms, deploying, managing labels, etc.), the **`fimo-cli`** skill is the source of truth. Run every CLI command as `npx fimo@latest <command>` (always the latest, no global install). Load it on demand with `npx fimo@latest skills get fimo-cli`.
18
+
19
+ ## Critical: NEVER hardcode user-facing things
20
+
21
+ This is the load-bearing rule for every code change. **Fimo's whole point is that content editors edit content in the dashboard, not in code.** Anything hardcoded breaks that.
22
+
23
+ - **Content** (posts, products, pages, lists, anything structured) → declare a schema, render collections with generated `useList()` or `useInfiniteList()` hooks + `fimo/ui` components. Use `useGet()` only for legacy fixed array queries. **Never** write `const posts = [...]` in JSX.
24
+ - **Strings** (labels, CTAs, headings, descriptions, any visible text) → wrap in `t('key')` and create the default-locale value with `fimo labels set`. Use `--locale <locale>` only when intentionally writing a non-default locale. **Never** write `<h1>Welcome</h1>` directly — write `<Text value={t('home.title')} as="h1" />`.
25
+ - **Media** (images, videos, files) → use `<Image>` / `<Video>` from `fimo/ui` for schema media, `<StaticImage>` for hard-coded URLs. **Never** use `<img src={...}>`.
26
+ - **Forms** → use the generated Zod schema + `submitX` helper from `@/forms/<name>`. Never hand-roll fetch or validation.
27
+
28
+ If you find yourself about to hardcode anything user-facing, **stop and use the appropriate Fimo primitive instead.** For pushing the schema/form/asset to the backend, that's CLI territory — see the `fimo-cli` skill.
29
+
30
+ ## When starting code work, load these references up front
31
+
32
+ These define the package surface for the load-bearing primitives. **Read all six before generating significant code:**
33
+
34
+ - `references/content.md` — schema JSON shape, field types, Tiptap nodes, generated React Query hooks
35
+ - `references/forms.md` — form JSON spec, generated Zod + `submitX` helper
36
+ - `references/assets.md` — `FimoMedia` shape, how to render assets
37
+ - `references/labels.md` — `t()` helper, `useLabels()`, wrap rules
38
+ - `references/locales.md` — locale routing helpers, `FimoLink`, custom-framework contract
39
+ - `references/ui.md` — `fimo/ui` components + JSX code conventions + app code rules
40
+
41
+ Workflow / CLI-side concerns (pushing schemas, generating images, managing labels, deploying) live in the **`fimo-cli`** skill's matching references.
42
+
43
+ ## Decision Tree (specific tasks)
44
+
45
+ - **Setting up Fimo in a new project** — pick the framework:
46
+ - React Router framework mode (new projects use React Router 8) → `references/setup-react-router.md`
47
+ - Plain Vite + React (or upgrading a legacy v3 project) → `references/setup-plain-vite.md`
48
+ - Writing schema JSON / picking field types / Tiptap richtext → `references/content.md`
49
+ - Writing form JSON / generated form client / form code → `references/forms.md`
50
+ - Plugging media into a component / `FimoMedia` shape → `references/assets.md`
51
+ - ANY user-facing string in code → `references/labels.md`
52
+ - Locale-aware routes, links, or framework adapters → `references/locales.md`
53
+ - ANY JSX rendering schema content or `t()` output → `references/ui.md`
54
+ - Major visual / redesign / hero section / brand → `references/design.md`
55
+
56
+ ## Anti-Patterns
57
+
58
+ - **Hardcoding content in JSX** — `<h1>My Blog</h1>` + an array of posts in code. Use schemas + entries + `t()`.
59
+ - **Raw HTML for schema content** — `<img src={post.coverImage.url}>` instead of `<Image value={post.coverImage}>`. The `fimo/ui` components carry metadata for inline editing in the admin.
60
+ - **Raw `<a href>` for internal navigation** — causes full page reloads. Use `<FimoLink>` for locale-aware internal links or React Router `<Link>` when intentionally bypassing locale helpers. Reserve `<a>` for external links.
61
+ - **Pulling stock photos from external URLs** — editors can't manage them. Use a Fimo media task such as `fimo image generate`.
62
+ - **Editing generated `.ts` files** under `src/schemas/` or `src/forms/` — regenerate them through `fimo validate` or the matching push command.
63
+ - **Writing raw HTML in `richtext` fields** — must be Tiptap JSONContent.
64
+ - **Calling `t()` with a dynamic first argument** — the key must be a string literal so the extractor finds it.
65
+ - **Decorating the disposable starter** — `src/pages/Index.tsx` is throwaway scaffolding. On first real generation, replace it entirely.
66
+ - **Skipping legal pages** — `Privacy.tsx` + `Terms.tsx` are required for public sites; the template ships them.
67
+ - **Showing Fimo branding** in the generated site unless the user explicitly asks for it.
@@ -17,10 +17,7 @@ exports, source repositories, CMS exports, media folders, or any hybrid of those
17
17
  It owns intake, source inventory, URL crawl bootstrapping, ledger normalization,
18
18
  imports, and QA so any LLM can run the work without silently dropping content.
19
19
 
20
- > Run every `fimo` command as `npx fimo <command>` when the project declares a
21
- > `fimo` dependency (adopted/wrapped projects pin an exact version tied to their
22
- > backend — never override it with `@latest`). Only fall back to
23
- > `npx fimo@latest` when the project has no `fimo` dependency.
20
+ > Run every `fimo` command as `npx fimo@latest <command>` — always the latest CLI, no global install.
24
21
 
25
22
  ## Non-Negotiables
26
23
 
@@ -33,13 +30,6 @@ imports, and QA so any LLM can run the work without silently dropping content.
33
30
  ledger.
34
31
  - Source exports beat inferred crawls. If CSV/XML/JSON exports, media folders, or
35
32
  source code exist, treat the public URL as visual/SEO reference only.
36
- - A working JS codebase is wrapped, not rewritten. Wrap mode
37
- (`references/wrap.md`) keeps the user's routing, styling, and components
38
- untouched; the diff is wiring + wrappers + config only. As the coding
39
- agent you own the whole wrap loop — run `npx fimo migrate` yourself and
40
- follow `references/wrap.md` § W0 (relay the recorded data-source
41
- decisions to the user, then loop `npx fimo migrate wrap --check` to
42
- exit 0).
43
33
  - Builder HTML is evidence, not the final runtime. Rebuild with Fimo conventions,
44
34
  schemas, forms, media primitives, translations, and routes.
45
35
  - Do not report completion until the QA gate passes or every failed check is
@@ -69,15 +59,7 @@ imports, and QA so any LLM can run the work without silently dropping content.
69
59
  pack.
70
60
  - **hybrid**: source files plus public URL. Use source-backed as truth and URL
71
61
  for route, SEO, visual, and behavior comparison.
72
- 4. Pick the mode:
73
- - **wrap** (default for a source-backed, working JS codebase — Next.js,
74
- Vite/React, React Router): keep the user's stack, adopt the repo with
75
- `fimo init`, and make content editable by wrapping it in place. Never
76
- rewrite routing, styling, or components. Follow `references/wrap.md`.
77
- - **rebuild**: url-only sources, builder exports/HTML dumps, non-JS
78
- backends, or codebases that do not build. Follow the standard workflow
79
- phases.
80
- 5. Create or update the canonical ledger described in
62
+ 4. Create or update the canonical ledger described in
81
63
  `references/manifest.md`.
82
64
 
83
65
  ## Workflow
@@ -114,8 +96,6 @@ node <this-skill>/scripts/write-migration-report.mjs <project-root>
114
96
  ## References
115
97
 
116
98
  - `references/workflow.md` - full decision tree and phase order.
117
- - `references/wrap.md` - wrap mode: adopt a working JS codebase and wrap its
118
- content in place (default for source-backed JS sites).
119
99
  - `references/manifest.md` - canonical migration ledger schema.
120
100
  - `references/content.md` - CMS, entries, references, and source value rules.
121
101
  - `references/media.md` - media inventory, upload, dedupe, and replacement rules.
@@ -18,14 +18,6 @@ ways:
18
18
  news teasers, and feature lists are almost always collections even when the
19
19
  source renders them inside one page.
20
20
 
21
- > **Rebuild path only.** These rules apply when Fimo re-authors the site
22
- > (URL/export migrations): the rebuilt code is disposable, so content belongs
23
- > in collections aggressively. **Wrap mode is deliberately stricter** — the
24
- > user's code stays primary, page furniture and nav stay in code with `t()`
25
- > labels, and every collection candidate is confirmed with the user first.
26
- > See `wrap.md` (W0 and the generated agent-prompt) — in wrap mode that
27
- > guidance overrides this section.
28
-
29
21
  After the source-faithful rebuild, treat **any hardcoded array of 3+ items with
30
22
  the same shape** as a collection candidate. Do not leave it hardcoded.
31
23
 
@@ -105,19 +97,3 @@ Skipped fields or entries require a manifest note with:
105
97
  - reason
106
98
  - owner impact
107
99
  - suggested action
108
-
109
- ## Scaffolded CMS — verify pages render
110
-
111
- When `fimo migrate --scaffold-cms` wires the site to Fimo, the machine does the
112
- deterministic work: it maps the CMS's components and dynamic zones to editable
113
- Fimo blocks, seeds every block with generic example content in the shape the
114
- components expect, and swaps the client's fetch for the generated Fimo adapter —
115
- so the whole site reads from Fimo with no per-view wiring.
116
-
117
- The last mile is yours and it is per-site. Open the main pages in `pnpm dev` (a
118
- list, a detail, the page-builder home) and confirm each renders. Every renderer is
119
- the site's own code, so a component may read a field the generic content did not
120
- fill, or expect a slightly different shape. Where a section renders blank or
121
- throws, fix it at that component — a defensive default, or the field it truly
122
- needs — and re-check. Record anything you cannot resolve as a caveat. Do not
123
- re-scaffold, re-wire, or hand-wrap content; the machine owns those.
@@ -34,7 +34,6 @@ follow-up agents, and import/QA checks.
34
34
  "seo": [],
35
35
  "unsupported": [],
36
36
  "unresolved": [],
37
- "wrap": null,
38
37
  "qa": {
39
38
  "status": "not-run|passed|failed|passed-with-unresolved",
40
39
  "checks": []
@@ -42,40 +41,6 @@ follow-up agents, and import/QA checks.
42
41
  }
43
42
  ```
44
43
 
45
- ## Wrap Block (wrap mode only)
46
-
47
- When the migration is a wrap (see `references/wrap.md`), set
48
- `source.mode: "source-backed"` and fill the `wrap` block; leave it `null` for
49
- rebuild migrations:
50
-
51
- ```json
52
- {
53
- "wrap": {
54
- "mode": "wrap",
55
- "framework": "next|react-router|vite",
56
- "adopted": true,
57
- "wired": true,
58
- "coverage": {
59
- "wrappable": 0,
60
- "wrapped": 25,
61
- "ignored": 0,
62
- "unresolvedItems": 0
63
- },
64
- "seeded": {
65
- "labels": 21,
66
- "wrappedMedia": 3,
67
- "wrappedRichText": 1
68
- },
69
- "planPath": ".fimo/migration/plan.json"
70
- }
71
- }
72
- ```
73
-
74
- `coverage` mirrors the final `fimo migrate wrap --check` output: `wrappable`
75
- must be 0 (or fully accounted for by `ignored` + `unresolvedItems`, each with a
76
- ledger entry). `seeded` counts must match what `fimo labels list` /
77
- `fimo entries list` report — fallback-only content is not seeded.
78
-
79
44
  ## Required Item Fields
80
45
 
81
46
  Every route, content type, entry batch, media asset, form, redirect, locale, SEO
@@ -18,11 +18,8 @@ Run this gate before reporting completion.
18
18
  ## Behavior
19
19
 
20
20
  - Dependencies are installed in the target project.
21
- - The project builds successfully **with its own toolchain** (`next build`,
22
- `vite build`, …) — wrapped sites are not Vite/React-Router projects; never
23
- assume Fimo-template tooling.
24
- - Local dev starts without loader/schema/form generation errors (Vite errors
25
- apply to rebuild-mode projects only).
21
+ - The project builds successfully.
22
+ - Local dev starts without Vite loader/schema/form generation errors.
26
23
  - Primary routes render without console/runtime errors.
27
24
  - Collection listing/detail pages work with imported data, seed data, or explicit
28
25
  empty states.
@@ -36,25 +33,6 @@ Run this gate before reporting completion.
36
33
  - Remove generated placeholder copy from visible UI.
37
34
  - Verify media aspect ratios and no broken images on primary routes.
38
35
 
39
- ## Wrap Mode (additional blocking checks)
40
-
41
- When the manifest says `mode: "wrap"`:
42
-
43
- - `fimo migrate wrap --check` exits zero — it enforces coverage (zero
44
- unwrapped items), render parity (rendered text/marks/media/links identical
45
- to the pre-wrap baseline), and seeding (every wrapped key exists in the
46
- database) — or every remaining item is an explicit ignored/unresolved
47
- ledger entry with a reason.
48
- - Labels are seeded: every `FimoText`/`t()` key exists in `fimo labels list`
49
- with the original string. Fallback-only content fails the gate.
50
- - Wrapped media/rich text have their `WrappedMedia`/`WrappedRichText` entries
51
- created and assets uploaded.
52
- - Render parity: pages render identically to pre-migration — same text, same
53
- formatting marks (bold/italic/underline/links), same media.
54
- - Diff audit: the migration diff contains only wiring, wrappers, label calls,
55
- config, and dependency changes. Any routing/styling/component rewrite fails
56
- the gate.
57
-
58
36
  ## Import Verification
59
37
 
60
38
  Record:
@@ -2,14 +2,6 @@
2
2
 
3
3
  Use this as the phase contract for complete migrations.
4
4
 
5
- > **Mode fork.** For a source-backed, WORKING JS codebase (Next.js, Vite/React,
6
- > React Router), wrap mode is the default: skip Phases 0 and 6 below and follow
7
- > `references/wrap.md` (adopt via `fimo init`, scan via `fimo migrate wrap`,
8
- > wrap in place, seed, verify). Phases 3–5 (content model, media/forms, import)
9
- > and Phase 8 (QA + report) still apply — wrap changes how content becomes
10
- > editable, not the accounting obligations. Everything else here is the rebuild
11
- > path.
12
-
13
5
  ## Phase 0: Target Safety
14
6
 
15
7
  1. Confirm the target path.
@@ -127,10 +119,7 @@ Required order:
127
119
  Record target IDs, import counts, failures, and unresolved items in the
128
120
  canonical ledger. Generated JSON without import counts is still draft state.
129
121
 
130
- ## Phase 6: Fimo Implementation (rebuild mode)
131
-
132
- In wrap mode this phase is replaced by `references/wrap.md` phases W3–W5
133
- (wire, wrap, seed); do not rebuild pages for a wrapped site.
122
+ ## Phase 6: Fimo Implementation
134
123
 
135
124
  Implement routes, schemas, forms, entries, media, redirects, translations, and
136
125
  React pages with Fimo conventions.
@@ -12,9 +12,7 @@ For text elements, the side panel shows editable fields where you can change the
12
12
 
13
13
  ### Editing Styles
14
14
 
15
- Style controls are only available on projects created before July 2026. Newer projects edit styles through the AI chat instead (for example: "make the hero title larger and dark blue"). If the user does not see the style controls described below, their project is a newer one -- point them to the chat.
16
-
17
- On projects that have them, the side panel organizes style controls into these categories:
15
+ The side panel organizes style controls into these categories:
18
16
 
19
17
  - **Typography** -- Font family, font size, font weight, line height, letter spacing, text alignment, and bold/italic/underline/strikethrough toggles.
20
18
  - **Color** -- Text and foreground colors.
@@ -33,5 +31,5 @@ Click the **Edit mode** toggle again or close the side panel. The side editor cl
33
31
 
34
32
  ## When to Use Edit Mode vs. Chat
35
33
 
36
- - **Edit mode** is best for content changes -- updating text (including bold, italic, underline, and links), and replacing images. On older projects it also covers quick style tweaks like colors and spacing.
37
- - **Chat** is better for style and structural changes -- changing colors or spacing (on newer projects), adding new sections, restructuring a page layout, or building new functionality.
34
+ - **Edit mode** is best for quick visual tweaks -- changing a color, adjusting spacing, updating text, or trying a different font.
35
+ - **Chat** is better for bigger changes -- adding new sections, restructuring a page layout, or building new functionality.
@@ -29,7 +29,7 @@ When Studio recognizes a Resend, Slack, or GitHub URL, it offers a request setup
29
29
 
30
30
  ## Add authentication
31
31
 
32
- Under **Headers**, add a header name and choose its value type. Prefer a project secret for API keys and tokens; choose whether the destination needs the raw secret, a `Bearer ` prefix, or a `token ` prefix. Fixed values are suitable only for non-sensitive headers.
32
+ Under **Headers**, add a header name and type any non-secret prefix, such as `Bearer `. Choose **Insert secret** to select an existing project secret or create one without leaving the webhook editor. Creating a secret never replaces an existing secret with the same name; select the existing secret instead. Fixed values are suitable only for non-sensitive headers.
33
33
 
34
34
  Fimo signs requests by default. Save the signing secret shown after creation so a custom receiver can verify `X-Fimo-Signature`. Rotate it from the webhook configuration if it is exposed.
35
35
 
@@ -1,5 +1,11 @@
1
1
  import type { Plugin } from 'vite';
2
- import { loadLabelBundle } from '../../../runtime/shared/labels-fetch.server.js';
2
+ interface LabelBundle {
3
+ dictionaries: Record<string, Record<string, string>>;
4
+ defaultLocale: string;
5
+ locales: string[];
6
+ updatedAt: string | null;
7
+ }
3
8
  export default function translationsPlugin(): Plugin;
4
- export { loadLabelBundle };
9
+ export declare function loadLabelBundle(rootDir: string): Promise<LabelBundle>;
10
+ export {};
5
11
  //# sourceMappingURL=translations.d.ts.map
@@ -1,8 +1,10 @@
1
1
  import { createHash } from 'node:crypto';
2
+ import { Buffer } from 'node:buffer';
2
3
  import { readFile } from 'node:fs/promises';
3
4
  import { homedir } from 'node:os';
4
5
  import { join } from 'node:path';
5
- import { emptyLabelBundle, labelSignature, loadLabelBundle, readProjectEnv, resolveTenantApiUrl, serializeBundle, } from '../../../runtime/shared/labels-fetch.server.js';
6
+ import { getFimoDefaultLocale, getFimoLocales } from '../../../runtime/i18n/locale.js';
7
+ import { getConfigServer } from '../../../runtime/shared/fimo-config.server.js';
6
8
  const VIRTUAL_ID = 'virtual:translations';
7
9
  const RESOLVED_ID = '\0' + VIRTUAL_ID;
8
10
  export default function translationsPlugin() {
@@ -143,7 +145,7 @@ export default function translationsPlugin() {
143
145
  };
144
146
  async function connectLabelEvents(root, onLabelsChanged) {
145
147
  const env = await readProjectEnv(root);
146
- const apiUrl = resolveTenantApiUrl(env);
148
+ const apiUrl = env.VITE_API_URL;
147
149
  if (!apiUrl) {
148
150
  return [];
149
151
  }
@@ -227,6 +229,24 @@ function parseContentChangePayload(payload) {
227
229
  updatedAt: typeof source.updatedAt === 'string' ? source.updatedAt : undefined,
228
230
  };
229
231
  }
232
+ function serializeBundle(bundle) {
233
+ return JSON.stringify({
234
+ dictionaries: bundle.dictionaries,
235
+ defaultLocale: bundle.defaultLocale,
236
+ locales: bundle.locales,
237
+ });
238
+ }
239
+ function emptyLabelBundle(rootDir) {
240
+ const config = getConfigServer(rootDir);
241
+ const defaultLocale = getFimoDefaultLocale(config);
242
+ const locales = getFimoLocales(config);
243
+ return {
244
+ dictionaries: Object.fromEntries(locales.map((locale) => [locale, {}])),
245
+ defaultLocale,
246
+ locales,
247
+ updatedAt: null,
248
+ };
249
+ }
230
250
  function findVirtualTranslationModules(server) {
231
251
  const direct = server.moduleGraph.getModuleById(RESOLVED_ID);
232
252
  const matches = new Set(direct ? [direct] : []);
@@ -237,13 +257,73 @@ function findVirtualTranslationModules(server) {
237
257
  }
238
258
  return [...matches];
239
259
  }
260
+ function labelSignature(bundle) {
261
+ return Buffer.from(serializeBundle(bundle)).toString('base64');
262
+ }
240
263
  function labelUpdatePayload(bundle) {
241
264
  return {
242
265
  ...bundle,
243
266
  signature: labelSignature(bundle),
244
267
  };
245
268
  }
246
- export { loadLabelBundle };
269
+ export async function loadLabelBundle(rootDir) {
270
+ const config = getConfigServer(rootDir);
271
+ const defaultLocale = getFimoDefaultLocale(config);
272
+ const locales = getFimoLocales(config);
273
+ const env = await readProjectEnv(rootDir);
274
+ const apiUrl = env.VITE_API_URL;
275
+ if (!apiUrl) {
276
+ return {
277
+ dictionaries: Object.fromEntries(locales.map((locale) => [locale, {}])),
278
+ defaultLocale,
279
+ locales,
280
+ updatedAt: null,
281
+ };
282
+ }
283
+ try {
284
+ const loaded = await Promise.all(locales.map((locale) => fetchLabelDictionary(apiUrl, locale).catch(() => ({ locale, labels: {}, updatedAt: null }))));
285
+ const updatedAt = loaded
286
+ .map((entry) => entry.updatedAt)
287
+ .filter((value) => typeof value === 'string')
288
+ .sort()
289
+ .at(-1);
290
+ return {
291
+ dictionaries: Object.fromEntries(loaded.map((entry) => [entry.locale, entry.labels])),
292
+ defaultLocale,
293
+ locales,
294
+ updatedAt: updatedAt ?? null,
295
+ };
296
+ }
297
+ catch {
298
+ return {
299
+ dictionaries: Object.fromEntries(locales.map((locale) => [locale, {}])),
300
+ defaultLocale,
301
+ locales,
302
+ updatedAt: null,
303
+ };
304
+ }
305
+ }
306
+ async function fetchLabelDictionary(apiUrl, locale) {
307
+ const url = new URL('/labels', apiUrl);
308
+ url.searchParams.set('locale', locale);
309
+ const response = await fetchWithTimeout(url, 4000);
310
+ if (!response.ok) {
311
+ return { locale, labels: {}, updatedAt: null };
312
+ }
313
+ const body = (await response.json());
314
+ if (Array.isArray(body.data)) {
315
+ return {
316
+ locale,
317
+ labels: Object.fromEntries(body.data.map((row) => [row.key, row.value ?? row.defaultValue ?? ''])),
318
+ updatedAt: null,
319
+ };
320
+ }
321
+ return {
322
+ locale,
323
+ labels: body.data?.labels ?? {},
324
+ updatedAt: body.data?.updatedAt ?? null,
325
+ };
326
+ }
247
327
  async function loadRuntimeConfig(apiUrl) {
248
328
  try {
249
329
  const response = await fetchWithTimeout(new URL('/runtime-config', apiUrl), 2000);
@@ -278,6 +358,44 @@ async function fetchWithTimeout(url, timeoutMs) {
278
358
  clearTimeout(timeout);
279
359
  }
280
360
  }
361
+ async function readProjectEnv(rootDir) {
362
+ const values = {
363
+ ...(await readEnvFile(join(rootDir, '.env'))),
364
+ ...(await readEnvFile(join(rootDir, '.env.local'))),
365
+ };
366
+ for (const key of ['VITE_API_URL']) {
367
+ if (process.env[key]) {
368
+ values[key] = process.env[key];
369
+ }
370
+ }
371
+ return values;
372
+ }
373
+ async function readEnvFile(filePath) {
374
+ try {
375
+ const content = await readFile(filePath, 'utf8');
376
+ const values = {};
377
+ for (const line of content.split(/\r?\n/)) {
378
+ const trimmed = line.trim();
379
+ if (!trimmed || trimmed.startsWith('#')) {
380
+ continue;
381
+ }
382
+ const index = trimmed.indexOf('=');
383
+ if (index === -1) {
384
+ continue;
385
+ }
386
+ const key = trimmed.slice(0, index).trim();
387
+ const value = trimmed
388
+ .slice(index + 1)
389
+ .trim()
390
+ .replace(/^['"]|['"]$/g, '');
391
+ values[key] = value;
392
+ }
393
+ return values;
394
+ }
395
+ catch {
396
+ return {};
397
+ }
398
+ }
281
399
  async function readProjectSettings(rootDir) {
282
400
  try {
283
401
  const raw = await readFile(join(rootDir, '.fimo.settings.json'), 'utf8');
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-07-23T17:15:28.604Z",
5
- "cliVersion": "0.8.0",
4
+ "bundledAt": "2026-07-24T11:14:53.290Z",
5
+ "cliVersion": "0.9.0",
6
6
  "external": [
7
7
  "oxc-parser",
8
8
  "fsevents",