fimo 2.8.0-staging.9 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/assets/skills/fimo/SKILL.md +0 -1
  2. package/assets/skills/fimo-cli/SKILL.md +6 -7
  3. package/assets/skills/fimo-cli/references/assets.md +2 -0
  4. package/assets/skills/fimo-cli/references/deploy.md +1 -1
  5. package/assets/skills/fimo-cli/references/init.md +1 -2
  6. package/assets/skills/fimo-cli/references/integrations/firecrawl.md +1 -41
  7. package/assets/skills/fimo-cli/references/integrations.md +2 -38
  8. package/assets/skills/fimo-cli/references/knowledge.md +1 -1
  9. package/assets/skills/fimo-cli/references/mcp.md +5 -6
  10. package/assets/skills/fimo-cli/references/preview.md +1 -1
  11. package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +0 -16
  12. package/assets/skills/fimo-cli/references/webhooks.md +0 -2
  13. package/assets/skills/fimo-code/SKILL.md +1 -0
  14. package/assets/skills/fimo-code/references/assets.md +5 -5
  15. package/assets/skills/fimo-code/references/design.md +1 -1
  16. package/assets/skills/fimo-code/references/ui.md +1 -1
  17. package/assets/skills/fimo-studio/SKILL.md +6 -9
  18. package/assets/skills/fimo-studio/references/ai-chat.md +9 -4
  19. package/assets/skills/fimo-studio/references/billing-and-credits.md +2 -4
  20. package/assets/skills/fimo-studio/references/command-palette.md +0 -2
  21. package/assets/skills/fimo-studio/references/connections.md +2 -2
  22. package/assets/skills/fimo-studio/references/project-creation.md +5 -3
  23. package/assets/skills/fimo-studio/references/webhooks.md +3 -3
  24. package/dist/cli/bundle.json +2 -2
  25. package/dist/cli/index.js +153 -162
  26. package/dist/runtime/paths/get-fimo-paths.js +2 -24
  27. package/dist/runtime/project-layout.d.ts +0 -1
  28. package/dist/runtime/project-layout.js +1 -5
  29. package/dist/runtime/shared/local-runtime-env.js +2 -14
  30. package/package.json +10 -10
  31. package/release.json +2 -2
  32. package/templates/astro/.fimo/config.json +0 -14
  33. package/templates/astro/AGENTS.md +2 -1
  34. package/templates/astro/_gitignore +3 -0
  35. package/templates/astro/package.json +3 -3
  36. package/templates/astro/src/layouts/Base.astro +0 -48
  37. package/templates/nextjs/AGENTS.md +1 -1
  38. package/templates/nextjs/_gitignore +3 -0
  39. package/templates/nextjs/package.json +5 -5
  40. package/templates/react-router/AGENTS.md +1 -1
  41. package/templates/react-router/_gitignore +3 -0
  42. package/templates/react-router/package.json +5 -5
  43. package/templates/sveltekit/AGENTS.md +1 -0
  44. package/templates/sveltekit/_gitignore +3 -0
  45. package/templates/sveltekit/package.json +3 -3
  46. package/templates/vite/AGENTS.md +2 -0
  47. package/templates/vite/_gitignore +3 -0
  48. package/templates/vite/package.json +5 -5
  49. package/assets/agent-templates/_default/GOAL.md +0 -21
  50. package/assets/agent-templates/_default/capabilities.yaml +0 -11
  51. package/assets/agent-templates/_default/config.yaml +0 -13
  52. package/assets/agent-templates/broken-link-sweeper/GOAL.md +0 -51
  53. package/assets/agent-templates/broken-link-sweeper/capabilities.yaml +0 -1
  54. package/assets/agent-templates/broken-link-sweeper/config.yaml +0 -13
  55. package/assets/agent-templates/content-translator/GOAL.md +0 -33
  56. package/assets/agent-templates/content-translator/capabilities.yaml +0 -5
  57. package/assets/agent-templates/content-translator/config.yaml +0 -12
  58. package/assets/agent-templates/content-translator/scripts/translate-entries.ts +0 -69
  59. package/assets/agent-templates/post-deploy-check/GOAL.md +0 -23
  60. package/assets/agent-templates/post-deploy-check/capabilities.yaml +0 -1
  61. package/assets/agent-templates/post-deploy-check/config.yaml +0 -10
  62. package/assets/agent-templates/post-deploy-check/scripts/check-logs.ts +0 -39
  63. package/assets/agent-templates/post-deploy-check/scripts/probe-routes.ts +0 -53
  64. package/assets/agent-templates/seo-audit/GOAL.md +0 -43
  65. package/assets/agent-templates/seo-audit/capabilities.yaml +0 -3
  66. package/assets/agent-templates/seo-audit/config.yaml +0 -14
  67. package/assets/agent-templates/seo-audit/references/report-template.md +0 -28
  68. package/assets/agent-templates/seo-audit/references/scoring-methodology.md +0 -30
  69. package/assets/agent-templates/seo-audit/scripts/analyze-html.ts +0 -82
  70. package/assets/agent-templates/seo-audit/scripts/fetch-page.ts +0 -39
  71. package/assets/agent-templates/seo-audit/scripts/list-routes.ts +0 -46
  72. package/assets/agent-templates/seo-audit/scripts/report.ts +0 -82
  73. package/assets/agent-templates/seo-audit/scripts/score.ts +0 -131
  74. package/assets/skills/fimo-cli/references/agents.md +0 -298
  75. package/assets/skills/fimo-studio/references/agents.md +0 -33
  76. package/assets/skills/fimo-studio/references/drawing-and-wireframing.md +0 -61
  77. package/templates/astro/src/components/ProjectOverview.astro +0 -45
  78. package/templates/astro/src/pages/[locale]/projects/[slug].astro +0 -38
  79. package/templates/astro/src/pages/[locale]/projects/index.astro +0 -19
  80. package/templates/astro/src/pages/projects/[slug].astro +0 -31
  81. package/templates/astro/src/pages/projects/index.astro +0 -13
  82. package/templates/astro/src/schemas/Project.json +0 -9
  83. package/templates/astro/src/schemas/Project.ts +0 -29
  84. package/templates/astro/src/schemas/Project.types.ts +0 -70
  85. package/templates/astro/src/schemas/SiteSettings.json +0 -10
  86. package/templates/astro/src/schemas/SiteSettings.ts +0 -31
  87. package/templates/astro/src/schemas/SiteSettings.types.ts +0 -69
  88. package/templates/react-router/src/pages/Privacy.tsx +0 -79
  89. package/templates/react-router/src/pages/Terms.tsx +0 -48
  90. package/templates/react-router/src/pages/legal/LegalPage.tsx +0 -42
@@ -1,12 +1,10 @@
1
1
  // Resolve the list of paths a project should consider for prerender / sitemap /
2
2
  // robots / per-route SEO generation. Static paths come from .fimo/config.json;
3
3
  // dynamic routes are expanded by fetching schema entries from the content API.
4
- import { existsSync, readFileSync } from 'node:fs';
5
- import { resolve } from 'node:path';
6
4
  import { materializeRoutePath, resolveRouteContracts, routeLocaleTargets } from '../routes/index.js';
7
5
  import { resolveSeoForPath } from '../seo/resolver.js';
8
6
  import { getConfigServer } from '../shared/fimo-config.server.js';
9
- import { resolveLocalRuntimeEnv } from '../shared/local-runtime-env.js';
7
+ import { readLocalEnvFiles, resolveLocalRuntimeEnv } from '../shared/local-runtime-env.js';
10
8
  const isValidationBuild = !!process.env.FIMO_VALIDATION_BUILD;
11
9
  const MAX_FETCH_ATTEMPTS = 3;
12
10
  const RETRYABLE_FETCH_STATUSES = new Set([502, 503, 504]);
@@ -15,27 +13,7 @@ const RETRY_BASE_DELAY_MS = 250;
15
13
  // `meta.hasMore` says whether another page follows.
16
14
  const ENTRIES_PAGE_SIZE = 100;
17
15
  function readEnvValue(rootDir, key) {
18
- if (process.env[key]) {
19
- return process.env[key];
20
- }
21
- // `.env.local` first — every framework resolves it last, so it wins there
22
- // and must win here too.
23
- for (const file of ['.env.local', '.env']) {
24
- const filePath = resolve(rootDir, file);
25
- if (!existsSync(filePath)) {
26
- continue;
27
- }
28
- const line = readFileSync(filePath, 'utf-8')
29
- .split('\n')
30
- .find((l) => l.trim().startsWith(`${key}=`));
31
- if (line) {
32
- return line
33
- .slice(key.length + 1)
34
- .trim()
35
- .replace(/^['"]|['"]$/g, '');
36
- }
37
- }
38
- return undefined;
16
+ return process.env[key] || readLocalEnvFiles(rootDir)[key];
39
17
  }
40
18
  function resolveApiBaseUrl(rootDir) {
41
19
  return (readEnvValue(rootDir, 'VITE_API_URL') ??
@@ -2,7 +2,6 @@ export type ProjectLayout = 'current' | 'legacy';
2
2
  export interface ProjectLayoutPaths {
3
3
  readonly project: string;
4
4
  readonly config: string;
5
- readonly agents: string;
6
5
  }
7
6
  export declare const CURRENT_PROJECT_LAYOUT: ProjectLayoutPaths;
8
7
  export declare const LEGACY_PROJECT_LAYOUT: ProjectLayoutPaths;
@@ -1,12 +1,10 @@
1
1
  export const CURRENT_PROJECT_LAYOUT = {
2
2
  project: '.fimo/project.json',
3
3
  config: '.fimo/config.json',
4
- agents: '.fimo/agents',
5
4
  };
6
5
  export const LEGACY_PROJECT_LAYOUT = {
7
6
  project: '.fimo.settings.json',
8
7
  config: 'fimo-config.json',
9
- agents: 'agents',
10
8
  };
11
9
  export const LEGACY_AGENT_POLICY_PATH = 'fimo.config.json';
12
10
  export function detectProjectLayout(paths) {
@@ -18,9 +16,7 @@ export function detectProjectLayout(paths) {
18
16
  const file = input.replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/$/, '');
19
17
  hasCurrentProject || (hasCurrentProject = file === CURRENT_PROJECT_LAYOUT.project);
20
18
  hasLegacyProject || (hasLegacyProject = file === LEGACY_PROJECT_LAYOUT.project);
21
- hasCurrentMarker || (hasCurrentMarker = file === CURRENT_PROJECT_LAYOUT.config ||
22
- file === CURRENT_PROJECT_LAYOUT.agents ||
23
- file.startsWith(`${CURRENT_PROJECT_LAYOUT.agents}/`));
19
+ hasCurrentMarker || (hasCurrentMarker = file === CURRENT_PROJECT_LAYOUT.config);
24
20
  hasLegacyMarker || (hasLegacyMarker = file === LEGACY_PROJECT_LAYOUT.config || file === LEGACY_AGENT_POLICY_PATH);
25
21
  }
26
22
  if (hasCurrentProject) {
@@ -18,6 +18,7 @@
18
18
  import { execFileSync } from 'node:child_process';
19
19
  import fs from 'node:fs';
20
20
  import path from 'node:path';
21
+ import { parseEnv } from 'node:util';
21
22
  import { CURRENT_PROJECT_LAYOUT, LEGACY_PROJECT_LAYOUT } from '../project-layout.js';
22
23
  import { LOCAL_CONTENT_API_ENV_KEYS, buildLocalRuntimeEnv, buildTenantApiUrl, isValidBranch, } from './branch-identity.js';
23
24
  /**
@@ -97,20 +98,7 @@ export function readLocalEnvFiles(cwd) {
97
98
  if (!fs.existsSync(/* turbopackIgnore: true */ filePath)) {
98
99
  continue;
99
100
  }
100
- for (const line of fs.readFileSync(/* turbopackIgnore: true */ filePath, 'utf-8').split(/\r?\n/)) {
101
- const trimmed = line.trim();
102
- if (!trimmed || trimmed.startsWith('#')) {
103
- continue;
104
- }
105
- const eq = trimmed.indexOf('=');
106
- if (eq <= 0) {
107
- continue;
108
- }
109
- values[trimmed.slice(0, eq).trim()] = trimmed
110
- .slice(eq + 1)
111
- .trim()
112
- .replace(/^['"]|['"]$/g, '');
113
- }
101
+ Object.assign(values, parseEnv(fs.readFileSync(/* turbopackIgnore: true */ filePath, 'utf-8')));
114
102
  }
115
103
  return values;
116
104
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fimo",
3
- "version": "2.8.0-staging.9",
3
+ "version": "2.8.0",
4
4
  "description": "Fimo CLI - create, deploy, and manage Fimo sites",
5
5
  "keywords": [
6
6
  "astro-component"
@@ -194,13 +194,13 @@
194
194
  "devDependencies": {
195
195
  "@clack/core": "^1.2.0",
196
196
  "@clack/prompts": "^1.2.0",
197
- "@fimo/agents-bundle": "2.8.0-staging.9",
198
- "@fimo/api-contracts": "2.8.0-staging.9",
199
- "@fimo/cli-kit": "2.8.0-staging.9",
200
- "@fimo/framework-detect": "2.8.0-staging.9",
201
- "@fimo/routes": "2.8.0-staging.9",
202
- "@fimo/sdk": "2.8.0-staging.9",
203
- "@fimo/tsconfig": "2.8.0-staging.9",
197
+ "@fimo/agents-bundle": "2.8.0",
198
+ "@fimo/api-contracts": "2.8.0",
199
+ "@fimo/cli-kit": "2.8.0",
200
+ "@fimo/framework-detect": "2.8.0",
201
+ "@fimo/routes": "2.8.0",
202
+ "@fimo/sdk": "2.8.0",
203
+ "@fimo/tsconfig": "2.8.0",
204
204
  "@types/node": "22.18.6",
205
205
  "agent-install": "^0.0.5",
206
206
  "astro": "^7.1.6",
@@ -211,8 +211,8 @@
211
211
  "open": "^10.1.2",
212
212
  "tsx": "4.22.4",
213
213
  "typescript": "7.0.2",
214
- "vite": "8.3.3",
215
- "vitest": "5.0.3",
214
+ "vite": "8.3.4",
215
+ "vitest": "5.0.4",
216
216
  "wrangler": "4.145.0",
217
217
  "yaml": "2.8.2"
218
218
  },
package/release.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "source": "npm",
3
- "apiUrl": "https://api.staging.fimo.team",
4
- "webUrl": "https://staging.fimo.team"
3
+ "apiUrl": "https://api.fimo.ai",
4
+ "webUrl": "https://fimo.ai"
5
5
  }
@@ -9,20 +9,6 @@
9
9
  "label": "Home",
10
10
  "path": "/:locale",
11
11
  "params": { "locale": { "type": "locale", "optional": true } }
12
- },
13
- "projects": {
14
- "label": "Projects",
15
- "path": "/:locale/projects",
16
- "params": { "locale": { "type": "locale", "optional": true } }
17
- },
18
- "project": {
19
- "label": "Project",
20
- "path": "/:locale/projects/:slug",
21
- "seo": { "title": "{{project.title}}", "description": "{{project.summary}}" },
22
- "params": {
23
- "locale": { "type": "locale", "optional": true },
24
- "slug": { "schema": "Project", "queryField": "slug", "displayField": "title" }
25
- }
26
12
  }
27
13
  },
28
14
  "version": "4"
@@ -33,10 +33,11 @@ a code-only task, or use `npx fimo@latest` for project-local code generation and
33
33
  - Keep `.fimo/config.json#routes` as Studio metadata aligned with Astro's page files. It does not configure Astro routing.
34
34
  - Astro owns routes, locale resolution, links and SEO. Base.astro resolves the actual path with `resolveSeoForPath` and renders `toSeoHead` from `fimo/seo`. Content pages pass already-resolved `seo` with their route data. Keep title/social tags in agreement and preserve the app's canonical policy.
35
35
  - Use generated schema clients, `getLabels({ locale })`, and native components from `fimo/astro/components` for editable values.
36
+ - Image and video files go to the media library with `fimo assets upload`, never into `public/` or `src/assets/` (favicons and the scaffold's own logos excepted).
36
37
  - Do not add React or a second deployment platform.
37
38
  - Never edit `.fimo/project.json`; it links this directory to the remote project.
38
39
  - Keep `.fimo/config.json#runtime` true to the code: framework, `dev`/`build`/`install` commands, output directory. Update it when you rename a package script, move the build output, or change framework; the reference is `fimo skills get fimo-code --ref frameworks/hosting`.
39
40
  - Keep secrets in the Fimo dashboard, not committed environment files.
40
41
  - Pass flags to interactive Fimo commands when scripting them.
41
42
 
42
- The scaffolded pages and content models are disposable. Replace them when building the requested site.
43
+ The scaffolded homepage is disposable. Replace it on the first real generation.
@@ -13,3 +13,6 @@ dist/
13
13
  .env
14
14
  .env.*
15
15
  !.env.example
16
+
17
+ # Fimo local credentials
18
+ .fimo/*.local.json
@@ -9,9 +9,9 @@
9
9
  "check": "astro sync && astro check"
10
10
  },
11
11
  "dependencies": {
12
- "fimo": "2.8.0-staging.9",
13
- "fimo-analytics": "2.8.0-staging.9",
14
- "fimo-astro": "2.8.0-staging.9",
12
+ "fimo": "2.8.0",
13
+ "fimo-analytics": "2.8.0",
14
+ "fimo-astro": "2.8.0",
15
15
  "zod": "^4.4.3"
16
16
  },
17
17
  "devDependencies": {
@@ -51,52 +51,4 @@ const head = toSeoHead({
51
51
  body {
52
52
  margin: 0;
53
53
  }
54
-
55
- main {
56
- box-sizing: border-box;
57
- width: min(100% - 3rem, 52rem);
58
- min-height: 100vh;
59
- margin: 0 auto;
60
- padding: 4rem 0;
61
- }
62
-
63
- nav,
64
- header,
65
- section,
66
- article {
67
- display: grid;
68
- gap: 0.75rem;
69
- }
70
-
71
- nav {
72
- grid-auto-flow: column;
73
- justify-content: start;
74
- margin-bottom: 4rem;
75
- }
76
-
77
- section {
78
- margin-top: 3rem;
79
- }
80
-
81
- article {
82
- padding: 1.5rem 0;
83
- border-top: 1px solid #d6d3cc;
84
- }
85
-
86
- h1,
87
- h2,
88
- p {
89
- margin: 0;
90
- }
91
-
92
- h1 {
93
- max-width: 16ch;
94
- font-size: clamp(2.75rem, 9vw, 5rem);
95
- line-height: 0.95;
96
- letter-spacing: -0.05em;
97
- }
98
-
99
- a {
100
- color: inherit;
101
- }
102
54
  </style>
@@ -21,7 +21,7 @@ a code-only task, or use `npx fimo@latest` for project-local code generation and
21
21
 
22
22
  - **Content**: declare a schema, push it, use its generated client, and render with `fimo-next` or `fimo-next/client`.
23
23
  - **Strings**: use labels and `t('key')`.
24
- - **Media**: use the active framework adapter's `Image` / `Video` primitives.
24
+ - **Media**: use the active framework adapter's `Image` / `Video` primitives. Image and video files go to the media library with `fimo assets upload`, never into `public/` (favicons and the scaffold's own logos excepted).
25
25
  - **Forms**: use the generated Zod schema and submit helper.
26
26
 
27
27
  The scaffolded homepage is disposable. Replace it on the first real generation.
@@ -15,3 +15,6 @@ next-env.d.ts
15
15
  .env
16
16
  .env.*
17
17
  !.env.example
18
+
19
+ # Fimo local credentials
20
+ .fimo/*.local.json
@@ -12,11 +12,11 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@tanstack/react-query": "^5.80.6",
15
- "fimo": "2.8.0-staging.9",
16
- "fimo-analytics": "2.8.0-staging.9",
17
- "fimo-next": "2.8.0-staging.9",
18
- "fimo-react": "2.8.0-staging.9",
19
- "next": "^16.3.8",
15
+ "fimo": "2.8.0",
16
+ "fimo-analytics": "2.8.0",
17
+ "fimo-next": "2.8.0",
18
+ "fimo-react": "2.8.0",
19
+ "next": "16.3.8",
20
20
  "react": "^19.2.7",
21
21
  "react-dom": "^19.2.7",
22
22
  "zod": "^4.4.3"
@@ -28,7 +28,7 @@ breaks that. Load `fimo-code` for the exact primitives, but the rule is:
28
28
 
29
29
  - **Content** → declare a schema, use its generated client, and render with the active framework adapter. Never `const posts = [...]` in JSX.
30
30
  - **Strings** → `t('key')` + `fimo labels set`. Never `<h1>Welcome</h1>`.
31
- - **Media** → `<Image>` / `<Video>` from the active framework adapter. Never `<img src>` for tracked media.
31
+ - **Media** → `<Image>` / `<Video>` from the active framework adapter. Never `<img src>` for tracked media. Image and video files go to the media library with `fimo assets upload`, never into `public/` or `src/assets/` (favicons and the scaffold's own logos excepted).
32
32
  - **Forms** → the generated Zod schema + `submitX` helper. Never hand-roll fetch/validation.
33
33
 
34
34
  ## Development loop
@@ -15,3 +15,6 @@ build/
15
15
  .env
16
16
  .env.*
17
17
  !.env.example
18
+
19
+ # Fimo local credentials
20
+ .fimo/*.local.json
@@ -21,11 +21,11 @@
21
21
  "cn": "0.2.4",
22
22
  "date-fns": "^4.1.0",
23
23
  "embla-carousel-react": "^8.6.0",
24
- "fimo": "2.8.0-staging.9",
25
- "fimo-analytics": "2.8.0-staging.9",
26
- "fimo-react": "2.8.0-staging.9",
27
- "fimo-react-router": "2.8.0-staging.9",
28
- "fimo-vite": "2.8.0-staging.9",
24
+ "fimo": "2.8.0",
25
+ "fimo-analytics": "2.8.0",
26
+ "fimo-react": "2.8.0",
27
+ "fimo-react-router": "2.8.0",
28
+ "fimo-vite": "2.8.0",
29
29
  "input-otp": "^1.4.2",
30
30
  "isbot": "^5",
31
31
  "lucide-react": "^0.577.0",
@@ -33,6 +33,7 @@ a code-only task, or use `npx fimo@latest` for project-local code generation and
33
33
  - Keep the document language request-aware: `src/hooks.server.ts` renders the initial `<html lang>`, and the root layout updates it after client navigation.
34
34
  - Keep `.fimo/config.json#routes` as Studio metadata aligned with SvelteKit's route files. It does not configure SvelteKit routing.
35
35
  - The application owns routes, locale resolution, links and SEO. Return final `seoHead` from route loads using `resolveSeoForPath` and `toSeoHead` from `fimo/seo`. The root renders `page.data.seoHead` once. Content pages supply route data; do not add competing page head tags. Check client navigation for stale tags.
36
+ - Image and video files go to the media library with `fimo assets upload`, never into `static/` or `src/lib/assets/` (favicons and the scaffold's own logos excepted).
36
37
  - Do not add a second deployment platform.
37
38
  - Never edit `.fimo/project.json`; it links this directory to the remote project.
38
39
  - Keep `.fimo/config.json#runtime` true to the code: framework, `dev`/`build`/`install` commands, output directory. Update it when you rename a package script, move the build output, or change framework; the reference is `fimo skills get fimo-code --ref frameworks/hosting`.
@@ -14,3 +14,6 @@ build/
14
14
  .env
15
15
  .env.*
16
16
  !.env.example
17
+
18
+ # Fimo local credentials
19
+ .fimo/*.local.json
@@ -11,9 +11,9 @@
11
11
  "prepare": "svelte-kit sync"
12
12
  },
13
13
  "dependencies": {
14
- "fimo": "2.8.0-staging.9",
15
- "fimo-analytics": "2.8.0-staging.9",
16
- "fimo-sveltekit": "2.8.0-staging.9",
14
+ "fimo": "2.8.0",
15
+ "fimo-analytics": "2.8.0",
16
+ "fimo-sveltekit": "2.8.0",
17
17
  "zod": "^4.4.3"
18
18
  },
19
19
  "devDependencies": {
@@ -27,6 +27,8 @@ fimo`, or `bunx --no-install fimo` when the project uses that package manager.
27
27
 
28
28
  - Use Fimo schemas and generated clients for content, labels for editable strings, Fimo primitives for media, and
29
29
  generated form helpers for submissions. Load `fimo-code` for their current APIs.
30
+ - Image and video files go to the media library with `fimo assets upload`, never into `public/` or `src/assets/`
31
+ (favicons and the scaffold's own logos excepted).
30
32
  - The scaffolded homepage is disposable. Replace it when building the requested site.
31
33
  - Treat the user's language request as part of setup. The first explicitly requested locale is the primary locale.
32
34
  Load `fimo skills get fimo-cli --ref locales` and use `fimo locales` to configure the exact locale set and default.
@@ -11,3 +11,6 @@ dist/
11
11
  .env
12
12
  .env.*
13
13
  !.env.example
14
+
15
+ # Fimo local credentials
16
+ .fimo/*.local.json
@@ -11,11 +11,11 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@tanstack/react-query": "^5.80.6",
14
- "fimo": "2.8.0-staging.9",
15
- "fimo-analytics": "2.8.0-staging.9",
16
- "fimo-react": "2.8.0-staging.9",
17
- "fimo-react-router": "2.8.0-staging.9",
18
- "fimo-vite": "2.8.0-staging.9",
14
+ "fimo": "2.8.0",
15
+ "fimo-analytics": "2.8.0",
16
+ "fimo-react": "2.8.0",
17
+ "fimo-react-router": "2.8.0",
18
+ "fimo-vite": "2.8.0",
19
19
  "react": "^19.2.7",
20
20
  "react-dom": "^19.2.7",
21
21
  "react-router": "^8.3.0",
@@ -1,21 +0,0 @@
1
- # Agent goal
2
-
3
- Describe what this agent should do. The whole of GOAL.md is the agent's
4
- prompt — there's no frontmatter or structured fields, just plain English.
5
-
6
- Some good things to include:
7
-
8
- - The end state you want when the agent succeeds
9
- - Inputs the agent should expect (CLI args, files, API responses)
10
- - Anything the agent should **not** do
11
- - The format of the report / output the agent should produce
12
-
13
- ## Decision policy
14
-
15
- Adapt these defaults to the risk and scope of this agent:
16
-
17
- - Proceed without asking when the work is within scope and a safe, reversible choice exists.
18
- - Ask when a missing human decision changes what the correct result should be.
19
- - Keep work open and request review when a human decision or approval is needed.
20
- - Merge completed, verified work within scope when runtime:auto_merge is granted; otherwise request human review.
21
- - Discard when the run produced no useful changes or deliberately abandoned them.
@@ -1,11 +0,0 @@
1
- - cms:*
2
- - assets:*
3
- - i18n:*
4
- - forms:*
5
- - webhooks:read
6
- - schedules:read
7
- - fimo:analytics:read
8
- - fimo:history:read
9
- - fimo:logs:read
10
- - fimo:preview:read
11
- - runtime:auto_merge
@@ -1,13 +0,0 @@
1
- # Minimum-viable config. Add triggers / composition / data_sources as needed.
2
- # See https://fimo.dev/docs/agents/bundle for the full reference.
3
- version: 1
4
- description: 'A new Fimo agent. Edit this tagline to describe what it does.'
5
- model: openai/gpt-5.6-luna
6
-
7
- runtime:
8
- # Per-run spend limit in credits. Remove to allow up to the
9
- # organization's available balance at admission.
10
- max_credits: 5000
11
-
12
- triggers:
13
- - type: manual
@@ -1,51 +0,0 @@
1
- # Broken-link sweeper
2
-
3
- Crawl the project's published site once a week, find every broken link
4
- (404s on internal routes, dead external destinations), classify them by
5
- the page they live on, and propose a per-page fix on its own branch.
6
-
7
- ## Inputs
8
-
9
- - The project's `sitemap.xml`, fetched from the published origin.
10
- - Each page's HTML, fetched fresh on every run.
11
- - The project's analytics (read-only) — used to rank which pages to
12
- triage first when the broken-link count is large.
13
-
14
- ## What to do
15
-
16
- 1. Fetch `sitemap.xml` and enumerate the canonical URL set.
17
- 2. For each URL, fetch the HTML and collect every `<a href>` plus every
18
- `<link rel="canonical">` and every `<img src>` target.
19
- 3. Classify each link:
20
- - **internal-404** — same-origin route that returns 4xx.
21
- - **external-dead** — third-party host that returns 4xx/5xx or
22
- times out after a reasonable retry.
23
- - **internal-redirect** — internal route that 301s to a different
24
- path (worth flagging, not always worth fixing).
25
- 4. Group findings by the source page that contains them.
26
- 5. For each affected page, open a fresh branch off `main` and commit a
27
- draft fix:
28
- - **internal-404** → propose a route alias or update the link to the
29
- closest live route (if the analytics show traffic to the dead path,
30
- prefer the alias; otherwise update in place).
31
- - **external-dead** → remove the link and replace its anchor text
32
- with plain text, leaving a TODO comment for a human to revisit.
33
- - **internal-redirect** → update the link to the canonical target.
34
- 6. Open one `agent_branch_proposal` per affected page so the owner can
35
- review each batch independently.
36
-
37
- ## What to produce
38
-
39
- - One branch per affected page, named `agent/broken-links/<page-slug>`.
40
- - One proposal per branch summarising the findings and the fix.
41
- - A single run report at `reports/broken-links-<YYYY-MM-DD>.md` with
42
- the overall counts, the top 5 dead external destinations, and a
43
- trend footer (`<!-- agent-summary: ... -->`) for diffing across
44
- runs.
45
-
46
- ## What NOT to do
47
-
48
- - Don't merge any branch — every fix goes through human review.
49
- - Don't follow `noindex` or `disallow`'d routes; respect the project's
50
- robots policy.
51
- - Don't fetch a URL more than once per run, and back off on 5xx.
@@ -1 +0,0 @@
1
- - fimo:analytics:read
@@ -1,13 +0,0 @@
1
- version: 1
2
- description: 'Crawl the published site and flag broken outbound links in a weekly report.'
3
- model: openai/gpt-5.6-luna
4
-
5
- runtime:
6
- cloud: true
7
- max_credits: 5000
8
-
9
- triggers:
10
- - type: manual
11
- - type: schedule
12
- cron: '0 4 * * MON'
13
- tz: UTC
@@ -1,33 +0,0 @@
1
- # Content translator
2
-
3
- Translate CMS entries and DB-backed labels from the project's default
4
- locale into every non-default locale declared in `.fimo/config.json`.
5
- Writes go through Fimo's content and label APIs. Do not create locale
6
- JSON files or put translated values in source code.
7
-
8
- ## Inputs
9
-
10
- - The list of CMS entries that have a non-empty default-locale field
11
- but an empty translation for any non-default locale.
12
- - The configured target locales (read from `.fimo/config.json`).
13
-
14
- ## What to do
15
-
16
- For each entry:
17
-
18
- 1. Read the default-locale field via `cms:read`.
19
- 2. Translate to every missing locale.
20
- 3. Write the translation back to the matching locale entry via `cms:write`.
21
- 4. For static UI labels, update values with the i18n/labels API rather
22
- than editing files.
23
-
24
- ## What NOT to do
25
-
26
- - Don't translate fields that the entry's schema marks `translate: false`.
27
- - Don't overwrite an existing translation, even if it looks lower quality.
28
-
29
- ## v1.x note
30
-
31
- Cloud-time activation of this agent requires
32
- `agents.notifications.email_recipients` to be non-empty (per ADR-0009).
33
- Add at least one address before deploying, or the cloud trigger stays unwired.
@@ -1,5 +0,0 @@
1
- # Reads CMS and writes DB-backed localized content / labels.
2
- - cms:read
3
- - cms:write
4
- - i18n:read
5
- - i18n:write
@@ -1,12 +0,0 @@
1
- version: 1
2
- description: 'Translate CMS content into the project locales whenever an entry is published.'
3
- model: openai/gpt-5.6-luna
4
- data_sources:
5
- - main
6
-
7
- # Trigger on every CMS publish event. The runtime debounces — multiple
8
- # publishes within ~30s collapse into a single agent run.
9
- triggers:
10
- - type: manual
11
- - type: event
12
- event: cms.publish
@@ -1,69 +0,0 @@
1
- /**
2
- * Tool: translate-entries
3
- *
4
- * Walk every default-locale CMS entry, find missing non-default-locale
5
- * document rows, call the configured translation provider, and write back
6
- * through the Fimo API. Skips fields marked `translate: false` in the schema.
7
- *
8
- * Provider is configured via env (FIMO_AGENT_TRANSLATE_PROVIDER) — the
9
- * runtime threads project secrets through when the v1.x secrets API
10
- * lands. For now this template uses the OpenAI fallback.
11
- */
12
-
13
- interface Entry {
14
- id: string;
15
- documentId: string;
16
- locale: string;
17
- type: string;
18
- data: Record<string, unknown>;
19
- }
20
-
21
- interface TranslateOptions {
22
- fromLocale: string;
23
- toLocales: string[];
24
- api: { base: string; projectId: string; env: string };
25
- }
26
-
27
- async function listMissing(_opts: TranslateOptions): Promise<Entry[]> {
28
- // Stub — wired to the Fimo API by the runtime. Returns entries with
29
- // at least one missing target-locale document row while the default-locale
30
- // row is populated.
31
- return [];
32
- }
33
-
34
- async function translate(text: string, _to: string): Promise<string> {
35
- // Stub — call the configured provider. Returns the translated string.
36
- return text;
37
- }
38
-
39
- async function writeBack(_entry: Entry, _locale: string, _value: string): Promise<void> {
40
- // Stub — create/update the target locale entry via
41
- // `/api/tenant/:projectId/branches/:branch/entries/:type`.
42
- }
43
-
44
- async function main(): Promise<void> {
45
- const fromLocale = process.env.FIMO_DEFAULT_LOCALE ?? 'en';
46
- const toLocales = (process.env.FIMO_TARGET_LOCALES ?? '').split(',').filter(Boolean);
47
- const api = {
48
- base: process.env.FIMO_API_URL ?? 'http://localhost:3000',
49
- projectId: process.env.FIMO_PROJECT_ID ?? '',
50
- env: process.env.FIMO_ENV ?? 'main',
51
- };
52
-
53
- const entries = await listMissing({ fromLocale, toLocales, api });
54
- for (const entry of entries) {
55
- for (const locale of toLocales) {
56
- const sourceValue = typeof entry.data.title === 'string' ? entry.data.title : undefined;
57
- if (!sourceValue) {
58
- continue;
59
- }
60
- const translated = await translate(sourceValue, locale);
61
- await writeBack(entry, locale, translated);
62
- }
63
- }
64
- }
65
-
66
- main().catch((err) => {
67
- console.error(err);
68
- process.exit(1);
69
- });