fimo 0.11.0-staging.1 → 0.11.0-staging.10

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 (80) 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 +12 -7
  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/content.md +2 -0
  8. package/assets/skills/fimo-cli/references/credits.md +1 -1
  9. package/assets/skills/fimo-cli/references/deploy.md +1 -1
  10. package/assets/skills/fimo-cli/references/describe.md +1 -1
  11. package/assets/skills/fimo-cli/references/history.md +1 -1
  12. package/assets/skills/fimo-cli/references/init.md +51 -16
  13. package/assets/skills/fimo-cli/references/integrations/firecrawl.md +12 -3
  14. package/assets/skills/fimo-cli/references/integrations.md +15 -3
  15. package/assets/skills/fimo-cli/references/invite.md +1 -1
  16. package/assets/skills/fimo-cli/references/labels.md +1 -1
  17. package/assets/skills/fimo-cli/references/locales.md +4 -4
  18. package/assets/skills/fimo-cli/references/mcp.md +85 -0
  19. package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +1 -1
  20. package/assets/skills/fimo-cli/references/projects.md +7 -7
  21. package/assets/skills/fimo-code/references/content.md +1 -0
  22. package/assets/skills/fimo-code/references/labels.md +2 -2
  23. package/assets/skills/fimo-code/references/locales.md +5 -5
  24. package/assets/skills/fimo-code/references/setup-plain-vite.md +12 -11
  25. package/assets/skills/fimo-code/references/setup-react-router.md +10 -5
  26. package/assets/skills/fimo-code/references/ui.md +1 -1
  27. package/assets/skills/fimo-migration/references/workflow.md +1 -1
  28. package/assets/skills/fimo-migration/scripts/build-canonical-manifest.mjs +32 -3
  29. package/assets/skills/fimo-studio/references/ai-chat.md +8 -2
  30. package/assets/skills/fimo-studio/references/custom-domains.md +1 -1
  31. package/assets/skills/fimo-studio/references/preview-and-responsive.md +1 -1
  32. package/assets/skills/fimo-studio/references/publish-and-deploy.md +2 -1
  33. package/assets/starters/fimo-site/manifest.json +64 -0
  34. package/assets/starters/fimo-site/template/.fimo/agents/content-guide/GOAL.md +8 -0
  35. package/assets/starters/fimo-site/template/.fimo/agents/content-guide/capabilities.yaml +2 -0
  36. package/assets/starters/fimo-site/template/.fimo/agents/content-guide/config.yaml +9 -0
  37. package/assets/starters/fimo-site/template/.fimo/agents/site-review/GOAL.md +14 -0
  38. package/assets/starters/fimo-site/template/.fimo/agents/site-review/capabilities.yaml +4 -0
  39. package/assets/starters/fimo-site/template/.fimo/agents/site-review/config.yaml +9 -0
  40. package/assets/starters/fimo-site/template/src/forms/contact.json +14 -0
  41. package/assets/starters/fimo-site/template/src/forms/contact.ts +46 -0
  42. package/assets/starters/fimo-site/template/src/pages/Contact.tsx +193 -0
  43. package/assets/starters/fimo-site/template/src/pages/Index.tsx +27 -0
  44. package/assets/starters/fimo-site/template/src/pages/SiteContent.tsx +191 -0
  45. package/assets/starters/fimo-site/template/src/schemas/HomePage.json +28 -0
  46. package/assets/starters/fimo-site/template/src/schemas/HomePage.ts +29 -0
  47. package/assets/starters/fimo-site/template/src/schemas/HomePage.types.ts +64 -0
  48. package/dist/build/vite/index.d.ts +3 -3
  49. package/dist/build/vite/index.js +12 -3
  50. package/dist/build/vite/plugins/fimo-config.d.ts +2 -2
  51. package/dist/build/vite/plugins/fimo-config.js +5 -5
  52. package/dist/build/vite/plugins/robots.d.ts +1 -1
  53. package/dist/build/vite/plugins/robots.js +3 -3
  54. package/dist/build/vite/plugins/server-config.js +1 -1
  55. package/dist/build/vite/plugins/sitemap.js +2 -2
  56. package/dist/build/vite/plugins/translations.js +14 -10
  57. package/dist/cli/bundle.json +1 -1
  58. package/dist/cli/index.js +147 -135
  59. package/dist/runtime/app/FimoProviders.js +18 -8
  60. package/dist/runtime/app/prefetch.d.ts +1 -1
  61. package/dist/runtime/app/prefetch.js +2 -2
  62. package/dist/runtime/content/client/internal.js +3 -3
  63. package/dist/runtime/paths/get-fimo-paths.d.ts +1 -1
  64. package/dist/runtime/paths/get-fimo-paths.js +5 -5
  65. package/dist/runtime/paths/types.d.ts +1 -1
  66. package/dist/runtime/project-layout.d.ts +14 -0
  67. package/dist/runtime/project-layout.js +57 -0
  68. package/dist/runtime/seo/resolver.d.ts +1 -1
  69. package/dist/runtime/seo/resolver.js +1 -1
  70. package/dist/runtime/shared/fimo-config.server.d.ts +2 -0
  71. package/dist/runtime/shared/fimo-config.server.js +17 -4
  72. package/dist/runtime/templates.d.ts +4 -4
  73. package/dist/runtime/templates.js +11 -6
  74. package/dist/scripts/validate-route-metadata.js +8 -6
  75. package/package.json +9 -3
  76. package/templates/react-router/AGENTS.md +1 -1
  77. package/templates/react-router/package.json +1 -1
  78. package/templates/react-router/src/vite-env.d.ts +1 -1
  79. package/templates/react-router/vite.config.ts +1 -1
  80. /package/templates/react-router/{fimo-config.json → .fimo/config.json} +0 -0
@@ -0,0 +1,85 @@
1
+ # Project MCP
2
+
3
+ > **Run via `npx fimo@latest <command>`** — always the latest CLI, no install needed.
4
+
5
+ The **Project MCP** lets an AI coding client use Fimo's project workflows through the Model Context Protocol. It is
6
+ the same Fimo tool surface exposed in two ways:
7
+
8
+ - **Local MCP**: `fimo mcp` over stdio, for an AI client running next to a checkout.
9
+ - **Remote MCP**: `https://api.fimo.ai/api/mcp` over authenticated Streamable HTTP, for ChatGPT, Claude, and other
10
+ clients that support OAuth.
11
+
12
+ The local and remote Project MCP modes share the same catalog. The public Docs MCP at
13
+ `https://fimo.ai/docs/mcp` is separate: it is unauthenticated, read-only, and only provides Fimo documentation.
14
+
15
+ ## Set up the local MCP
16
+
17
+ Authenticate the CLI first:
18
+
19
+ ```bash
20
+ npx fimo@latest login
21
+ ```
22
+
23
+ Then configure the MCP client to launch:
24
+
25
+ ```text
26
+ npx fimo@latest mcp
27
+ ```
28
+
29
+ For clients that accept a JSON command configuration, the equivalent entry is:
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "fimo": {
35
+ "command": "npx",
36
+ "args": ["fimo@latest", "mcp"]
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ Do not add shell output or logging around the command: stdout is reserved for MCP JSON-RPC frames. Diagnostics are
43
+ written to stderr.
44
+
45
+ ## Project and environment scope
46
+
47
+ When launched inside a linked Fimo project, `fimo mcp` reads the project from `.fimo.settings.json` and uses the
48
+ current git branch as the default environment. This keeps an AI client working against the same project environment as
49
+ the checkout.
50
+
51
+ Outside a linked project, the server still works, but each project-scoped tool call must provide `projectId` and
52
+ `env`. The client can also pass an environment override when launching the CLI. Never edit `.fimo.settings.json`
53
+ manually to change scope.
54
+
55
+ The CLI credential represents the signed-in user's Fimo authority. If an MCP server is invoked from a Fimo agent
56
+ session, the session's frozen capability snapshot still limits the operations available to that agent.
57
+
58
+ ## Capabilities
59
+
60
+ The Project MCP catalog covers:
61
+
62
+ - **Identity and navigation** — current user, projects, and environments.
63
+ - **Content** — schemas, collection entries, search, create/update/delete, bounded bulk operations, and Singles.
64
+ - **Labels** — list, read, set, batch-set, and delete localized labels.
65
+ - **Media** — list and inspect assets, generate images or videos, create folders, move, and delete assets. Binary
66
+ upload remains `fimo assets upload`.
67
+ - **Forms** — create, read, update, and delete forms; inspect submissions and statistics.
68
+ - **Files** — read, glob, grep, write, edit, and delete project files within the scoped environment. Sensitive files
69
+ such as credentials and `.env` files are excluded.
70
+ - **Agents** — list agents, start a run, and inspect run status.
71
+
72
+ Use the MCP client's tool list as the wire-level source of truth. The catalog is shared with the remote endpoint, so a
73
+ client configured locally sees the same tool names and input shapes as a remote client.
74
+
75
+ ## Local versus remote authorization
76
+
77
+ Local MCP uses the stored CLI credential (or `FIMO_API_TOKEN` when explicitly configured). It does not use the
78
+ browser OAuth consent screen. Remote MCP uses Fimo OAuth with `read`, `write`, and `agents` scopes; the user selects
79
+ the optional capabilities during consent.
80
+
81
+ In both modes, Fimo still checks the user's project permissions, environment access, input validation, and file safety
82
+ rules for every operation. MCP does not grant access to projects the user cannot already access.
83
+
84
+ For ChatGPT, Claude, or another remote MCP client, use the setup guide in the public [MCP documentation](https://fimo.ai/docs/ai/mcp)
85
+ instead of the local stdio configuration above.
@@ -62,7 +62,7 @@ fimo agents secrets remove seo-publisher FIRECRAWL_API_KEY
62
62
  fimo agents validate
63
63
  ```
64
64
 
65
- `fimo agents secrets add` edits `agents/<name>/config.yaml`. It does not create or rotate the secret value. Use `fimo secrets add` to create the value or `fimo secrets update` to rotate it.
65
+ `fimo agents secrets add` edits `.fimo/agents/<name>/config.yaml`. It does not create or rotate the secret value. Use `fimo secrets add` to create the value or `fimo secrets update` to rotate it.
66
66
 
67
67
  `fimo agents validate` checks that required agent secrets exist in the project. A running agent keeps the environment it started with; the next run reads the deployed agent config again.
68
68
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **Run via `npx fimo@latest <command>`** — always the latest CLI, no install needed.
4
4
 
5
- Commands for listing projects across an org, cloning a remote project locally, and managing the lifecycle of a single project (delete, publish, unpublish, rename). Most lifecycle commands operate on the **current project** (read from `.fimo.settings.json` in the cwd) by default; for `delete`, `publish`, and `unpublish` you can pass an explicit `[projectId]` to target another. (`rename` is local-only — it never targets a different project; see below.)
5
+ Commands for listing projects across an org, cloning a remote project locally, and managing the lifecycle of a single project (delete, publish, unpublish, rename). Most lifecycle commands operate on the **current project** (read from `.fimo/project.json`, or the legacy `.fimo.settings.json`, in the cwd) by default; for `delete`, `publish`, and `unpublish` you can pass an explicit `[projectId]` to target another. (`rename` only edits the linked local project; see below.)
6
6
 
7
7
  ## The `fimo projects` namespace
8
8
 
@@ -13,15 +13,15 @@ fimo projects clone [projectId] [dir] [--env <name>] # clone an existing project
13
13
  fimo projects delete [projectId] [-C <dir>] [-y] # delete (defaults to current project)
14
14
  fimo projects publish [projectId] [-C <dir>] # make the project live (publish from main)
15
15
  fimo projects unpublish [projectId] [-C <dir>] # take the project offline
16
- fimo projects rename <name> [projectId] [-C <dir>] # local-only: set seo.siteName in fimo-config.json
16
+ fimo projects rename <name> [projectId] [-C <dir>] # set seo.siteName in the linked project config
17
17
  ```
18
18
 
19
19
  - **`list`** — projects you can see in the org. Live projects are marked.
20
20
  - **`create`** — identical to `fimo init` (create-new path); see `references/init.md`.
21
- - **`clone`** — clone a remote Fimo project's git repo to your machine and write the local `.fimo.settings.json`/agent files. Use `fimo clone <projectId>` when scripting or when the ID is known. In an interactive terminal, bare `fimo clone` opens a project picker for the active org; JSON mode and non-TTY shells require an explicit project ID and fail fast instead of prompting. By default it clones `main`; pass `--env <name>` to clone a specific env. The target directory defaults to the project display name/name, or pass `[dir]` explicitly.
21
+ - **`clone`** — clone a remote Fimo project's git repo to your machine and write the local `.fimo/project.json` and agent files. Use `fimo clone <projectId>` when scripting or when the ID is known. In an interactive terminal, bare `fimo clone` opens a project picker for the active org; JSON mode and non-TTY shells require an explicit project ID and fail fast instead of prompting. By default it clones `main`; pass `--env <name>` to clone a specific env. The target directory defaults to the project display name/name, or pass `[dir]` explicitly.
22
22
  - **`delete`** — destructive; prompts unless `-y`. Removes the remote project.
23
23
  - **`publish` / `unpublish`** — toggle the project's public visibility. `publish` flips the current `main` state live (the same "go live" as `fimo deploy --publish`, minus the git push). This is **not** the versioned release path — for that, see `fimo publish` in `references/branches.md`.
24
- - **`rename`** — **local-only**, unlike the others. It does not touch the remote project record. It requires `.fimo.settings.json` in the cwd, and if you pass a `[projectId]` that doesn't match the linked project it errors and exits 1 (so you can't rename a different project). It writes `seo.siteName` into the local `fimo-config.json`; you must commit and run `fimo deploy` to apply the change.
24
+ - **`rename`** — edits only the linked local project immediately. It requires a project marker in the cwd, and if you pass a `[projectId]` that doesn't match the linked project it errors and exits 1 (so you can't rename a different project). It writes `seo.siteName` into the current or legacy project config; commit and run `fimo deploy` to reconcile the remote `displayName` and deploy the new site name.
25
25
 
26
26
  ## Top-level clone shortcut
27
27
 
@@ -33,15 +33,15 @@ Use the top-level shortcut for the common "get this project onto my machine" wor
33
33
 
34
34
  ## Top-level shortcuts (current project)
35
35
 
36
- These target the project linked in the cwd's `.fimo.settings.json` — handy from inside a project directory:
36
+ These target the project linked in the cwd's `.fimo/project.json` (or legacy `.fimo.settings.json`) — handy from inside a project directory:
37
37
 
38
38
  ```bash
39
39
  fimo delete [-C <dir>] [-y] # delete the current project
40
40
  fimo unpublish [-C <dir>] # unpublish the current project
41
- fimo rename "<Site Name>" # local edit: set seo.siteName in fimo-config.json
41
+ fimo rename "<Site Name>" # local edit: set seo.siteName in the project config
42
42
  ```
43
43
 
44
- `fimo rename` sets the **site name** (`seo.siteName`) in the local `fimo-config.json` — it is a local edit, not a remote update, so it requires a follow-up commit + `fimo deploy` to take effect. It does **not** change the project's remote display name (the `displayName` shown by `projects list`), which is set once at creation time from the project directory name. See `references/init.md` and `references/deploy.md`.
44
+ `fimo rename` sets the **site name** (`seo.siteName`) in the local project config — it is a local edit, not an immediate remote update, so it requires a follow-up commit + `fimo deploy` to take effect. Deploy reconciles the project's remote `displayName` with the committed site name while pushing the config. See `references/init.md` and `references/deploy.md`.
45
45
 
46
46
  ## Three "publish" verbs — don't confuse them
47
47
 
@@ -163,6 +163,7 @@ A field may declare `showIf` (every clause must match) or `showIfAny` (one claus
163
163
 
164
164
  - `blocks.schema.fields` repeats one homogeneous shape.
165
165
  - `blocks.schema.oneOf` lets the editor choose exactly one variant per item.
166
+ - Blocks schemas support at most 7 nested `blocks` levels, 40 variants in one `schema.oneOf`, and `min` or `max` values up to 200 items per blocks field.
166
167
  - Blocks always read and write arrays. A field with `max: 1` is `[]` or `[item]`, never a bare object.
167
168
  - `min` and `max` constrain the total number of blocks. Use `min: 1` to require at least one block; `required: true` has the same minimum-one behavior.
168
169
  - Fimo creates a stable `_key` for each item. A `oneOf` item also carries `_type`, matching the variant `uid`.
@@ -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,16 +85,16 @@ 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`
92
92
 
93
- `FimoProviders` (and the runtime primitives it wraps) require **two** contexts:
94
- a React Router `<Router>` ancestor (it reads `useLocation`/`useNavigate`) and a
95
- `@tanstack/react-query` `<QueryClientProvider>` (its internal
96
- `RefreshContentProvider` calls `useQueryClient`). Mount both around
97
- `<FimoProviders>`:
93
+ `FimoProviders` requires a React Router `<Router>` ancestor (it reads
94
+ `useLocation`/`useNavigate`). It reuses a host app's
95
+ `@tanstack/react-query` client when one exists and supplies a stable fallback
96
+ for adopted SPAs. This recipe still mounts an explicit provider so the app owns
97
+ the shared cache and its configuration:
98
98
 
99
99
  ```tsx
100
100
  import { FimoProviders } from 'fimo/react-router';
@@ -122,8 +122,9 @@ createRoot(document.getElementById('root')!).render(
122
122
 
123
123
  `react-router` and `@tanstack/react-query` are peer dependencies of `fimo`;
124
124
  both are in the install command above. `FimoProviders` is exported only from
125
- the `fimo/react-router` adapter barrel — there is no router-free (or
126
- react-query-free) provider surface in the package today.
125
+ the `fimo/react-router` adapter barrel. Keep the explicit QueryClientProvider
126
+ when the app needs custom query defaults or shared cache access; adopted SPAs
127
+ can omit it.
127
128
 
128
129
  ## File: `src/App.tsx`
129
130
 
@@ -139,7 +140,7 @@ export function App() {
139
140
  }
140
141
  ```
141
142
 
142
- ## File: `fimo-config.json`
143
+ ## File: `.fimo/config.json`
143
144
 
144
145
  ```json
145
146
  {
@@ -164,7 +165,7 @@ this version field. It also never injects the React Router plugin: in a
164
165
  framework-mode project that `reactRouter()` plugin is added by your own
165
166
  `vite.config.ts`, not by `fimo/vite`.
166
167
 
167
- ## File: `.fimo.settings.json`
168
+ ## File: `.fimo/project.json`
168
169
 
169
170
  ```json
170
171
  {
@@ -221,6 +222,6 @@ shows the **deployed** app, not the localhost dev server.
221
222
  ## What to do next
222
223
 
223
224
  - Add a sitemap: pass `fimo({ seo: true, sitemap: true })` and set
224
- `fimo-config.json#seo.url` to your production base URL.
225
+ `.fimo/config.json#seo.url` to your production base URL.
225
226
  - Look up exports: see `references/ui.md`.
226
227
  - Use schema content: see `references/content.md`.
@@ -100,6 +100,11 @@ when to render them, and how.
100
100
 
101
101
  ## File: `src/root.tsx`
102
102
 
103
+ The explicit `QueryClientProvider` below is the canonical template shape so the
104
+ app can configure query defaults such as `staleTime`. Adopted SPAs can omit it:
105
+ `FimoProviders` reuses an ancestor client when present and supplies a stable
106
+ fallback otherwise.
107
+
103
108
  ```tsx
104
109
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
105
110
  import { FimoProviders, FimoScripts, loadFimoMetaData, buildFimoMeta, fimoHtmlProps } from 'fimo/react-router';
@@ -161,7 +166,7 @@ export default fimoRoutes(routes) satisfies RouteConfig;
161
166
  Page filenames are your choice; the scaffold uses PascalCase (e.g. `Index.tsx`,
162
167
  `Privacy.tsx`).
163
168
 
164
- `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`.
165
170
 
166
171
  ## File: `src/pages/Index.tsx`
167
172
 
@@ -177,7 +182,7 @@ export default function HomePage() {
177
182
  }
178
183
  ```
179
184
 
180
- ## File: `fimo-config.json`
185
+ ## File: `.fimo/config.json`
181
186
 
182
187
  ```json
183
188
  {
@@ -195,7 +200,7 @@ export default function HomePage() {
195
200
  }
196
201
  ```
197
202
 
198
- ## File: `.fimo.settings.json`
203
+ ## File: `.fimo/project.json`
199
204
 
200
205
  ```json
201
206
  {
@@ -263,9 +268,9 @@ changes after a `fimo deploy` (the local dev server is localhost-only).
263
268
  ## What to do next
264
269
 
265
270
  - Add more routes: extend `src/routes.ts`, create matching `src/pages/*.tsx`,
266
- add route entries in `fimo-config.json#routes`.
271
+ add route entries in `.fimo/config.json#routes`.
267
272
  - Add a sitemap: pass `fimo({ sitemap: true })` (opt-in, off by default; the
268
273
  canonical template enables it). To customize the base URL, set
269
- `fimo-config.json#seo.url`.
274
+ `.fimo/config.json#seo.url`.
270
275
  - Override SEO per route: see `references/seo-overrides.md`.
271
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') {
@@ -9,6 +9,12 @@ The AI chat opens as a floating panel by default. You can dock it to the left or
9
9
  3. Press **Enter** or click the **send button**.
10
10
  4. The AI responds in a stream. You see tool status badges appear as it works, and the preview updates automatically.
11
11
 
12
+ ## Responding to Choices and Forms
13
+
14
+ The AI can place choices, cards, tables, images, and contextual actions directly in its reply. Optional suggestions do not interrupt the conversation.
15
+
16
+ When the AI needs an answer before it can continue, it shows a form in the chat and waits for your response. Complete the form for a structured answer, or reply normally in the chat to answer in your own words.
17
+
12
18
  ## Attaching Context
13
19
 
14
20
  Give the AI more to work with:
@@ -37,9 +43,9 @@ While the AI works, you see small badges in the chat showing what it is doing. E
37
43
 
38
44
  Chat changes are prepared separately and then applied to the environment you are viewing. Most changes merge automatically.
39
45
 
40
- If the project changed in the same place while the AI was working, the response shows a **Review changes** card instead. Open it to inspect the proposal, resolve any conflicts, and merge when it is ready. Until you merge it, the proposal is not part of the environment and later chat messages will not see it.
46
+ If the project changed in the same place while the AI was working, the response shows a **Review changes** card and an attention banner above the chat input. The banner remains visible when floating chat history is collapsed.
41
47
 
42
- Discarding the merge leaves the current environment unchanged and keeps the proposal separate.
48
+ Choose **Auto fix** or keep chatting to let Fimo continue in the retained proposal, resolve the conflict, and retry the merge. Choose **Review manually** to inspect and resolve the proposal yourself. Discarding leaves the current environment unchanged and permanently removes the proposal.
43
49
 
44
50
  ## Tips for Better Results
45
51
 
@@ -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:
@@ -47,4 +47,4 @@ The preview is one of several workspaces, and only one is shown at a time. Switc
47
47
  - **Alt+4** -- Code
48
48
  - **Alt+5** -- Settings
49
49
 
50
- When the Preview workspace is open, the visual editor and the changes panel can appear alongside it as the preview's side panels.
50
+ When the Preview workspace is open, the visual editor can appear alongside it as a preview side panel.
@@ -14,7 +14,7 @@ Every change you make is automatically saved to your project, but saved changes
14
14
 
15
15
  To push your latest changes live, open the publish panel from the header **Publish** button and click **Publish** inside it again. It redeploys with your latest code and content.
16
16
 
17
- > **Tip:** Before your site has ever been published, the chat shows a one-click **Publish** button that deploys immediately without opening the panel.
17
+ > **Tip:** After completing relevant work, the AI may offer a one-click **Publish** callout in chat. It appears only when publishing is available; the header **Publish** control remains the reliable path at any time.
18
18
 
19
19
  ## Publishing Changes That Need Review
20
20
 
@@ -29,6 +29,7 @@ The header **Publish** button itself only shows the label "Publish" (or a spinne
29
29
  - **"Not published yet"** — Your site has never been published. The **Publish** button inside the panel is ready to click.
30
30
  - **"Publishing"** — Publishing is in progress. A spinner and a **Publishing** status badge show while it builds, and the button is disabled.
31
31
  - **"Published"** — Your site is live. A **Published** status badge appears, your live URL is listed under a **Published site** heading as a clickable link, and a **Last published** date and time is shown.
32
+ - **"Couldn't publish · N issues"** — Project validation found issues that must be fixed first. Choose **Fix with Fimo** to send the safe issue list to the project chat and ask Fimo to repair it.
32
33
 
33
34
  ## Key Concepts
34
35
 
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "fimo-site",
3
+ "version": 1,
4
+ "description": "A content-led site with a homepage, contact form, labels, and manual review agents.",
5
+ "singletons": [
6
+ {
7
+ "type": "HomePage",
8
+ "data": {
9
+ "eyebrow": "Field notes",
10
+ "title": "Your website, ready to edit.",
11
+ "intro": {
12
+ "type": "doc",
13
+ "content": [
14
+ {
15
+ "type": "paragraph",
16
+ "content": [
17
+ {
18
+ "type": "text",
19
+ "text": "This starter is real website content. Edit the copy in Studio, change the code with your favorite agent, and keep both surfaces in sync."
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ },
25
+ "primaryCtaLabel": "Read the field notes",
26
+ "primaryCtaHref": "#stories",
27
+ "featured": [
28
+ {
29
+ "label": "Start here",
30
+ "title": "A calmer content workflow",
31
+ "summary": "Keep content, code, previews, and the team in one editable project.",
32
+ "href": "#stories"
33
+ },
34
+ {
35
+ "label": "For agents",
36
+ "title": "Build once, keep iterating",
37
+ "summary": "Give your coding agent a real CMS surface to work with after the first deploy.",
38
+ "href": "#stories"
39
+ },
40
+ {
41
+ "label": "For teams",
42
+ "title": "Make every edit reviewable",
43
+ "summary": "Let teammates shape the site without asking them to open a code editor.",
44
+ "href": "#stories"
45
+ }
46
+ ],
47
+ "contactHeading": "Make something useful",
48
+ "contactIntro": "Tell us what you are building and we will help you find the shortest path from first draft to a site your team can own."
49
+ }
50
+ }
51
+ ],
52
+ "labels": [
53
+ { "key": "nav.stories", "value": "Field notes", "locale": "en" },
54
+ { "key": "nav.contact", "value": "Start a conversation", "locale": "en" },
55
+ { "key": "hero.scroll", "value": "Explore the starter", "locale": "en" },
56
+ { "key": "contact.name", "value": "Your name", "locale": "en" },
57
+ { "key": "contact.email", "value": "Email address", "locale": "en" },
58
+ { "key": "contact.message", "value": "What are you building?", "locale": "en" },
59
+ { "key": "contact.submit", "value": "Send a note", "locale": "en" },
60
+ { "key": "contact.sent", "value": "Thanks. Your note is on its way.", "locale": "en" },
61
+ { "key": "contact.failed", "value": "That did not send. Please try again.", "locale": "en" }
62
+ ],
63
+ "forms": ["contact"]
64
+ }
@@ -0,0 +1,8 @@
1
+ # Content guide
2
+
3
+ Inspect the site's content model and homepage copy. Suggest a small editorial
4
+ backlog that makes the site more useful to its intended audience.
5
+
6
+ Return three suggestions, each with the content type or field it touches and
7
+ why it matters. Use the existing content as evidence. Do not write files,
8
+ change entries, or create labels.
@@ -0,0 +1,9 @@
1
+ # Keep starter agents manual-only. Adding a schedule or webhook and pushing to
2
+ # main registers an automation for the project.
3
+ version: 1
4
+ description: 'Suggest useful editorial improvements from the existing CMS content.'
5
+ data_sources:
6
+ - main
7
+
8
+ triggers:
9
+ - type: manual
@@ -0,0 +1,14 @@
1
+ # Site review
2
+
3
+ Review the starter project as a teammate would before the first publish.
4
+
5
+ Read the declared routes, the CMS content, the labels, and the public site.
6
+ Return a short report with:
7
+
8
+ - one thing that already feels clear;
9
+ - the three highest-value improvements;
10
+ - any missing content or broken route you can prove;
11
+ - one next action that a human or coding agent can review.
12
+
13
+ This is a read-only review. Do not edit files, change CMS content, create
14
+ branches, or publish anything.
@@ -0,0 +1,4 @@
1
+ - files:read
2
+ - cms:read
3
+ - i18n:read
4
+ - net:fetch
@@ -0,0 +1,9 @@
1
+ # Keep starter agents manual-only. Adding a schedule or webhook and pushing to
2
+ # main registers an automation for the project.
3
+ version: 1
4
+ description: 'Review the starter site and return a concise, read-only launch report.'
5
+ data_sources:
6
+ - main
7
+
8
+ triggers:
9
+ - type: manual
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "contact",
3
+ "label": "Start a conversation",
4
+ "fields": {
5
+ "name": { "type": "text", "label": "Your name", "required": true },
6
+ "email": { "type": "email", "label": "Email address", "required": true },
7
+ "message": {
8
+ "type": "textarea",
9
+ "label": "What are you building?",
10
+ "required": true,
11
+ "validation": { "minLength": 10, "maxLength": 2000 }
12
+ }
13
+ }
14
+ }