fimo 2.8.0-staging.8 → 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.
- package/assets/skills/fimo/SKILL.md +0 -1
- package/assets/skills/fimo-cli/SKILL.md +6 -7
- package/assets/skills/fimo-cli/references/assets.md +2 -0
- package/assets/skills/fimo-cli/references/deploy.md +1 -1
- package/assets/skills/fimo-cli/references/init.md +1 -2
- package/assets/skills/fimo-cli/references/integrations/firecrawl.md +1 -41
- package/assets/skills/fimo-cli/references/integrations.md +2 -38
- package/assets/skills/fimo-cli/references/knowledge.md +1 -1
- package/assets/skills/fimo-cli/references/mcp.md +5 -6
- package/assets/skills/fimo-cli/references/preview.md +1 -1
- package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +0 -16
- package/assets/skills/fimo-cli/references/webhooks.md +0 -2
- package/assets/skills/fimo-code/SKILL.md +1 -0
- package/assets/skills/fimo-code/references/assets.md +5 -5
- package/assets/skills/fimo-code/references/design.md +1 -1
- package/assets/skills/fimo-code/references/ui.md +1 -1
- package/assets/skills/fimo-studio/SKILL.md +13 -7
- package/assets/skills/fimo-studio/references/ai-chat.md +15 -2
- package/assets/skills/fimo-studio/references/billing-and-credits.md +4 -6
- package/assets/skills/fimo-studio/references/cms.md +1 -1
- package/assets/skills/fimo-studio/references/command-palette.md +1 -2
- package/assets/skills/fimo-studio/references/connections.md +3 -4
- package/assets/skills/fimo-studio/references/custom-domains.md +2 -2
- package/assets/skills/fimo-studio/references/media-library.md +1 -2
- package/assets/skills/fimo-studio/references/preview-and-responsive.md +4 -9
- package/assets/skills/fimo-studio/references/project-creation.md +24 -6
- package/assets/skills/fimo-studio/references/publish-and-deploy.md +2 -2
- package/assets/skills/fimo-studio/references/schedules.md +2 -3
- package/assets/skills/fimo-studio/references/seo-settings.md +2 -2
- package/assets/skills/fimo-studio/references/sharing-and-collaboration.md +2 -3
- package/assets/skills/fimo-studio/references/visual-editing.md +1 -1
- package/assets/skills/fimo-studio/references/webhooks.md +7 -8
- package/dist/cli/bundle.json +2 -2
- package/dist/cli/index.js +153 -162
- package/dist/runtime/paths/get-fimo-paths.js +2 -24
- package/dist/runtime/project-layout.d.ts +0 -1
- package/dist/runtime/project-layout.js +1 -5
- package/dist/runtime/shared/local-runtime-env.js +2 -14
- package/dist/runtime/templates.d.ts +0 -1
- package/dist/runtime/templates.js +0 -3
- package/package.json +10 -10
- package/release.json +2 -2
- package/templates/astro/.fimo/config.json +0 -14
- package/templates/astro/AGENTS.md +2 -1
- package/templates/astro/_gitignore +3 -0
- package/templates/astro/package.json +3 -3
- package/templates/astro/src/layouts/Base.astro +0 -48
- package/templates/nextjs/AGENTS.md +1 -1
- package/templates/nextjs/_gitignore +3 -0
- package/templates/nextjs/package.json +5 -5
- package/templates/react-router/AGENTS.md +1 -1
- package/templates/react-router/_gitignore +3 -0
- package/templates/react-router/package.json +5 -5
- package/templates/sveltekit/AGENTS.md +1 -0
- package/templates/sveltekit/_gitignore +3 -0
- package/templates/sveltekit/package.json +3 -3
- package/templates/vite/AGENTS.md +2 -0
- package/templates/vite/_gitignore +3 -0
- package/templates/vite/package.json +5 -5
- package/assets/agent-templates/_default/GOAL.md +0 -21
- package/assets/agent-templates/_default/capabilities.yaml +0 -11
- package/assets/agent-templates/_default/config.yaml +0 -13
- package/assets/agent-templates/broken-link-sweeper/GOAL.md +0 -51
- package/assets/agent-templates/broken-link-sweeper/capabilities.yaml +0 -1
- package/assets/agent-templates/broken-link-sweeper/config.yaml +0 -13
- package/assets/agent-templates/content-translator/GOAL.md +0 -33
- package/assets/agent-templates/content-translator/capabilities.yaml +0 -5
- package/assets/agent-templates/content-translator/config.yaml +0 -12
- package/assets/agent-templates/content-translator/scripts/translate-entries.ts +0 -69
- package/assets/agent-templates/post-deploy-check/GOAL.md +0 -23
- package/assets/agent-templates/post-deploy-check/capabilities.yaml +0 -1
- package/assets/agent-templates/post-deploy-check/config.yaml +0 -10
- package/assets/agent-templates/post-deploy-check/scripts/check-logs.ts +0 -39
- package/assets/agent-templates/post-deploy-check/scripts/probe-routes.ts +0 -53
- package/assets/agent-templates/seo-audit/GOAL.md +0 -43
- package/assets/agent-templates/seo-audit/capabilities.yaml +0 -3
- package/assets/agent-templates/seo-audit/config.yaml +0 -14
- package/assets/agent-templates/seo-audit/references/report-template.md +0 -28
- package/assets/agent-templates/seo-audit/references/scoring-methodology.md +0 -30
- package/assets/agent-templates/seo-audit/scripts/analyze-html.ts +0 -82
- package/assets/agent-templates/seo-audit/scripts/fetch-page.ts +0 -39
- package/assets/agent-templates/seo-audit/scripts/list-routes.ts +0 -46
- package/assets/agent-templates/seo-audit/scripts/report.ts +0 -82
- package/assets/agent-templates/seo-audit/scripts/score.ts +0 -131
- package/assets/skills/fimo-cli/references/agents.md +0 -298
- package/assets/skills/fimo-studio/references/agents.md +0 -33
- package/assets/skills/fimo-studio/references/drawing-and-wireframing.md +0 -61
- package/templates/astro/src/components/ProjectOverview.astro +0 -45
- package/templates/astro/src/pages/[locale]/projects/[slug].astro +0 -38
- package/templates/astro/src/pages/[locale]/projects/index.astro +0 -19
- package/templates/astro/src/pages/projects/[slug].astro +0 -31
- package/templates/astro/src/pages/projects/index.astro +0 -13
- package/templates/astro/src/schemas/Project.json +0 -9
- package/templates/astro/src/schemas/Project.ts +0 -29
- package/templates/astro/src/schemas/Project.types.ts +0 -70
- package/templates/astro/src/schemas/SiteSettings.json +0 -10
- package/templates/astro/src/schemas/SiteSettings.ts +0 -31
- package/templates/astro/src/schemas/SiteSettings.types.ts +0 -69
- package/templates/react-router/src/pages/Privacy.tsx +0 -79
- package/templates/react-router/src/pages/Terms.tsx +0 -48
- package/templates/react-router/src/pages/legal/LegalPage.tsx +0 -42
- package/templates/welcome/manifest.json +0 -655
- package/templates/welcome/media/analytics-overview.avif +0 -0
- package/templates/welcome/media/autonomous-loop.avif +0 -0
- package/templates/welcome/media/editable-preview.avif +0 -0
- package/templates/welcome/media/media-library.avif +0 -0
- package/templates/welcome/media/slack-teams.avif +0 -0
- package/templates/welcome/template/.fimo/agents/welcome-guide/GOAL.md +0 -12
- package/templates/welcome/template/.fimo/agents/welcome-guide/capabilities.yaml +0 -3
- package/templates/welcome/template/.fimo/agents/welcome-guide/config.yaml +0 -8
- package/templates/welcome/template/.fimo/config.json +0 -52
- package/templates/welcome/template/src/font.css +0 -60
- package/templates/welcome/template/src/pages/ArticleDetail.tsx +0 -104
- package/templates/welcome/template/src/pages/Index.tsx +0 -36
- package/templates/welcome/template/src/pages/SiteContent.tsx +0 -674
- package/templates/welcome/template/src/pages/fallback-content.ts +0 -152
- package/templates/welcome/template/src/routes.ts +0 -9
- package/templates/welcome/template/src/schemas/Article.json +0 -34
- package/templates/welcome/template/src/schemas/Article.ts +0 -54
- package/templates/welcome/template/src/schemas/Article.types.ts +0 -93
- package/templates/welcome/template/src/schemas/Author.json +0 -17
- package/templates/welcome/template/src/schemas/Author.ts +0 -51
- package/templates/welcome/template/src/schemas/Author.types.ts +0 -54
- package/templates/welcome/template/src/schemas/Category.json +0 -17
- package/templates/welcome/template/src/schemas/Category.ts +0 -51
- package/templates/welcome/template/src/schemas/Category.types.ts +0 -54
- package/templates/welcome/template/src/schemas/HomePage.json +0 -110
- package/templates/welcome/template/src/schemas/HomePage.ts +0 -22
- package/templates/welcome/template/src/schemas/HomePage.types.ts +0 -116
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tool: score
|
|
3
|
-
*
|
|
4
|
-
* Apply the SEO scoring methodology (see references/scoring-methodology.md)
|
|
5
|
-
* to a list of `(path, SEOSignals)` tuples and produce a per-page report.
|
|
6
|
-
*
|
|
7
|
-
* Inputs (stdin JSON): { signals: Record<path, SEOSignals> }
|
|
8
|
-
* Outputs (stdout JSON): { score: 0..100, pages: PageReport[] }
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
interface SEOSignals {
|
|
12
|
-
title: string | null;
|
|
13
|
-
description: string | null;
|
|
14
|
-
canonical: string | null;
|
|
15
|
-
robots: string | null;
|
|
16
|
-
openGraph: Record<string, string>;
|
|
17
|
-
schemaOrg: unknown[];
|
|
18
|
-
headings: { h1: string[]; h2: string[]; h3: string[] };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface Finding {
|
|
22
|
-
rule: string;
|
|
23
|
-
severity: 'ok' | 'warn' | 'fail';
|
|
24
|
-
message: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface PageReport {
|
|
28
|
-
path: string;
|
|
29
|
-
score: number;
|
|
30
|
-
findings: Finding[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function audit(signals: SEOSignals): Finding[] {
|
|
34
|
-
const out: Finding[] = [];
|
|
35
|
-
|
|
36
|
-
// Title
|
|
37
|
-
if (!signals.title) {
|
|
38
|
-
out.push({ rule: 'title-present', severity: 'fail', message: 'Missing <title>' });
|
|
39
|
-
} else if (signals.title.length < 30 || signals.title.length > 60) {
|
|
40
|
-
out.push({
|
|
41
|
-
rule: 'title-length',
|
|
42
|
-
severity: 'warn',
|
|
43
|
-
message: `Title length ${signals.title.length} chars — recommend 30–60`,
|
|
44
|
-
});
|
|
45
|
-
} else {
|
|
46
|
-
out.push({ rule: 'title', severity: 'ok', message: 'Title looks good' });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Description
|
|
50
|
-
if (!signals.description) {
|
|
51
|
-
out.push({ rule: 'description-present', severity: 'fail', message: 'Missing meta description' });
|
|
52
|
-
} else if (signals.description.length < 50 || signals.description.length > 160) {
|
|
53
|
-
out.push({
|
|
54
|
-
rule: 'description-length',
|
|
55
|
-
severity: 'warn',
|
|
56
|
-
message: `Description length ${signals.description.length} chars — recommend 50–160`,
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// OG tags
|
|
61
|
-
for (const key of ['title', 'description', 'image', 'url']) {
|
|
62
|
-
if (!signals.openGraph[key]) {
|
|
63
|
-
out.push({ rule: `og-${key}`, severity: 'warn', message: `Missing og:${key}` });
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Headings
|
|
68
|
-
if (signals.headings.h1.length === 0) {
|
|
69
|
-
out.push({ rule: 'h1-present', severity: 'fail', message: 'No <h1> on the page' });
|
|
70
|
-
} else if (signals.headings.h1.length > 1) {
|
|
71
|
-
out.push({ rule: 'h1-single', severity: 'warn', message: `Multiple <h1> tags (${signals.headings.h1.length})` });
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Canonical
|
|
75
|
-
if (!signals.canonical) {
|
|
76
|
-
out.push({ rule: 'canonical', severity: 'warn', message: 'Missing canonical link' });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Robots
|
|
80
|
-
if (signals.robots && /noindex/i.test(signals.robots)) {
|
|
81
|
-
out.push({ rule: 'robots-noindex', severity: 'fail', message: 'Page is marked noindex' });
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Schema.org
|
|
85
|
-
if (signals.schemaOrg.length === 0) {
|
|
86
|
-
out.push({ rule: 'schema-org', severity: 'warn', message: 'No JSON-LD schema.org block' });
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return out;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function scoreOf(findings: Finding[]): number {
|
|
93
|
-
// Each fail = -15, each warn = -5. Floor at 0.
|
|
94
|
-
let pts = 100;
|
|
95
|
-
for (const f of findings) {
|
|
96
|
-
if (f.severity === 'fail') {
|
|
97
|
-
pts -= 15;
|
|
98
|
-
} else if (f.severity === 'warn') {
|
|
99
|
-
pts -= 5;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return Math.max(0, pts);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
async function readStdin(): Promise<string> {
|
|
106
|
-
const chunks: Buffer[] = [];
|
|
107
|
-
for await (const chunk of process.stdin) {
|
|
108
|
-
chunks.push(Buffer.from(chunk));
|
|
109
|
-
}
|
|
110
|
-
return Buffer.concat(chunks).toString('utf8');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function main(): Promise<void> {
|
|
114
|
-
const text = await readStdin();
|
|
115
|
-
const payload = JSON.parse(text) as { signals: Record<string, SEOSignals> };
|
|
116
|
-
|
|
117
|
-
const pages: PageReport[] = [];
|
|
118
|
-
for (const [path, signals] of Object.entries(payload.signals)) {
|
|
119
|
-
const findings = audit(signals);
|
|
120
|
-
pages.push({ path, score: scoreOf(findings), findings });
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const overall = pages.length === 0 ? 0 : Math.round(pages.reduce((a, p) => a + p.score, 0) / pages.length);
|
|
124
|
-
|
|
125
|
-
process.stdout.write(JSON.stringify({ score: overall, pages }, null, 2));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
main().catch((err) => {
|
|
129
|
-
console.error(err);
|
|
130
|
-
process.exit(1);
|
|
131
|
-
});
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
# Agents workflow (`fimo agents *`)
|
|
2
|
-
|
|
3
|
-
The `fimo agents` namespace authors and operates **agent bundles** — multi-file definitions under `<project>/.fimo/agents/<name>/` (a `config.yaml`, a `GOAL.md`, optional `capabilities.yaml`, etc.). Legacy projects keep using root `agents/<name>/`.
|
|
4
|
-
|
|
5
|
-
## Mental model
|
|
6
|
-
|
|
7
|
-
The namespace splits cleanly in two:
|
|
8
|
-
|
|
9
|
-
- **Bundle authoring** — `create`, `list-templates`, `list`, `validate`, `secrets add/remove/list`. Local config editing, no API call except the project-level validation path. Operates on the files under `.fimo/agents/<name>/` (or root `agents/<name>/` for legacy projects).
|
|
10
|
-
- **Cloud ops** — `run`, `runs`, `report`. Branch-aware, talk to the server. Default `--branch` is `main`; `--env` is rejected as a Branch selector. `--project` defaults to the linked project in `.fimo/project.json` or legacy `.fimo.settings.json`.
|
|
11
|
-
|
|
12
|
-
The bundle lives in **git** (`.fimo/agents/<name>/`, or legacy root `agents/<name>/`), not the database. The DB only mirrors what `config.yaml` declares on `main` (which triggers are wired) plus **run sessions**. So the bundle reaches the server through `fimo deploy` — and that push to `main` is also what wires its triggers. There is no activate command: deploying IS the enablement act, and removing a trigger from `config.yaml` tears it down on the next deploy.
|
|
13
|
-
|
|
14
|
-
Typical flow:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
fimo agents create <name> # scaffold .fimo/agents/<name>/ from a template (local)
|
|
18
|
-
fimo agents secrets add <name> FIRECRAWL_API_KEY # request a project secret in config.yaml
|
|
19
|
-
fimo secrets add FIRECRAWL_API_KEY --stdin # store the hidden value in Fimo
|
|
20
|
-
fimo agents validate <name> # parse + policy + composition + requested secrets
|
|
21
|
-
fimo validate # project build and codegen checks
|
|
22
|
-
fimo deploy # push to main — this also wires the declared triggers
|
|
23
|
-
fimo agents run <name> # trigger a manual run → sessionId
|
|
24
|
-
fimo agents runs <name> # see past sessions
|
|
25
|
-
fimo agents report <name> # print a run's outcome summary
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Bundle authoring (local)
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
fimo agents list-templates
|
|
32
|
-
fimo agents create <name> [--template <t>] [--description <text>] [--quiet] [-C <dir>]
|
|
33
|
-
fimo agents list [-C <dir>]
|
|
34
|
-
fimo agents validate [name] [--json] [-C <dir>]
|
|
35
|
-
fimo agents secrets list <name> [--json] [-C <dir>]
|
|
36
|
-
fimo agents secrets add <name> <KEY> [-C <dir>]
|
|
37
|
-
fimo agents secrets remove <name> <KEY> [-C <dir>]
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
- **`list-templates`** — list the bundled starter templates with the first line of each template's `GOAL.md` as a summary. Ships with the CLI binary; no API call. The five bundled templates are `_default`, `seo-audit`, `content-translator`, `broken-link-sweeper`, `post-deploy-check`.
|
|
41
|
-
- **`create <name>`** — scaffold `.fimo/agents/<name>/` from a template (default `_default`, a minimal valid bundle with a manual trigger). `--description <text>` writes a one-line tagline into the scaffolded `config.yaml` (surfaces in the dashboard's agents list). When run **without** `-C`, it requires the cwd to be inside a real Fimo site (walks up for `.fimo/project.json` or legacy `.fimo.settings.json`) and errors out cleanly otherwise, so it never leaks an agent bundle into a stray cwd. If the template declares capabilities, an install-consent flow runs after the copy (`--quiet` skips it; critical caps still abort). Keep the scaffolded `runtime` block as is unless the author asks for a different credit limit; see the `runtime` reference below before adding any limit key.
|
|
42
|
-
- Every generated `config.yaml` includes `model: openai/gpt-5.6-luna`. Change that top-level value to another supported Fimo text model when needed; bundles without `model` keep the Luna fallback. Deploy after changing it because cloud runs use the deployed bundle.
|
|
43
|
-
- **`list`** — list the agents declared under `<project>/.fimo/agents/` (or legacy root `agents/`), with each one's trigger types and capability count. Local — the bundle list is the source of truth even if the project isn't linked yet.
|
|
44
|
-
- **`validate [name]`** — run the full validation pipeline: parse → capability vocabulary → composition (cycle / missing sub-agents / invalid grants) → semantic + Fimo site config policy checks. Omit `name` to validate every bundle. `--json` emits a structured `ValidationReport` for CI; exit code is non-zero on any failure.
|
|
45
|
-
- **`secrets add/remove/list`** — edit or inspect the agent's requested secret names in `.fimo/agents/<name>/config.yaml` (or legacy root). These commands do not create, rotate, or reveal secret values. Store values with `fimo secrets add`; run `fimo agents validate` to check that required requested secrets exist in the project. See `references/project-vars-and-secrets.md`.
|
|
46
|
-
- **`integrations <name>`** — preview the agent's `integrations` allowlist from `.fimo/agents/<name>/config.yaml` (or legacy root) and, when linked, overlay project integration status. See `references/integrations.md`.
|
|
47
|
-
|
|
48
|
-
Agent integration access is configured in `.fimo/agents/<name>/config.yaml` (or legacy root). Enable the integration there; omit `tools` to allow all tools that integration exposes, or add a `tools` map to keep the agent on a smaller set:
|
|
49
|
-
|
|
50
|
-
```yaml
|
|
51
|
-
integrations:
|
|
52
|
-
firecrawl:
|
|
53
|
-
enabled: true
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
An explicit map is restrictive: only entries set to `true` are available. An omitted or disabled integration cannot be
|
|
57
|
-
used. See `references/integrations.md` for project setup, auth, and provider-specific commands.
|
|
58
|
-
|
|
59
|
-
Declare a `runtime` block in `config.yaml` to gate where a bundle runs and bound what one run costs:
|
|
60
|
-
|
|
61
|
-
```yaml
|
|
62
|
-
runtime:
|
|
63
|
-
cloud: true
|
|
64
|
-
dev: false
|
|
65
|
-
max_credits: 5000
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
- `cloud` / `dev` — declared boolean environment flags for where the bundle may run.
|
|
69
|
-
- `max_credits` — the run's own credit ceiling (integer, credits ≥ 1) and the one limit to tune. The default scaffold
|
|
70
|
-
template ships `max_credits: 5000` as a visible starter limit; raise, lower, or remove it to fit the agent's work.
|
|
71
|
-
Unset: the run may spend up to the organization's available credits at admission.
|
|
72
|
-
- `max_steps` — advanced cost-management knob, extremely rare: a cap on model-loop steps for one run (integer ≥ 1).
|
|
73
|
-
Leave it unset unless the author explicitly wants a step-based bound on top of credits. Do not add it when
|
|
74
|
-
scaffolding a bundle, and do not reach for it to control spend — tune `max_credits` instead. Unset: no step cap;
|
|
75
|
-
`max_credits` (or the organization's balance) and the plan's agent-hours bound the run.
|
|
76
|
-
|
|
77
|
-
All four keys are optional; an absent `runtime` block behaves as if every key were unset. There is no platform step cap
|
|
78
|
-
and no platform per-run cost ceiling — the only stops are these author-owned limits, the organization running out of
|
|
79
|
-
credits (`insufficient_credits`), and the agent-hours allowance. A limit that fires records a truthful terminal reason
|
|
80
|
-
(`max_steps`, `budget_exceeded`, or `insufficient_credits`), readable via `fimo agents report` and the Studio run page.
|
|
81
|
-
|
|
82
|
-
## How a cloud run ends
|
|
83
|
-
|
|
84
|
-
Runs perform compute; explicit work sessions hold project changes. Ordinary conversation and research need no session.
|
|
85
|
-
Project operations name their session. Save accumulated work before a risky operation or handoff. A confirmed save
|
|
86
|
-
commits and pushes without merging or publishing; Fimo also attempts a bounded save when compute ends.
|
|
87
|
-
|
|
88
|
-
Merge ready work explicitly. Resolve clear conflicts through the existing merge tools; ask when the resolution requires
|
|
89
|
-
product intent. Request review with one sessionId; request_review saves current work itself and makes that same session visible and durable. Inspecting or leaving a session open creates no review.
|
|
90
|
-
Discard only unwanted work within the requested scope. Ending a run does none of these operations implicitly.
|
|
91
|
-
|
|
92
|
-
The autonomous `report` tool records a structured report without ending compute or deciding session fate. The model may
|
|
93
|
-
continue working after reporting. A normal model stop ends compute. Scheduled work has no implicit publication grant.
|
|
94
|
-
|
|
95
|
-
The run report is a concise outcome summary: what changed, what was verified, and what is still blocked. It is not a
|
|
96
|
-
chronological account, and it should not use decorative emoji.
|
|
97
|
-
|
|
98
|
-
## Define the agent's decision policy
|
|
99
|
-
|
|
100
|
-
When authoring or editing an agent, add a short **Decision policy** to its `GOAL.md`. Describe the domain conditions for
|
|
101
|
-
acting, asking, review, and merge; do not copy Fimo's tool protocol. Use this shape and replace the examples with rules
|
|
102
|
-
specific to the agent:
|
|
103
|
-
|
|
104
|
-
Infer the intended autonomy from the user's request when it is clear. Otherwise ask what the agent may apply itself,
|
|
105
|
-
what needs review, and whether it may publish. Record that policy in `GOAL.md`; do not impose review-first on every
|
|
106
|
-
agent or treat permission to merge as permission to publish. A routine fixer and a proposal writer need different policies.
|
|
107
|
-
|
|
108
|
-
```md
|
|
109
|
-
## Decision policy
|
|
110
|
-
|
|
111
|
-
- Proceed without asking when the work is within scope and a safe, reversible choice exists.
|
|
112
|
-
- Ask when a missing human decision changes what the correct result should be.
|
|
113
|
-
- Request review of the saved session when completed work needs a person's approval before merge.
|
|
114
|
-
- Request merge only when the result is complete, verified, and clearly safe for this agent's scope.
|
|
115
|
-
- Discard when the run produced no useful changes or deliberately abandoned them.
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
`ask_user` requests a blocking decision and ends the current invocation. `request_review` saves and captures one selected session for approval
|
|
119
|
-
without ending compute. Neither operation merges or discards sessions.
|
|
120
|
-
|
|
121
|
-
Make those rules concrete enough that the agent can decide without guessing. For example:
|
|
122
|
-
|
|
123
|
-
- **Broken-link sweeper:** fix and request merge for up to ten internal links when each replacement is unambiguous and
|
|
124
|
-
the link check passes. Ask when two plausible destinations change the page's meaning. Retain useful fixes if complete
|
|
125
|
-
verification is blocked. Discard when the scan is clean or exploratory edits were reverted.
|
|
126
|
-
- **Launch-copy agent:** draft from an approved brief without asking about routine wording. Ask before choosing pricing,
|
|
127
|
-
product promises, brand direction, or deletions. Retain every completed draft for human review; never request merge.
|
|
128
|
-
- **Read-only auditor:** inspect and report autonomously. Ask only when the requested scope cannot be inferred.
|
|
129
|
-
- **Missing capability:** ask once for the exact capability and explain which operation it unlocks. Do not retain partial
|
|
130
|
-
work as a substitute for the blocking permission decision.
|
|
131
|
-
|
|
132
|
-
A review-first content agent could use this complete policy:
|
|
133
|
-
|
|
134
|
-
```md
|
|
135
|
-
## Decision policy
|
|
136
|
-
|
|
137
|
-
- Draft all requested copy without asking when the brief and approved source material answer the content decisions.
|
|
138
|
-
- Ask before inventing a price, product promise, legal claim, brand direction, or deleting existing content.
|
|
139
|
-
- Group every blocking decision and missing capability into one question.
|
|
140
|
-
- Retain every completed draft so a person reviews all changes before merge. Never request merge directly.
|
|
141
|
-
- Discard only when no useful draft was produced or the attempted approach was fully abandoned.
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
When a run cannot continue correctly without a decision from a project member, it may call `ask_user` instead. Fimo
|
|
145
|
-
emails project members a link to answer it in Studio, and the current invocation ends. It can reference zero or more
|
|
146
|
-
sessions. An authorized answer starts a continuation in the same thread; the referenced work stays open and the original
|
|
147
|
-
model process does not wait.
|
|
148
|
-
|
|
149
|
-
Use `ask_user` sparingly, especially from scheduled agents:
|
|
150
|
-
|
|
151
|
-
- Ask only for a genuinely blocking human decision. Prefer a safe reversible default when one exists.
|
|
152
|
-
- Group every known blocker into one form with 1–4 related steps. Give it a 1–3 sentence description that says where
|
|
153
|
-
the work stands and why the decision matters or what it unlocks; keep implementation detail in the run.
|
|
154
|
-
- Use choices for compact text options. Use cards only when an option benefits from an image or a richer title and
|
|
155
|
-
subtitle. Use assets when the image itself is the answer, and tables when options need the same structured comparison.
|
|
156
|
-
- Do not repeat a question or request already waiting in prior run history.
|
|
157
|
-
- Use `request_review` with one sessionId when approval is needed. No pre-save or promotion is required; other sessions stay unchanged and work can continue.
|
|
158
|
-
|
|
159
|
-
An agent may include one multi-select `capabilities` step in that same form to request public Fimo capabilities it does
|
|
160
|
-
not currently hold. Group related tokens in one request. Selected tokens apply only to the continuation started by that
|
|
161
|
-
answer; unselected tokens are denied, selecting none is valid, and the blocked invocation never gains new authority.
|
|
162
|
-
Internal runtime abilities, integration setup, and OAuth are not capability requests.
|
|
163
|
-
|
|
164
|
-
At the start of a run, `run_history` provides bounded summaries of earlier outcomes and work still awaiting a person. An agent
|
|
165
|
-
may also maintain `.fimo/agents/<name>/MEMORY.md` as an ordinary reviewed file for durable facts that change future
|
|
166
|
-
behavior. Keep it under 4 KB, record no secrets or run log, and prune stale entries before adding new ones.
|
|
167
|
-
|
|
168
|
-
When three or more earlier runs still await a question answer, review, conflict resolution, or recovery, the agent
|
|
169
|
-
normally starts no new independent work. Unless the current trigger explicitly asks it to proceed anyway, it makes no
|
|
170
|
-
changes and records a brief report of what is waiting.
|
|
171
|
-
|
|
172
|
-
## Define reporting preferences when they matter
|
|
173
|
-
|
|
174
|
-
Fimo's default report needs no setup: a short, scannable brief appears in email, while the full report in Fimo carries
|
|
175
|
-
the organized evidence and depth. Do not add a reporting section merely to restate that default.
|
|
176
|
-
|
|
177
|
-
When the user names an audience, depth, recurring comparison, required section, or useful visual, preserve the request
|
|
178
|
-
in a short **Reporting** section of `GOAL.md`. Describe the communication outcome in ordinary language. Do not prescribe
|
|
179
|
-
report block arrays or promise that the full report will appear in email.
|
|
180
|
-
|
|
181
|
-
Examples for different jobs:
|
|
182
|
-
|
|
183
|
-
```md
|
|
184
|
-
## Reporting
|
|
185
|
-
|
|
186
|
-
Write the brief for a marketing lead. Lead with the outcome and at most three decisions or risks. Keep implementation
|
|
187
|
-
evidence in the full report.
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
```md
|
|
191
|
-
## Reporting
|
|
192
|
-
|
|
193
|
-
Compare this week with the previous four weeks. Use a graph only when the change over time is part of the conclusion,
|
|
194
|
-
and include the complete channel breakdown in the full report.
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
```md
|
|
198
|
-
## Reporting
|
|
199
|
-
|
|
200
|
-
Show enough of each created article to judge its voice, then link to the draft. Preserve the complete copy and editorial
|
|
201
|
-
decisions in the full report.
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
These are preferences, not templates. Keep the default brief short and scannable unless the user asks for a different
|
|
205
|
-
audience or emphasis. Even then, the brief remains the external handoff and the full report holds the supporting depth.
|
|
206
|
-
|
|
207
|
-
## Capabilities
|
|
208
|
-
|
|
209
|
-
Capabilities describe the opt-in Fimo actions an agent may take. Managed agents always receive project filesystem
|
|
210
|
-
access, a shell, the ability to commit their task-environment changes, and web and data tools; Fimo owns branch creation
|
|
211
|
-
and publication. If `capabilities.yaml` is absent or empty, the agent keeps baseline project reads such as agent run
|
|
212
|
-
history, but receives no CMS, asset, or other domain-operation scope. Once you add a capabilities file, list every Fimo
|
|
213
|
-
permission the agent needs. `net:fetch` is no longer needed and is ignored.
|
|
214
|
-
Namespace selectors such as `cms:*`, `assets:*`, `i18n:*`, and `forms:*` grant every current and future declarable capability
|
|
215
|
-
in that namespace. Fimo expands selectors to concrete grants when a run starts. Use exact tokens for narrower agents.
|
|
216
|
-
The default template includes those four selectors plus read access to analytics, deployment logs, history, previews,
|
|
217
|
-
webhooks, and schedules; remove entries when an agent should have less access.
|
|
218
|
-
|
|
219
|
-
| Capability | Allows the agent to | Risk |
|
|
220
|
-
| ------------------------------------------- | ------------------------------------------------------------------------- | ------------ |
|
|
221
|
-
| `cms:read` | Read CMS content | Low |
|
|
222
|
-
| `cms:write` | Create, update, or delete CMS entries | Medium |
|
|
223
|
-
| `cms:schema:read` | Read CMS schemas | Low |
|
|
224
|
-
| `cms:schema:write` | Modify CMS schemas | High |
|
|
225
|
-
| `assets:read` | Read uploaded media | Low |
|
|
226
|
-
| `assets:write` | Upload, replace, or delete media | Medium |
|
|
227
|
-
| `i18n:read` / `i18n:write` | Read / modify translation catalogs | Low / Medium |
|
|
228
|
-
| `cms:*` / `assets:*` / `i18n:*` / `forms:*` | Every declarable capability in that namespace, including future additions | Mixed |
|
|
229
|
-
| `forms:read` / `forms:write` | Read / modify form schemas and submissions | Low / Medium |
|
|
230
|
-
| `webhooks:read` | Read webhook configs and deliveries | Low |
|
|
231
|
-
| `webhooks:write` | Create, modify, delete, or trigger webhooks | High |
|
|
232
|
-
| `schedules:read` | Read schedule configs and run history | Low |
|
|
233
|
-
| `schedules:write` | Create, change, or trigger scheduled runs | Critical |
|
|
234
|
-
| `fimo:logs:read` | Read project deployment logs | Low |
|
|
235
|
-
| `fimo:analytics:read` | Read analytics data | Low |
|
|
236
|
-
| `fimo:preview:read` | Read a current preview URL | Low |
|
|
237
|
-
| `fimo:history:read` | Read project restore points | Low |
|
|
238
|
-
| `fimo:deploy` | Trigger a production deploy | Critical |
|
|
239
|
-
| `agent:delegate` | Invoke declared sub-agents | Medium |
|
|
240
|
-
| `runtime:auto_merge` | Merge work sessions without per-change review | Critical |
|
|
241
|
-
|
|
242
|
-
If a public Fimo capability is missing and the work is genuinely blocked, the agent can request it through `ask_user`.
|
|
243
|
-
Fimo grants only the selected subset to the next invocation in that run thread. Unknown capabilities, internal runtime
|
|
244
|
-
abilities, and capabilities the run already holds are refused before the question is stored. For durable access on
|
|
245
|
-
ordinary future runs, add the capability to `capabilities.yaml`, validate, and deploy the bundle.
|
|
246
|
-
|
|
247
|
-
Managed agents can list project agents and read their run history through baseline site access. This does not
|
|
248
|
-
require `fimo:agents:run`; that capability is only required to dispatch another agent.
|
|
249
|
-
|
|
250
|
-
Studio chat and project-bound Slack turns receive `fimo:logs:read`. The default autonomous-agent template now declares
|
|
251
|
-
it too; custom templates still need to declare it before using `fimo logs` to diagnose a failed preview.
|
|
252
|
-
|
|
253
|
-
Example for a content editor that can read and update entries but cannot change schemas:
|
|
254
|
-
|
|
255
|
-
```yaml
|
|
256
|
-
- cms:read
|
|
257
|
-
- cms:write
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## Cloud ops (Branch-aware)
|
|
261
|
-
|
|
262
|
-
```bash
|
|
263
|
-
fimo agents run <name> [--branch <branch>] [--project <id>] [--skip-drift-check] [-C <dir>]
|
|
264
|
-
fimo agents runs <name> [--limit <n>] [--cursor <cursor>] [--all-pages] [--branch <branch>] [--project <id>] [-C <dir>]
|
|
265
|
-
fimo agents report <name> [--session <id>] [--branch <branch>] [--project <id>] [-C <dir>]
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
- **`run <name>`** — fire the agent's `manual` trigger on the server; prints a `sessionId` on success. A refusal you must act on exits **1** with a stable code (`--json` puts it in `error.code`, and the raw server reason in `error.details.skipped`):
|
|
269
|
-
|
|
270
|
-
| Code | Means | Fix |
|
|
271
|
-
| --------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------- |
|
|
272
|
-
| `AGENT_NOT_DEPLOYED` | no bundle for this agent on `main` | `fimo deploy` |
|
|
273
|
-
| `AGENT_CONFIG_INVALID` | the deployed bundle does not parse, so the sync registered none of its triggers | `fimo agents validate <name>`, fix, `fimo deploy` |
|
|
274
|
-
| `NO_MANUAL_TRIGGER` | the deployed `config.yaml` really declares no `manual` trigger | add `- type: manual`, `fimo deploy` |
|
|
275
|
-
| `MANUAL_TRIGGER_NOT_SYNCED` | `main` declares it, the background sync has not registered it yet | wait a few seconds, retry |
|
|
276
|
-
| `TRIGGER_NOT_WIRED` | registered but not live (see the wiring note below) | `fimo agents list` for the reason |
|
|
277
|
-
| `INSUFFICIENT_CREDITS` | the org is under the credit floor a run needs | `fimo credits` |
|
|
278
|
-
|
|
279
|
-
A refusal that clears on its own (`agent-paused`, `run-in-progress`, `task-branch-budget`) exits **0** and prints `Dispatch was skipped: <reason>`. **Pre-flight drift check**: if `.fimo/agents/<name>/` (or the legacy root bundle) has uncommitted git changes, the command refuses — the server would dispatch the _deployed_ version, so deploy first. Pass `--skip-drift-check` to dispatch the deployed bundle anyway. Defaults `--branch` to `main`.
|
|
280
|
-
|
|
281
|
-
- **`runs <name>`** — list past run sessions for the agent in a compact table (id, started, duration, status, trigger, Branch, credits — settled credit consumption, `—` until a run settles). Default `--limit 20`; `--branch` filters to one Branch. The response uses the canonical `branch` field.
|
|
282
|
-
- **`report <name>`** — print a run's structured **report**: its durable outcome summary (for a read-only agent like `seo-audit` this _is_ the audit; for a write agent it's a "what I changed" summary). A run that returns plain text without calling `report` receives a small structured fallback document. With no `--session`, the most recent run for `<name>` is used (combine with `--branch` to scope); `--session <id>` targets a specific run. Output is projected Markdown, so it stays readable in the terminal and pipes cleanly (e.g. `fimo agents report seo-audit | glow`). If the run hasn't finished, or produced no report, it says so (and shows the stop reason when there is one).
|
|
283
|
-
|
|
284
|
-
## How triggers get wired
|
|
285
|
-
|
|
286
|
-
Agents are not Branch-scoped: they belong to the project, are read from `main`, and their triggers are global. Studio shows the deployed main agents on every Branch. When the selected Branch contains a new bundle that is not on main yet, Studio also shows it as disabled and explains that it becomes available after merge. Its triggers remain inactive until the bundle reaches main.
|
|
287
|
-
|
|
288
|
-
Pushing `.fimo/agents/<name>/config.yaml` (or a legacy root bundle) to `main` is the whole enablement act — `fimo deploy` does it. The server reconciles the file into its trigger rows on every push: a `schedule` trigger gets a cron, a `webhook` trigger gets its path, and `manual` becomes runnable. Removing a trigger from the file deletes it (cron torn down, path released) on the next deploy; deleting the agent's directory removes the whole deployment.
|
|
289
|
-
|
|
290
|
-
Cloud triggers (`schedule` / `webhook`) additionally require `notifications.email_recipients` in `.fimo/config.json` (legacy root `fimo-config.json` and `fimo.config.json` are also accepted). Without it the trigger is recorded but deliberately left **unwired** and will not fire — `fimo agents validate` warns about this before you deploy, and the Studio agents view shows the reason afterwards.
|
|
291
|
-
|
|
292
|
-
## `-C, --cwd <dir>`
|
|
293
|
-
|
|
294
|
-
Every `fimo agents` command accepts `-C, --cwd <dir>` to point at a different project directory. For the cloud-ops commands, `--project <id>` overrides the project id otherwise read from `.fimo/project.json` or legacy `.fimo.settings.json`.
|
|
295
|
-
|
|
296
|
-
## Non-interactive use
|
|
297
|
-
|
|
298
|
-
No `fimo agents` command prompts — authoring and cloud ops both run unattended.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Agents
|
|
2
|
-
|
|
3
|
-
Site agents are versioned bundles from the site's repository. Studio lets site members inspect their configuration and run history, while site managers can start, stop, resume, and delete them.
|
|
4
|
-
|
|
5
|
-
## Open an agent
|
|
6
|
-
|
|
7
|
-
1. Open the site and choose **Agents**.
|
|
8
|
-
2. Select **Agents** again to see the available bundles.
|
|
9
|
-
3. Choose an agent to open its **Runs** and **Settings** tabs.
|
|
10
|
-
|
|
11
|
-
On a user Branch, the list also shows new bundles that exist only on that Branch. Their cards are disabled; open one to see that the agent and its triggers become available after the Branch is merged into main.
|
|
12
|
-
|
|
13
|
-
When the agent has a live schedule, its next run appears first in **Runs**, marked **Scheduled**. The row uses **Next** for its projected ID, a relative date such as **Tomorrow at 11:00 AM**, and **—** for changes and duration until it starts. **Settings** shows the bundle's declared capabilities and trigger wiring; it is read-only because the repository remains the source of truth.
|
|
14
|
-
|
|
15
|
-
## Run, stop, or resume
|
|
16
|
-
|
|
17
|
-
Choose **Run** to start an agent whose manual trigger is live.
|
|
18
|
-
|
|
19
|
-
Choose **Stop** to pause every future trigger and stop planned or running work. Studio asks for confirmation and explains that the bundle, trigger configuration, model, capabilities, and other settings are preserved.
|
|
20
|
-
|
|
21
|
-
A stopped agent shows **Paused** in the header. **Resume** makes the same triggers live again with their previous settings.
|
|
22
|
-
|
|
23
|
-
Only site managers see Run, Stop, and Resume. Other site members can still see schedule timing, status, settings, and run history.
|
|
24
|
-
|
|
25
|
-
## Delete an agent
|
|
26
|
-
|
|
27
|
-
Site managers can open **Agent actions** beside Run/Stop, choose **Delete agent**, and confirm. Deletion stops planned or running work and commits removal of the agent bundle from `main`. Recorded runs remain in history. Remove the bundle from a local checkout before deploying again, or that deployment recreates the agent.
|
|
28
|
-
|
|
29
|
-
If a run cannot be stopped or `main` changes before deletion commits, the definition stays intact and the agent may remain paused. Reload and retry, or resume it if you want to keep it.
|
|
30
|
-
|
|
31
|
-
## Inspect runs
|
|
32
|
-
|
|
33
|
-
Open **Runs** on an agent to see only that bundle's history. Select a run to read its status, report, captured changes, and any question or review state that needs attention.
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
## Opening the Drawing Tool
|
|
2
|
-
|
|
3
|
-
Inside an existing site, open the wireframe canvas from the chat attachment dropdown: click the add-attachments (**+**) button next to the chat input, then choose **Draw**. (This option is hidden on mobile.)
|
|
4
|
-
|
|
5
|
-
Selecting **Draw** opens a large drawing canvas powered by Excalidraw, displayed in a centered dialog.
|
|
6
|
-
|
|
7
|
-
## Toolbar Basics
|
|
8
|
-
|
|
9
|
-
Across the top of the canvas you will find these tools:
|
|
10
|
-
|
|
11
|
-
- **Hand** -- pan around the canvas without selecting anything.
|
|
12
|
-
- **Select** -- select and move elements.
|
|
13
|
-
- **Rectangle** -- draw rectangular shapes.
|
|
14
|
-
- **Diamond** -- draw diamond shapes.
|
|
15
|
-
- **Ellipse** -- draw circles and ovals.
|
|
16
|
-
- **Arrow** -- draw arrows to show flow or connections.
|
|
17
|
-
- **Line** -- draw straight lines.
|
|
18
|
-
- **Draw (freehand)** -- draw anything by hand for quick annotations or custom shapes.
|
|
19
|
-
- **Text** -- click anywhere to add labels like "Header", "Hero Image", or "Sign Up Button".
|
|
20
|
-
- **Image** -- insert an image onto the canvas.
|
|
21
|
-
|
|
22
|
-
Pick a tool, draw on the canvas, and switch tools as needed. Zoom ranges from 10% to 300%.
|
|
23
|
-
|
|
24
|
-
## Component Library
|
|
25
|
-
|
|
26
|
-
The canvas comes with a library panel of **pre-made UI wireframe components**:
|
|
27
|
-
|
|
28
|
-
- Buttons, input fields, and form elements.
|
|
29
|
-
- Cards, containers, and navigation bars.
|
|
30
|
-
- Common layout blocks you would find on a typical website.
|
|
31
|
-
|
|
32
|
-
Drag any component from the library onto the canvas to use it. They are meant to be building blocks, so mix and match freely.
|
|
33
|
-
|
|
34
|
-
## Sketching Tips
|
|
35
|
-
|
|
36
|
-
You do not need to be an artist. The AI is good at interpreting rough layouts:
|
|
37
|
-
|
|
38
|
-
- Draw **boxes with text labels** for each section (Header, Hero, Features, Footer).
|
|
39
|
-
- Use **arrows** to show flow or relationships between elements.
|
|
40
|
-
- Indicate approximate **sizing and placement** -- a tall box for a sidebar, a wide box for a hero banner.
|
|
41
|
-
- Rough shapes and simple labels are enough. Pixel-perfect drawings are not necessary.
|
|
42
|
-
|
|
43
|
-
## Attaching Your Drawing
|
|
44
|
-
|
|
45
|
-
When you are happy with your sketch:
|
|
46
|
-
|
|
47
|
-
1. Click **Attach drawing**.
|
|
48
|
-
2. The canvas is exported as an image and added to your message.
|
|
49
|
-
3. The AI uses your wireframe as a visual guide alongside any text you write.
|
|
50
|
-
|
|
51
|
-
## Clearing the Canvas
|
|
52
|
-
|
|
53
|
-
Click the **clear canvas** button to start fresh. A confirmation dialog appears before clearing to prevent accidental loss.
|
|
54
|
-
|
|
55
|
-
Your work is retained while you close and reopen the canvas within the same session, so you can step away and come back to it. It is cleared once you attach the drawing, and it is not persisted across page reloads or navigating away from the site.
|
|
56
|
-
|
|
57
|
-
## Getting the Best Results
|
|
58
|
-
|
|
59
|
-
- **Combine a wireframe with a text description.** Tell the AI what each section should contain and how you want it styled. The wireframe handles layout; the text handles details.
|
|
60
|
-
- **Label everything.** A box labeled "Testimonials" tells the AI much more than an unlabeled rectangle.
|
|
61
|
-
- **Keep it simple.** A few well-placed shapes communicate layout faster than a detailed illustration.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { getLabels } from 'fimo/astro';
|
|
3
|
-
import { Text } from 'fimo/astro/components';
|
|
4
|
-
|
|
5
|
-
import * as Project from '../schemas/Project';
|
|
6
|
-
import * as SiteSettings from '../schemas/SiteSettings';
|
|
7
|
-
|
|
8
|
-
interface Props {
|
|
9
|
-
locale: string;
|
|
10
|
-
localePrefix?: string;
|
|
11
|
-
rendering: 'static' | 'server';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const { locale, localePrefix, rendering } = Astro.props;
|
|
15
|
-
const prefix = localePrefix ? `/${localePrefix}` : '';
|
|
16
|
-
const localize = (path: string) => `${prefix}${path}`;
|
|
17
|
-
const [settings, projects, labels] = await Promise.all([
|
|
18
|
-
SiteSettings.get({ locale }),
|
|
19
|
-
Project.list({ locale, limit: 12 }),
|
|
20
|
-
getLabels({ locale }),
|
|
21
|
-
]);
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
<main data-framework="astro" data-rendering={rendering} data-locale={locale} data-fimo-starter="projects">
|
|
25
|
-
<nav aria-label="Primary">
|
|
26
|
-
<a href={localize('/')}>Home</a>
|
|
27
|
-
</nav>
|
|
28
|
-
<header>
|
|
29
|
-
<Text as="h1" value={settings.studioName} />
|
|
30
|
-
<Text as="p" value={settings.intro} />
|
|
31
|
-
<a href={localize('/projects')}><Text as="span" value={labels.t('navigation.projects')} /></a>
|
|
32
|
-
</header>
|
|
33
|
-
<section>
|
|
34
|
-
<Text as="h2" value={labels.t('projects.heading')} />
|
|
35
|
-
{
|
|
36
|
-
projects.items.map((project) => (
|
|
37
|
-
<article data-project-slug={String(project.slug)}>
|
|
38
|
-
<Text as="h3" value={project.title} />
|
|
39
|
-
<Text as="p" value={project.summary} />
|
|
40
|
-
<a href={localize(`/projects/${String(project.slug)}`)}><Text as="span" value={project.title} /></a>
|
|
41
|
-
</article>
|
|
42
|
-
))
|
|
43
|
-
}
|
|
44
|
-
</section>
|
|
45
|
-
</main>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { getLabels } from 'fimo/astro';
|
|
3
|
-
import { Text } from 'fimo/astro/components';
|
|
4
|
-
import { resolveSeoForPath } from 'fimo/seo';
|
|
5
|
-
|
|
6
|
-
import config from '../../../../.fimo/config.json';
|
|
7
|
-
import Base from '../../../layouts/Base.astro';
|
|
8
|
-
import { prefixedLocales } from '../../../locales';
|
|
9
|
-
import * as Project from '../../../schemas/Project';
|
|
10
|
-
|
|
11
|
-
export const prerender = false;
|
|
12
|
-
|
|
13
|
-
const routeLocale = Astro.params.locale;
|
|
14
|
-
const slug = Astro.params.slug ?? '';
|
|
15
|
-
|
|
16
|
-
if (!routeLocale || !prefixedLocales.has(routeLocale)) {
|
|
17
|
-
return new Response(null, { status: 404, statusText: 'Not found' });
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const locale = Astro.currentLocale ?? routeLocale;
|
|
21
|
-
|
|
22
|
-
const [project, labels] = await Promise.all([Project.getBySlug(slug, { locale }), getLabels({ locale })]);
|
|
23
|
-
|
|
24
|
-
if (!project) {
|
|
25
|
-
return Astro.redirect('/404');
|
|
26
|
-
}
|
|
27
|
-
const seo = resolveSeoForPath(Astro.url.pathname, config, { project });
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
<Base lang={locale} seo={seo} title={seo?.title ?? String(project.title)}>
|
|
31
|
-
<main data-framework="astro" data-rendering="server" data-project-slug={slug}>
|
|
32
|
-
<a href={`/${locale}/projects`}><Text as="span" value={labels.t('navigation.projects')} /></a>
|
|
33
|
-
<article>
|
|
34
|
-
<Text as="h1" value={project.title} />
|
|
35
|
-
<Text as="p" value={project.summary} />
|
|
36
|
-
</article>
|
|
37
|
-
</main>
|
|
38
|
-
</Base>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import ProjectOverview from '../../../components/ProjectOverview.astro';
|
|
3
|
-
import Base from '../../../layouts/Base.astro';
|
|
4
|
-
import { prefixedLocales } from '../../../locales';
|
|
5
|
-
|
|
6
|
-
export const prerender = false;
|
|
7
|
-
|
|
8
|
-
const routeLocale = Astro.params.locale;
|
|
9
|
-
|
|
10
|
-
if (!routeLocale || !prefixedLocales.has(routeLocale)) {
|
|
11
|
-
return new Response(null, { status: 404, statusText: 'Not found' });
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const locale = Astro.currentLocale ?? routeLocale;
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
<Base lang={locale} title="Projects">
|
|
18
|
-
<ProjectOverview {locale} localePrefix={locale} rendering="server" />
|
|
19
|
-
</Base>
|