fimo 0.10.1-staging.4 → 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.
- package/assets/agent-templates/content-translator/GOAL.md +3 -3
- package/assets/agent-templates/seo-audit/config.yaml +1 -1
- package/assets/skills/fimo/SKILL.md +5 -0
- package/assets/skills/fimo-cli/SKILL.md +12 -7
- package/assets/skills/fimo-cli/references/agents.md +71 -23
- package/assets/skills/fimo-cli/references/branches.md +2 -2
- package/assets/skills/fimo-cli/references/content.md +2 -0
- package/assets/skills/fimo-cli/references/credits.md +1 -1
- package/assets/skills/fimo-cli/references/deploy.md +1 -1
- package/assets/skills/fimo-cli/references/describe.md +1 -1
- package/assets/skills/fimo-cli/references/history.md +1 -1
- package/assets/skills/fimo-cli/references/init.md +51 -16
- package/assets/skills/fimo-cli/references/integrations/firecrawl.md +12 -3
- package/assets/skills/fimo-cli/references/integrations.md +15 -3
- package/assets/skills/fimo-cli/references/invite.md +1 -1
- package/assets/skills/fimo-cli/references/labels.md +1 -1
- package/assets/skills/fimo-cli/references/locales.md +4 -4
- package/assets/skills/fimo-cli/references/mcp.md +85 -0
- package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +1 -1
- package/assets/skills/fimo-cli/references/projects.md +7 -7
- package/assets/skills/fimo-code/references/content.md +20 -15
- package/assets/skills/fimo-code/references/labels.md +2 -2
- package/assets/skills/fimo-code/references/locales.md +5 -5
- package/assets/skills/fimo-code/references/setup-plain-vite.md +12 -11
- package/assets/skills/fimo-code/references/setup-react-router.md +10 -5
- package/assets/skills/fimo-code/references/ui.md +4 -1
- package/assets/skills/fimo-migration/references/workflow.md +1 -1
- package/assets/skills/fimo-migration/scripts/build-canonical-manifest.mjs +32 -3
- package/assets/skills/fimo-studio/references/ai-chat.md +14 -0
- package/assets/skills/fimo-studio/references/custom-domains.md +1 -1
- package/assets/skills/fimo-studio/references/preview-and-responsive.md +1 -1
- package/assets/skills/fimo-studio/references/publish-and-deploy.md +8 -1
- package/assets/starters/fimo-site/manifest.json +64 -0
- package/assets/starters/fimo-site/template/.fimo/agents/content-guide/GOAL.md +8 -0
- package/assets/starters/fimo-site/template/.fimo/agents/content-guide/capabilities.yaml +2 -0
- package/assets/starters/fimo-site/template/.fimo/agents/content-guide/config.yaml +9 -0
- package/assets/starters/fimo-site/template/.fimo/agents/site-review/GOAL.md +14 -0
- package/assets/starters/fimo-site/template/.fimo/agents/site-review/capabilities.yaml +4 -0
- package/assets/starters/fimo-site/template/.fimo/agents/site-review/config.yaml +9 -0
- package/assets/starters/fimo-site/template/src/forms/contact.json +14 -0
- package/assets/starters/fimo-site/template/src/forms/contact.ts +46 -0
- package/assets/starters/fimo-site/template/src/pages/Contact.tsx +193 -0
- package/assets/starters/fimo-site/template/src/pages/Index.tsx +27 -0
- package/assets/starters/fimo-site/template/src/pages/SiteContent.tsx +191 -0
- package/assets/starters/fimo-site/template/src/schemas/HomePage.json +28 -0
- package/assets/starters/fimo-site/template/src/schemas/HomePage.ts +29 -0
- package/assets/starters/fimo-site/template/src/schemas/HomePage.types.ts +64 -0
- package/dist/build/vite/index.d.ts +3 -3
- package/dist/build/vite/index.js +12 -3
- package/dist/build/vite/plugins/fimo-config.d.ts +2 -2
- package/dist/build/vite/plugins/fimo-config.js +5 -5
- package/dist/build/vite/plugins/robots.d.ts +1 -1
- package/dist/build/vite/plugins/robots.js +3 -3
- package/dist/build/vite/plugins/server-config.js +1 -1
- package/dist/build/vite/plugins/sitemap.js +2 -2
- package/dist/build/vite/plugins/translations.js +14 -10
- package/dist/cli/bundle.json +1 -1
- package/dist/cli/index.js +147 -135
- package/dist/runtime/app/FimoProviders.js +18 -8
- package/dist/runtime/app/prefetch.d.ts +1 -1
- package/dist/runtime/app/prefetch.js +2 -2
- package/dist/runtime/content/client/createContentClient.d.ts +15 -0
- package/dist/runtime/content/client/createContentClient.js +23 -0
- package/dist/runtime/content/client/createSingletonClient.js +3 -0
- package/dist/runtime/content/client/internal.js +66 -5
- package/dist/runtime/content/utils/retrieve-data-sources.d.ts +13 -0
- package/dist/runtime/content/utils/retrieve-data-sources.js +45 -31
- package/dist/runtime/paths/get-fimo-paths.d.ts +1 -1
- package/dist/runtime/paths/get-fimo-paths.js +5 -5
- package/dist/runtime/paths/types.d.ts +1 -1
- package/dist/runtime/primitives/components/Json.d.ts +25 -0
- package/dist/runtime/primitives/components/Json.js +29 -0
- package/dist/runtime/primitives/index.d.ts +1 -0
- package/dist/runtime/primitives/index.js +1 -0
- package/dist/runtime/project-layout.d.ts +14 -0
- package/dist/runtime/project-layout.js +57 -0
- package/dist/runtime/seo/resolver.d.ts +1 -1
- package/dist/runtime/seo/resolver.js +1 -1
- package/dist/runtime/shared/fimo-config.server.d.ts +2 -0
- package/dist/runtime/shared/fimo-config.server.js +17 -4
- package/dist/runtime/templates.d.ts +4 -4
- package/dist/runtime/templates.js +11 -6
- package/dist/scripts/validate-route-metadata.js +8 -6
- package/package.json +12 -6
- package/templates/react-router/AGENTS.md +1 -1
- package/templates/react-router/package.json +6 -6
- package/templates/react-router/src/vite-env.d.ts +1 -1
- package/templates/react-router/vite.config.ts +1 -1
- /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
|
|
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
|
|
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>] #
|
|
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.
|
|
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`** —
|
|
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
|
|
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
|
|
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
|
|
|
@@ -73,7 +73,7 @@ something else (e.g. `handle`, `permalink`).
|
|
|
73
73
|
| `reference` | `{ "id": "..." }`, `null`, or an array of reference objects when `many: true` | References to another schema |
|
|
74
74
|
| `blocks` | ordered array of objects | Fixed groups, repeated sections, or selectable page blocks |
|
|
75
75
|
|
|
76
|
-
A `date` field
|
|
76
|
+
A `date` field generates as `string` in the TS client and wraps in `FimoString` at read time — the same source-tracked shape as `string`/`text` — so `<Date value={post.someDate} />` and plain string methods (`.slice()`, template literals, …) both work directly.
|
|
77
77
|
|
|
78
78
|
## Enumerated strings
|
|
79
79
|
|
|
@@ -163,10 +163,12 @@ 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`.
|
|
169
170
|
- Nested fields support the same defaults and validators as top-level fields.
|
|
171
|
+
- **Each block item's own scalar fields wrap the same way their field type wraps at the top level** — a nested `string`/`text` field is a `FimoString`, a nested `richtext` field is a `FimoRichText`, a nested `media` field is a `FimoMedia`, a nested `boolean` is a `FimoBoolean`, a nested `date` is a `FimoString`, a nested `json` field is a shallow-cloned, source-tagged object, a nested `number` stays a plain `number`, and a nested `blocks` field recurses the same way. Pass those nested values to the matching `fimo/ui` component exactly like a top-level field — `<Text value={section.heading} />` or `<Json value={section.metadata} />` inside a `.map()` over `page.sections` stays inline-editable.
|
|
170
172
|
- Blocks inherit the owning entry's locale.
|
|
171
173
|
- Nested references use one fixed `target`. Unpopulated reads return `{ id, documentId }`, like top-level references.
|
|
172
174
|
- Nested population and filtering are not supported yet.
|
|
@@ -516,22 +518,25 @@ Populate is depth-one. It only works for reference fields; trying to populate a
|
|
|
516
518
|
|
|
517
519
|
The entry objects a hook returns are **not** plain JS values. The generated client wraps each _trackable_ field in a `fimo/ui` primitive that carries source metadata for inline editing. Which fields wrap, and which stay plain:
|
|
518
520
|
|
|
519
|
-
| Schema field type | Field value you get | Notes
|
|
520
|
-
| ----------------- | ----------------------------------- |
|
|
521
|
-
| `string` | `FimoString` | `extends String` — **not** a primitive `string`
|
|
522
|
-
| `text` | `FimoString` | Multiline plain text with the same source tracking as `string`
|
|
523
|
-
| `richtext` | `FimoRichText` | Tiptap JSONContent + source metadata
|
|
524
|
-
| `boolean` | `FimoBoolean` | class; `.valueOf()` → `boolean`
|
|
525
|
-
| `media` | `FimoMedia` / `FimoMedia[]` | shape + rendering in `references/assets.md`
|
|
526
|
-
| `number` | `number` | plain — not wrapped
|
|
527
|
-
| `json` | `Record<string, any>` |
|
|
528
|
-
| `date` | `
|
|
529
|
-
| `
|
|
521
|
+
| Schema field type | Field value you get | Notes |
|
|
522
|
+
| ----------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
523
|
+
| `string` | `FimoString` | `extends String` — **not** a primitive `string` |
|
|
524
|
+
| `text` | `FimoString` | Multiline plain text with the same source tracking as `string` |
|
|
525
|
+
| `richtext` | `FimoRichText` | Tiptap JSONContent + source metadata |
|
|
526
|
+
| `boolean` | `FimoBoolean` | class; `.valueOf()` → `boolean` |
|
|
527
|
+
| `media` | `FimoMedia` / `FimoMedia[]` | shape + rendering in `references/assets.md` |
|
|
528
|
+
| `number` | `number` | plain — not wrapped. A wrapper would break `<span>{post.views}</span>` (React renders a boxed `String` directly but throws on a boxed `Number`), so it stays untracked and unclickable in the editing surfaces |
|
|
529
|
+
| `json` | `Record<string, any>` | the same shape you wrote, plus a hidden (non-enumerable, symbol-keyed) source tag — render with `<Json>`, see below |
|
|
530
|
+
| `date` | `FimoString` | same wrapper as `string`/`text`, **not** `FimoDate` — see below |
|
|
531
|
+
| `blocks` | array of plain objects | the array/objects themselves are plain; each item's own scalar fields are wrapped by their own field type (a nested `string` is still `FimoString`, a nested `number` stays a plain `number`, …) — see "Blocks" above |
|
|
532
|
+
| `reference` | `FimoReference` / `FimoReference[]` | reference object(s) with target `id`; use `populate` when embedded targets are needed |
|
|
530
533
|
|
|
531
534
|
Rules of thumb:
|
|
532
535
|
|
|
533
|
-
- **Pass the whole primitive to the matching `fimo/ui` component** — `<Text value={post.title} />`, `<Image value={post.cover} />`, `<RichText value={post.body} />`, `<Boolean value={p.inStock} />`. Don't unwrap first; the component reads the source metadata so the field stays inline-editable in the dashboard.
|
|
536
|
+
- **Pass the whole primitive to the matching `fimo/ui` component** — `<Text value={post.title} />`, `<Image value={post.cover} />`, `<RichText value={post.body} />`, `<Boolean value={p.inStock} />`, `<Date value={post.publishDate} />`, `<Json value={post.metadata} />`. Don't unwrap first; the component reads the source metadata so the field stays inline-editable in the dashboard.
|
|
534
537
|
- **`FimoString extends String`**, so `typeof post.title === 'object'` and `post.title === 'Hi'` is `false`. It stringifies fine inside JSX and template literals; call `.toString()` only when something genuinely needs a primitive `string`.
|
|
538
|
+
- **`number` fields are the one scalar type left unwrapped** — `post.views` is a plain `number`, so `{post.views}` renders directly in JSX, `typeof`/`===`/arithmetic all behave normally, and there is no `<Number>` component. This is deliberate, not a gap: wrapping it would break direct JSX rendering in every existing site.
|
|
539
|
+
- **`json` fields are a shallow clone of what you wrote**, tagged with a hidden source symbol — not the original object, and not a class instance. Reading it behaves exactly like plain JSON (`JSON.stringify` round-trips it unchanged; `for...in`/`Object.keys` see only your own keys). Render it with `<Json value={post.metadata} />` (default renders as a `<span>`; pass `as="pre"` for a formatted block, or a children render function for specific keys) so it stays inline-editable and live-updates in the dashboard preview like every other field.
|
|
535
540
|
- **Never hand-construct** a `FimoString` / `FimoMedia` / etc. — that bypasses source tracking. For a literal string use `t()`; for a literal image use `<StaticImage>`.
|
|
536
541
|
- `t()` also returns a `FimoString` (see `references/labels.md`).
|
|
537
542
|
|
|
@@ -553,7 +558,7 @@ class FimoBoolean {
|
|
|
553
558
|
}
|
|
554
559
|
```
|
|
555
560
|
|
|
556
|
-
> **`FimoDate`:** exported from `fimo/ui` (it's the `<Date>` component's value
|
|
561
|
+
> **`FimoDate`:** exported from `fimo/ui` (it's one of the `<Date>` component's accepted value types), but the generated schema client does **not** wrap `date` fields in it — a `date` field wraps as `FimoString` instead (see the table above), because the generated TypeScript type for a `date` field is `string`, and `FimoString` is what keeps that contract's string methods (`.slice()`, `.includes()`, …) working. `<Date value={post.someDate} />` accepts a `FimoString`, a `FimoDate`, a raw `Date`, or a raw string — all four render correctly.
|
|
557
562
|
|
|
558
563
|
## UI code pattern
|
|
559
564
|
|
|
@@ -579,7 +584,7 @@ export function BlogList() {
|
|
|
579
584
|
}
|
|
580
585
|
```
|
|
581
586
|
|
|
582
|
-
For the `<Text>` / `<RichText>` / `<Image>` / `<Date>` components and the rules of thumb, see `references/ui.md`.
|
|
587
|
+
For the `<Text>` / `<RichText>` / `<Image>` / `<Date>` / `<Json>` components and the rules of thumb, see `references/ui.md`.
|
|
583
588
|
|
|
584
589
|
## Read path (published app, no auth)
|
|
585
590
|
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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`
|
|
94
|
-
|
|
95
|
-
`@tanstack/react-query`
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
126
|
-
|
|
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:
|
|
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.
|
|
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
|
-
|
|
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
|
|
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:
|
|
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.
|
|
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
|
|
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
|
-
|
|
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`.
|
|
@@ -17,6 +17,7 @@ Use these to render content-type field values consistently. They carry source me
|
|
|
17
17
|
| `<Video>` | Schema `media` video fields | `<Video value={post.heroVideo} />` |
|
|
18
18
|
| `<Date>` | Schema date fields | `<Date value={post.publishDate} />` |
|
|
19
19
|
| `<Boolean>` | Schema boolean fields | `<Boolean value={product.inStock} />` |
|
|
20
|
+
| `<Json>` | Schema `json` fields | `<Json value={post.metadata} as="pre" />` |
|
|
20
21
|
| `` fimo`...` `` | Compose tracked values (mix `t()` + schema text) | ``<Text value={fimo`${t('by')} ${post.author}`} />`` |
|
|
21
22
|
| `useLabels()` | `t('key')` hook | see `references/labels.md` |
|
|
22
23
|
| `useLocale()` | Active locale and route locale metadata | see `references/locales.md` |
|
|
@@ -26,9 +27,10 @@ Use these to render content-type field values consistently. They carry source me
|
|
|
26
27
|
1. **Schema text → `<Text>`**, never `<h1>{post.title}</h1>`.
|
|
27
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.
|
|
28
29
|
3. **Non-schema images** (decorative, hard-coded URLs, generated assets referenced directly) → `<StaticImage>`. Never hand-construct a `FimoMedia` to feed `<Image>`.
|
|
29
|
-
4. **Label text → `<Text value={t('key')} />`**, not `<h1>{t(...)}</h1>`. Label values live in the DB for `i18n.defaultLocale` from
|
|
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
31
|
5. **Mixed schema + translated text** → the `` fimo`...` `` template literal inside `<Text>`.
|
|
31
32
|
6. **Never hand-roll richtext rendering** — always `<RichText>`. To restyle a node, pass `components={{ heading: ..., link: ..., ... }}`.
|
|
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.
|
|
32
34
|
|
|
33
35
|
## App code conventions
|
|
34
36
|
|
|
@@ -78,6 +80,7 @@ The template uses **Vite + React 19 + TypeScript + Tailwind v4 + shadcn/ui + rea
|
|
|
78
80
|
|
|
79
81
|
- Raw `<a href>` for internal nav → use `<FimoLink>` for locale-aware paths or React Router `<Link>` / `<NavLink>` only when intentionally bypassing Fimo locale helpers.
|
|
80
82
|
- Raw `<img>` for schema media → use `<Image>` (with width/height).
|
|
83
|
+
- Raw `<pre data-fimo-source={getFimoSource(...)}>` for schema `json` fields → use `<Json>`.
|
|
81
84
|
- Hardcoded strings in JSX → wrap in `t('key')` and add the DB value with `fimo labels set`.
|
|
82
85
|
- Calling `t()` with a dynamic first argument → key must be a string literal.
|
|
83
86
|
- Editing generated `.ts` files under `src/schemas/` or `src/forms/` → regenerate them through `fimo validate` or the matching push command.
|
|
@@ -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: [
|
|
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:
|
|
@@ -33,6 +39,14 @@ To halt the AI mid-generation, use the **Stop button** in the input bar — whil
|
|
|
33
39
|
|
|
34
40
|
While the AI works, you see small badges in the chat showing what it is doing. Each badge displays a tool name and its current status. Examples include reading files, writing code, searching your project, or generating images. These badges help you follow along without needing to understand the technical details.
|
|
35
41
|
|
|
42
|
+
## Reviewing Changes That Could Not Merge
|
|
43
|
+
|
|
44
|
+
Chat changes are prepared separately and then applied to the environment you are viewing. Most changes merge automatically.
|
|
45
|
+
|
|
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.
|
|
47
|
+
|
|
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.
|
|
49
|
+
|
|
36
50
|
## Tips for Better Results
|
|
37
51
|
|
|
38
52
|
- **Be specific**: Mention colors, layout, text content, and spacing when you can.
|
|
@@ -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
|
|
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
|
|
50
|
+
When the Preview workspace is open, the visual editor can appear alongside it as a preview side panel.
|
|
@@ -14,7 +14,13 @@ 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:**
|
|
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
|
+
|
|
19
|
+
## Publishing Changes That Need Review
|
|
20
|
+
|
|
21
|
+
If an AI chat change cannot merge automatically, use the response's **Review changes** card first. Resolve the conflicts and merge the proposal into `main`.
|
|
22
|
+
|
|
23
|
+
When the AI requested publication, the review dialog offers **Merge and publish** after the conflicts are resolved. Publishing starts only after the merge succeeds, so unresolved or discarded proposals never reach the live site.
|
|
18
24
|
|
|
19
25
|
## What You See When You Click Publish
|
|
20
26
|
|
|
@@ -23,6 +29,7 @@ The header **Publish** button itself only shows the label "Publish" (or a spinne
|
|
|
23
29
|
- **"Not published yet"** — Your site has never been published. The **Publish** button inside the panel is ready to click.
|
|
24
30
|
- **"Publishing"** — Publishing is in progress. A spinner and a **Publishing** status badge show while it builds, and the button is disabled.
|
|
25
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.
|
|
26
33
|
|
|
27
34
|
## Key Concepts
|
|
28
35
|
|