fimo 0.11.0-staging.4 → 0.11.0-staging.6

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 (55) hide show
  1. package/assets/agent-templates/content-translator/GOAL.md +3 -3
  2. package/assets/agent-templates/seo-audit/config.yaml +1 -1
  3. package/assets/skills/fimo/SKILL.md +1 -0
  4. package/assets/skills/fimo-cli/SKILL.md +8 -6
  5. package/assets/skills/fimo-cli/references/agents.md +71 -23
  6. package/assets/skills/fimo-cli/references/branches.md +2 -2
  7. package/assets/skills/fimo-cli/references/credits.md +1 -1
  8. package/assets/skills/fimo-cli/references/deploy.md +1 -1
  9. package/assets/skills/fimo-cli/references/describe.md +1 -1
  10. package/assets/skills/fimo-cli/references/history.md +1 -1
  11. package/assets/skills/fimo-cli/references/init.md +4 -2
  12. package/assets/skills/fimo-cli/references/integrations/firecrawl.md +12 -3
  13. package/assets/skills/fimo-cli/references/integrations.md +15 -3
  14. package/assets/skills/fimo-cli/references/invite.md +1 -1
  15. package/assets/skills/fimo-cli/references/labels.md +1 -1
  16. package/assets/skills/fimo-cli/references/locales.md +4 -4
  17. package/assets/skills/fimo-cli/references/mcp.md +85 -0
  18. package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +1 -1
  19. package/assets/skills/fimo-cli/references/projects.md +7 -7
  20. package/assets/skills/fimo-code/references/labels.md +2 -2
  21. package/assets/skills/fimo-code/references/locales.md +5 -5
  22. package/assets/skills/fimo-code/references/setup-plain-vite.md +4 -4
  23. package/assets/skills/fimo-code/references/setup-react-router.md +5 -5
  24. package/assets/skills/fimo-code/references/ui.md +1 -1
  25. package/assets/skills/fimo-migration/references/workflow.md +1 -1
  26. package/assets/skills/fimo-migration/scripts/build-canonical-manifest.mjs +32 -3
  27. package/assets/skills/fimo-studio/references/custom-domains.md +1 -1
  28. package/dist/build/vite/index.d.ts +3 -3
  29. package/dist/build/vite/plugins/fimo-config.d.ts +2 -2
  30. package/dist/build/vite/plugins/fimo-config.js +5 -5
  31. package/dist/build/vite/plugins/robots.d.ts +1 -1
  32. package/dist/build/vite/plugins/robots.js +3 -3
  33. package/dist/build/vite/plugins/server-config.js +1 -1
  34. package/dist/build/vite/plugins/sitemap.js +2 -2
  35. package/dist/build/vite/plugins/translations.js +14 -10
  36. package/dist/cli/bundle.json +1 -1
  37. package/dist/cli/index.js +142 -131
  38. package/dist/runtime/app/prefetch.d.ts +1 -1
  39. package/dist/runtime/app/prefetch.js +2 -2
  40. package/dist/runtime/paths/get-fimo-paths.d.ts +1 -1
  41. package/dist/runtime/paths/get-fimo-paths.js +2 -2
  42. package/dist/runtime/paths/types.d.ts +1 -1
  43. package/dist/runtime/project-layout.d.ts +14 -0
  44. package/dist/runtime/project-layout.js +57 -0
  45. package/dist/runtime/seo/resolver.d.ts +1 -1
  46. package/dist/runtime/seo/resolver.js +1 -1
  47. package/dist/runtime/shared/fimo-config.server.d.ts +2 -0
  48. package/dist/runtime/shared/fimo-config.server.js +17 -4
  49. package/dist/runtime/templates.d.ts +4 -4
  50. package/dist/runtime/templates.js +11 -6
  51. package/dist/scripts/validate-route-metadata.js +8 -6
  52. package/package.json +7 -1
  53. package/templates/react-router/AGENTS.md +1 -1
  54. package/templates/react-router/package.json +1 -1
  55. /package/templates/react-router/{fimo-config.json → .fimo/config.json} +0 -0
@@ -21,11 +21,11 @@ In development, the generated app reloads when DB label values change. In produc
21
21
 
22
22
  ## Locale behavior
23
23
 
24
- The default label locale is `i18n.defaultLocale` in `fimo-config.json`, falling back to `en` when it is not set. `fimo validate`, the generated app runtime, and `fimo labels set` without `--locale` all use that default locale.
24
+ The default label locale is `i18n.defaultLocale` in `.fimo/config.json`, falling back to `en` when it is not set. `fimo validate`, the generated app runtime, and `fimo labels set` without `--locale` all use that default locale.
25
25
 
26
26
  For non-default locales, create explicit DB values with `fimo labels set --locale <locale>` or `fimo labels set-many --locale <locale>`. Keep the code shape the same for every locale: `t('hero.title')` declares the key, and the DB decides which locale value is shown.
27
27
 
28
- `fimo-config.json` owns the locale list:
28
+ `.fimo/config.json` owns the locale list:
29
29
 
30
30
  ```json
31
31
  {
@@ -4,7 +4,7 @@ Fimo provides locale utilities that follow the Fimo standard, but they are helpe
4
4
 
5
5
  ## Configuration
6
6
 
7
- `fimo-config.json` owns the locale list and routing strategy. Keep one locale unless the user asks for multilingual or localized output.
7
+ `.fimo/config.json` owns the locale list and routing strategy. Keep one locale unless the user asks for multilingual or localized output.
8
8
 
9
9
  ```jsonc
10
10
  {
@@ -28,7 +28,7 @@ Locale tags should be structurally valid, for example `en`, `es`, `pt-BR`, or `z
28
28
 
29
29
  ## Canonical Routes
30
30
 
31
- Keep `fimo-config.json#routes` canonical and unlocalized:
31
+ Keep `.fimo/config.json#routes` canonical and unlocalized:
32
32
 
33
33
  ```json
34
34
  {
@@ -71,7 +71,7 @@ Copyable examples live in `assets/react-router-locales/routes.ts` and `assets/re
71
71
 
72
72
  Before changing a multilingual app, inspect its locale provider, route table, language switcher, redirects, and current public URLs. Preserve that behavior while migrating.
73
73
 
74
- For React Router projects, prefer converging on one locale contract owned by `fimo-config.json`, `fimoRoutes()`, and `FimoLink`. Move existing providers and language-switcher UI into the framework root instead of replacing them or adding a second locale context. Keep route metadata canonical and reuse page modules across locales.
74
+ For React Router projects, prefer converging on one locale contract owned by `.fimo/config.json`, `fimoRoutes()`, and `FimoLink`. Move existing providers and language-switcher UI into the framework root instead of replacing them or adding a second locale context. Keep route metadata canonical and reuse page modules across locales.
75
75
 
76
76
  If adopting the standard helper would change established public URLs, do not silently rewrite them. Keep the custom router temporarily, pass its resolved locale to `<FimoProviders locale={locale}>`, and ask the user to choose the canonical URLs and redirects before normalizing the route table.
77
77
 
@@ -86,7 +86,7 @@ import { FimoLink } from 'fimo/react-router';
86
86
  <FimoLink to="/pricing" locale="es">Spanish pricing</FimoLink>
87
87
  ```
88
88
 
89
- `FimoLink` localizes absolute internal paths according to `fimo-config.json#i18n.routing`. It leaves relative, hash, query-only, and external URLs alone. Use React Router's raw `Link` only when you intentionally want to bypass Fimo's locale behavior.
89
+ `FimoLink` localizes absolute internal paths according to `.fimo/config.json#i18n.routing`. It leaves relative, hash, query-only, and external URLs alone. Use React Router's raw `Link` only when you intentionally want to bypass Fimo's locale behavior.
90
90
 
91
91
  Read the active locale with `useLocale()` when component logic needs it:
92
92
 
@@ -125,5 +125,5 @@ When using custom routing, also provide localized internal-link helpers in that
125
125
  ## What Not To Do
126
126
 
127
127
  - Do not create `src/pages/__localized/*` copies just for locales.
128
- - Do not duplicate every route in `fimo-config.json` per locale.
128
+ - Do not duplicate every route in `.fimo/config.json` per locale.
129
129
  - Do not use `/es` as a normal canonical route when `es` is an enabled locale.
@@ -85,7 +85,7 @@ Notes:
85
85
  ```
86
86
 
87
87
  The `seo` plugin rewrites `<title>`, og, twitter, canonical tags from
88
- `fimo-config.json#seo` at build time. You can leave a placeholder title in
88
+ `.fimo/config.json#seo` at build time. You can leave a placeholder title in
89
89
  `index.html`; it'll be replaced.
90
90
 
91
91
  ## File: `src/main.tsx`
@@ -140,7 +140,7 @@ export function App() {
140
140
  }
141
141
  ```
142
142
 
143
- ## File: `fimo-config.json`
143
+ ## File: `.fimo/config.json`
144
144
 
145
145
  ```json
146
146
  {
@@ -165,7 +165,7 @@ this version field. It also never injects the React Router plugin: in a
165
165
  framework-mode project that `reactRouter()` plugin is added by your own
166
166
  `vite.config.ts`, not by `fimo/vite`.
167
167
 
168
- ## File: `.fimo.settings.json`
168
+ ## File: `.fimo/project.json`
169
169
 
170
170
  ```json
171
171
  {
@@ -222,6 +222,6 @@ shows the **deployed** app, not the localhost dev server.
222
222
  ## What to do next
223
223
 
224
224
  - Add a sitemap: pass `fimo({ seo: true, sitemap: true })` and set
225
- `fimo-config.json#seo.url` to your production base URL.
225
+ `.fimo/config.json#seo.url` to your production base URL.
226
226
  - Look up exports: see `references/ui.md`.
227
227
  - Use schema content: see `references/content.md`.
@@ -166,7 +166,7 @@ export default fimoRoutes(routes) satisfies RouteConfig;
166
166
  Page filenames are your choice; the scaffold uses PascalCase (e.g. `Index.tsx`,
167
167
  `Privacy.tsx`).
168
168
 
169
- `fimoRoutes()` is Fimo's React Router helper for path-prefix locales. It is a no-op for single-locale projects and expands concrete locale aliases when `fimo-config.json#i18n.locales` contains more locales. Custom routers can ignore this helper and pass their own locale to `<FimoProviders locale={locale}>`; see `references/locales.md`.
169
+ `fimoRoutes()` is Fimo's React Router helper for path-prefix locales. It is a no-op for single-locale projects and expands concrete locale aliases when `.fimo/config.json#i18n.locales` contains more locales. Custom routers can ignore this helper and pass their own locale to `<FimoProviders locale={locale}>`; see `references/locales.md`.
170
170
 
171
171
  ## File: `src/pages/Index.tsx`
172
172
 
@@ -182,7 +182,7 @@ export default function HomePage() {
182
182
  }
183
183
  ```
184
184
 
185
- ## File: `fimo-config.json`
185
+ ## File: `.fimo/config.json`
186
186
 
187
187
  ```json
188
188
  {
@@ -200,7 +200,7 @@ export default function HomePage() {
200
200
  }
201
201
  ```
202
202
 
203
- ## File: `.fimo.settings.json`
203
+ ## File: `.fimo/project.json`
204
204
 
205
205
  ```json
206
206
  {
@@ -268,9 +268,9 @@ changes after a `fimo deploy` (the local dev server is localhost-only).
268
268
  ## What to do next
269
269
 
270
270
  - Add more routes: extend `src/routes.ts`, create matching `src/pages/*.tsx`,
271
- add route entries in `fimo-config.json#routes`.
271
+ add route entries in `.fimo/config.json#routes`.
272
272
  - Add a sitemap: pass `fimo({ sitemap: true })` (opt-in, off by default; the
273
273
  canonical template enables it). To customize the base URL, set
274
- `fimo-config.json#seo.url`.
274
+ `.fimo/config.json#seo.url`.
275
275
  - Override SEO per route: see `references/seo-overrides.md`.
276
276
  - Look up an export: see `references/api.md`.
@@ -27,7 +27,7 @@ Use these to render content-type field values consistently. They carry source me
27
27
  1. **Schema text → `<Text>`**, never `<h1>{post.title}</h1>`.
28
28
  2. **Schema media → `<Image>` / `<Video>`**, never `<img src={post.coverImage.url} />`. Provide `width` / `height` when known so Fimo can optimize and reserve layout space.
29
29
  3. **Non-schema images** (decorative, hard-coded URLs, generated assets referenced directly) → `<StaticImage>`. Never hand-construct a `FimoMedia` to feed `<Image>`.
30
- 4. **Label text → `<Text value={t('key')} />`**, not `<h1>{t(...)}</h1>`. Label values live in the DB for `i18n.defaultLocale` from `fimo-config.json` unless a non-default locale is explicitly targeted. See `references/labels.md`.
30
+ 4. **Label text → `<Text value={t('key')} />`**, not `<h1>{t(...)}</h1>`. Label values live in the DB for `i18n.defaultLocale` from `.fimo/config.json` unless a non-default locale is explicitly targeted. See `references/labels.md`.
31
31
  5. **Mixed schema + translated text** → the `` fimo`...` `` template literal inside `<Text>`.
32
32
  6. **Never hand-roll richtext rendering** — always `<RichText>`. To restyle a node, pass `components={{ heading: ..., link: ..., ... }}`.
33
33
  7. **Schema `json` → `<Json>`**, not a hand-rolled `<pre data-fimo-source={getFimoSource(post.metadata)}>{JSON.stringify(post.metadata)}</pre>`. Default renders as a `<span>`; pass `as="pre"` (with a `whitespace-pre-wrap` class) for a formatted block, or a children render function for custom display of specific keys.
@@ -6,7 +6,7 @@ Use this as the phase contract for complete migrations.
6
6
 
7
7
  1. Confirm the target path.
8
8
  2. If the target path is missing, create exactly one Fimo project there.
9
- 3. If it has `.fimo.settings.json`, reuse it.
9
+ 3. If it has `.fimo/project.json` or the legacy `.fimo.settings.json`, reuse it.
10
10
  4. If it is non-empty and not a Fimo project, stop and ask for a target path.
11
11
  5. Never overwrite user work outside generated migration folders without reading
12
12
  the existing files first.
@@ -110,7 +110,7 @@ function buildCanonicalManifest({ projectRoot, urlLedger, urlLedgerPath, sourceL
110
110
  forms,
111
111
  redirects: normalizeItems(sourceLedger?.redirects, 'redirect'),
112
112
  locales: normalizeItems(sourceLedger?.locales, 'locale'),
113
- seo: normalizeSeo(urlLedger),
113
+ seo: normalizeSeo(urlLedger, projectRoot),
114
114
  unsupported: normalizeItems(sourceLedger?.unsupported, 'unsupported'),
115
115
  unresolved: mergeItems([
116
116
  ...normalizeUnresolved(sourceLedger?.unresolved),
@@ -326,14 +326,15 @@ function normalizeUrlForms(forms) {
326
326
  }));
327
327
  }
328
328
 
329
- function normalizeSeo(urlLedger) {
329
+ function normalizeSeo(urlLedger, projectRoot) {
330
+ const configPath = resolveProjectConfigPath(projectRoot);
330
331
  return asArray(urlLedger?.pages).map((page) => ({
331
332
  id: `seo:${page.route}`,
332
333
  status: 'discovered',
333
334
  route: page.route,
334
335
  sourceUrls: compact([page.url]),
335
336
  sourceFiles: compact([page.artifacts?.html]),
336
- targetFiles: ['fimo-config.json'],
337
+ targetFiles: [configPath],
337
338
  confidence: numberOr(page.confidence, 0.7),
338
339
  title: page.seo?.title ?? page.title ?? null,
339
340
  description: page.seo?.description ?? null,
@@ -341,6 +342,34 @@ function normalizeSeo(urlLedger) {
341
342
  }));
342
343
  }
343
344
 
345
+ function resolveProjectConfigPath(projectRoot) {
346
+ if (fs.existsSync(path.join(projectRoot, '.fimo/project.json'))) {
347
+ return '.fimo/config.json';
348
+ }
349
+ if (fs.existsSync(path.join(projectRoot, '.fimo.settings.json'))) {
350
+ if (fs.existsSync(path.join(projectRoot, 'fimo-config.json'))) {
351
+ return 'fimo-config.json';
352
+ }
353
+ if (fs.existsSync(path.join(projectRoot, 'fimo.config.json'))) {
354
+ return 'fimo.config.json';
355
+ }
356
+ return 'fimo-config.json';
357
+ }
358
+ if (
359
+ fs.existsSync(path.join(projectRoot, '.fimo/config.json')) ||
360
+ fs.existsSync(path.join(projectRoot, '.fimo/agents'))
361
+ ) {
362
+ return '.fimo/config.json';
363
+ }
364
+ if (fs.existsSync(path.join(projectRoot, 'fimo-config.json'))) {
365
+ return 'fimo-config.json';
366
+ }
367
+ if (fs.existsSync(path.join(projectRoot, 'fimo.config.json'))) {
368
+ return 'fimo.config.json';
369
+ }
370
+ return '.fimo/config.json';
371
+ }
372
+
344
373
  function normalizeUnresolved(items) {
345
374
  return asArray(items).map((item, index) => {
346
375
  if (typeof item === 'string') {
@@ -12,7 +12,7 @@ If you're driving Fimo from the terminal, the equivalent commands are `fimo doma
12
12
  ## Adding a Custom Domain
13
13
 
14
14
  1. Open **Settings** from the top navigation bar (gear icon), alongside Preview, Content, Assets, Agents, and Analytics.
15
- 2. In the Settings menu on the left, select **Domains** (globe icon) — listed with General, SEO, and Audit log.
15
+ 2. In the Settings menu on the left, select **Domains** (globe icon) — listed with General and SEO.
16
16
  3. Click the **Add domain** button (+ icon) in the top-right of the panel. (When domain purchase is enabled, a **Buy domain** button with a shopping-cart icon sits next to it.)
17
17
  4. A drawer opens. Type or select a domain — you can enter a subdomain or an apex domain. Domains your organization already owns appear in an autocomplete dropdown, and Fimo checks availability live as you type. For an apex domain, a checkbox lets you also redirect it to the `www` subdomain (on by default). Confirm to add it.
18
18
  5. A DNS table appears showing the record(s) you need to add. For a **subdomain** it's a single CNAME record:
@@ -2,7 +2,7 @@ import type { PluginOption } from 'vite';
2
2
  export interface FimoViteOptions {
3
3
  /**
4
4
  * Emit `sitemap.xml` at build (and serve at `/sitemap.xml` in dev). Reads
5
- * `seo.url` from `fimo-config.json` as the base URL.
5
+ * `seo.url` from `.fimo/config.json` as the base URL.
6
6
  *
7
7
  * Opt-in via `fimo({ sitemap: true })`.
8
8
  */
@@ -10,14 +10,14 @@ export interface FimoViteOptions {
10
10
  /**
11
11
  * Emit `robots.txt` at build (and serve at `/robots.txt` in dev). Defaults
12
12
  * to an allow-all robots policy + a `Sitemap:` directive when `seo.url` is
13
- * set in `fimo-config.json`.
13
+ * set in `.fimo/config.json`.
14
14
  *
15
15
  * Opt-in via `fimo({ robots: true })`.
16
16
  */
17
17
  robots?: boolean;
18
18
  /**
19
19
  * Inject SEO meta tags into `index.html` via `transformIndexHtml`. Resolves
20
- * per-route SEO from `fimo-config.json#seo` and the matched route.
20
+ * per-route SEO from `.fimo/config.json#seo` and the matched route.
21
21
  *
22
22
  * Only applies in projects that have an `index.html` (plain Vite). Conflicts
23
23
  * with frameworks that have their own SEO mechanism — React Router's `meta`
@@ -1,11 +1,11 @@
1
1
  import type { Plugin } from 'vite';
2
2
  /**
3
- * Vite plugin that exposes the user's `fimo-config.json`:
3
+ * Vite plugin that exposes the user's `.fimo/config.json`:
4
4
  * - As a virtual module `virtual:fimo-config` that browser-running package
5
5
  * code (fimo/seo, fimo/app) imports to read `seo`, `routes`, etc. without
6
6
  * relying on `readFileSync` at runtime.
7
7
  *
8
- * Edits to `fimo-config.json` invalidate the virtual module so HMR picks up
8
+ * Edits to the project config invalidate the virtual module so HMR picks up
9
9
  * the new values without a full reload.
10
10
  */
11
11
  export default function fimoConfigPlugin(): Plugin;
@@ -1,23 +1,23 @@
1
1
  import { readFileSync } from 'fs';
2
- import { resolve } from 'path';
2
+ import { resolveFimoConfigPath } from '../../../runtime/shared/fimo-config.server.js';
3
3
  const VIRTUAL_ID = 'virtual:fimo-config';
4
4
  const RESOLVED_ID = '\0' + VIRTUAL_ID;
5
5
  /**
6
- * Vite plugin that exposes the user's `fimo-config.json`:
6
+ * Vite plugin that exposes the user's `.fimo/config.json`:
7
7
  * - As a virtual module `virtual:fimo-config` that browser-running package
8
8
  * code (fimo/seo, fimo/app) imports to read `seo`, `routes`, etc. without
9
9
  * relying on `readFileSync` at runtime.
10
10
  *
11
- * Edits to `fimo-config.json` invalidate the virtual module so HMR picks up
11
+ * Edits to the project config invalidate the virtual module so HMR picks up
12
12
  * the new values without a full reload.
13
13
  */
14
14
  export default function fimoConfigPlugin() {
15
- let configPath = resolve(process.cwd(), 'fimo-config.json');
15
+ let configPath = resolveFimoConfigPath(process.cwd());
16
16
  return {
17
17
  name: 'vite-plugin-fimo-config',
18
18
  config(userConfig) {
19
19
  const root = typeof userConfig.root === 'string' ? userConfig.root : process.cwd();
20
- configPath = resolve(root, 'fimo-config.json');
20
+ configPath = resolveFimoConfigPath(root);
21
21
  },
22
22
  resolveId(id) {
23
23
  if (id === VIRTUAL_ID) {
@@ -1,7 +1,7 @@
1
1
  import type { Plugin } from 'vite';
2
2
  /**
3
3
  * Emit a minimal `robots.txt` (allow-all + Sitemap reference if `seo.url` is
4
- * set in `fimo-config.json`). Serves at `/robots.txt` in dev; emits as a
4
+ * set in `.fimo/config.json`). Serves at `/robots.txt` in dev; emits as a
5
5
  * static asset at build time.
6
6
  *
7
7
  * Opt-in via `fimo({ robots: true })` in your `vite.config.ts`.
@@ -1,8 +1,8 @@
1
1
  import { readFileSync } from 'fs';
2
- import { resolve } from 'path';
2
+ import { resolveFimoConfigPath } from '../../../runtime/shared/fimo-config.server.js';
3
3
  function readSeoUrl() {
4
4
  try {
5
- const raw = readFileSync(resolve(process.cwd(), 'fimo-config.json'), 'utf-8');
5
+ const raw = readFileSync(resolveFimoConfigPath(process.cwd()), 'utf-8');
6
6
  const config = JSON.parse(raw);
7
7
  return config.seo?.url;
8
8
  }
@@ -25,7 +25,7 @@ function buildRobotsTxt(baseUrl) {
25
25
  }
26
26
  /**
27
27
  * Emit a minimal `robots.txt` (allow-all + Sitemap reference if `seo.url` is
28
- * set in `fimo-config.json`). Serves at `/robots.txt` in dev; emits as a
28
+ * set in `.fimo/config.json`). Serves at `/robots.txt` in dev; emits as a
29
29
  * static asset at build time.
30
30
  *
31
31
  * Opt-in via `fimo({ robots: true })` in your `vite.config.ts`.
@@ -9,7 +9,7 @@ export default function serverConfigPlugin() {
9
9
  overlay: false,
10
10
  },
11
11
  watch: {
12
- ignored: ['**/.worktrees/**', '**/fimo-config.json'],
12
+ ignored: ['**/.worktrees/**', '**/.fimo/config.json', '**/fimo-config.json'],
13
13
  },
14
14
  },
15
15
  build: {},
@@ -1,9 +1,9 @@
1
1
  import { readFileSync } from 'fs';
2
- import { resolve } from 'path';
3
2
  import { getFimoPaths } from '../../../runtime/paths/get-fimo-paths.js';
3
+ import { resolveFimoConfigPath } from '../../../runtime/shared/fimo-config.server.js';
4
4
  function readSeoUrl() {
5
5
  try {
6
- const raw = readFileSync(resolve(process.cwd(), 'fimo-config.json'), 'utf-8');
6
+ const raw = readFileSync(resolveFimoConfigPath(process.cwd()), 'utf-8');
7
7
  const config = JSON.parse(raw);
8
8
  return config.seo?.url;
9
9
  }
@@ -4,7 +4,8 @@ import { readFile } from 'node:fs/promises';
4
4
  import { homedir } from 'node:os';
5
5
  import { join } from 'node:path';
6
6
  import { getFimoDefaultLocale, getFimoLocales } from '../../../runtime/i18n/locale.js';
7
- import { getConfigServer } from '../../../runtime/shared/fimo-config.server.js';
7
+ import { CURRENT_PROJECT_LAYOUT, LEGACY_PROJECT_LAYOUT } from '../../../runtime/project-layout.js';
8
+ import { getConfigServer, resolveFimoConfigPath } from '../../../runtime/shared/fimo-config.server.js';
8
9
  const VIRTUAL_ID = 'virtual:translations';
9
10
  const RESOLVED_ID = '\0' + VIRTUAL_ID;
10
11
  const EVENT_RECONNECT_DELAY_MS = 2000;
@@ -155,7 +156,7 @@ export default function translationsPlugin() {
155
156
  },
156
157
  async buildStart() {
157
158
  bundle = emptyLabelBundle(rootDir);
158
- this.addWatchFile(join(rootDir, 'fimo-config.json'));
159
+ this.addWatchFile(resolveFimoConfigPath(rootDir));
159
160
  this.addWatchFile(join(rootDir, '.env'));
160
161
  this.addWatchFile(join(rootDir, '.env.local'));
161
162
  if (command === 'build') {
@@ -165,7 +166,7 @@ export default function translationsPlugin() {
165
166
  configureServer(server) {
166
167
  devServer = server;
167
168
  closed = false;
168
- server.watcher.add([join(rootDir, 'fimo-config.json'), join(rootDir, '.env'), join(rootDir, '.env.local')]);
169
+ server.watcher.add([resolveFimoConfigPath(rootDir), join(rootDir, '.env'), join(rootDir, '.env.local')]);
169
170
  void refreshLabelsAndInvalidateIfChanged().catch(() => undefined);
170
171
  startFallbackPolling();
171
172
  void connectEvents();
@@ -196,7 +197,7 @@ export default function translationsPlugin() {
196
197
  ].join('\n');
197
198
  },
198
199
  async handleHotUpdate(ctx) {
199
- const watched = new Set([join(rootDir, 'fimo-config.json'), join(rootDir, '.env'), join(rootDir, '.env.local')]);
200
+ const watched = new Set([resolveFimoConfigPath(rootDir), join(rootDir, '.env'), join(rootDir, '.env.local')]);
200
201
  if (!watched.has(ctx.file)) {
201
202
  return;
202
203
  }
@@ -515,13 +516,16 @@ async function readEnvFile(filePath) {
515
516
  }
516
517
  }
517
518
  async function readProjectSettings(rootDir) {
518
- try {
519
- const raw = await readFile(join(rootDir, '.fimo.settings.json'), 'utf8');
520
- return JSON.parse(raw);
521
- }
522
- catch {
523
- return {};
519
+ for (const relativePath of [CURRENT_PROJECT_LAYOUT.project, LEGACY_PROJECT_LAYOUT.project]) {
520
+ try {
521
+ const raw = await readFile(join(rootDir, relativePath), 'utf8');
522
+ return JSON.parse(raw);
523
+ }
524
+ catch {
525
+ continue;
526
+ }
524
527
  }
528
+ return {};
525
529
  }
526
530
  function deriveEventsRooms(projectId, tenantApiUrl) {
527
531
  const rooms = new Set([projectId]);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-08-02T09:47:16.199Z",
4
+ "bundledAt": "2026-08-04T09:13:16.740Z",
5
5
  "cliVersion": "0.10.0",
6
6
  "external": [
7
7
  "oxc-parser",