@areca-cms/skills 0.4.0 → 0.5.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/CHANGELOG.md +7 -0
- package/README.md +2 -1
- package/dist/cli.js +3 -1
- package/dist/skills.d.ts +8 -3
- package/dist/skills.js +19 -12
- package/package.json +1 -1
- package/skills/areca-mcp/SKILL.md +19 -5
- package/skills/areca-mcp/references/languages.md +86 -0
- package/skills/areca-mcp/references/tools.md +21 -12
- package/skills/areca-quickstart/SKILL.md +245 -0
- package/skills/areca-quickstart/references/connect.md +123 -0
- package/skills/areca-quickstart/references/first-release.md +181 -0
- package/skills/areca-quickstart/references/frameworks.md +533 -0
- package/skills/areca-quickstart/references/interview.md +169 -0
- package/skills/areca-quickstart/references/recipes.md +243 -0
- package/skills/areca-sdk/SKILL.md +15 -10
- package/skills/areca-sdk/references/api.md +17 -9
- package/skills/areca-sdk/references/languages.md +177 -0
- package/skills/areca-sdk/references/production.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@areca-cms/skills`.
|
|
4
4
|
|
|
5
|
+
## 0.5.0 (2026-10-26)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- **sdk:** manifest pull asks only when something would be removed (a265c3e)
|
|
10
|
+
- **skills:** add areca-quickstart skill and set_publishing_mode MCP tool (3c1bdbd)
|
|
11
|
+
|
|
5
12
|
## 0.4.0 (2026-10-14)
|
|
6
13
|
|
|
7
14
|
### Features
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ Agent skills that teach AI coding agents and chat apps how to work with Areca CM
|
|
|
6
6
|
| --- | --- |
|
|
7
7
|
| `areca-sdk` | Connecting a website with `@areca-cms/site-sdk`: tokens and env vars, `areca.config.ts`, the `areca` CLI, reading content, rich text, SEO, preview routes, Go-live builds |
|
|
8
8
|
| `areca-mcp` | Connecting an AI to a site's MCP server and using it: OAuth and personal keys, roles, the draft/ready/live workflow, field formats, SEO, images, every tool |
|
|
9
|
+
| `areca-quickstart` | Setting up Areca in a new website project: checks the project, interviews you about the content model, languages and build, wires the SDK, and makes a first release. Run it as `/areca-quickstart` |
|
|
9
10
|
|
|
10
11
|
The skills are plain `SKILL.md` folders in the open [Agent Skills](https://agentskills.io) format. They have no scripts and no dependencies, so they work in any project.
|
|
11
12
|
|
|
@@ -45,7 +46,7 @@ MCP config is written to the project file for Claude Code (`.mcp.json`), Cursor,
|
|
|
45
46
|
## Other ways to install
|
|
46
47
|
|
|
47
48
|
- **Claude Code plugin:** `/plugin marketplace add ekozf/areca-cms`, then `/plugin install areca@areca-cms`.
|
|
48
|
-
- **skills CLI:** `npx skills add ekozf/areca-cms --skill areca-sdk --skill areca-mcp`.
|
|
49
|
+
- **skills CLI:** `npx skills add ekozf/areca-cms --skill areca-sdk --skill areca-mcp --skill areca-quickstart`.
|
|
49
50
|
- **Manually:** copy `skills/areca-*` from the repository into your agent's skills folder.
|
|
50
51
|
|
|
51
52
|
## Development
|
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ Commands:
|
|
|
19
19
|
|
|
20
20
|
Options:
|
|
21
21
|
-a, --agent <id> Agent id, repeatable or comma separated (see list)
|
|
22
|
-
-s, --skill <name> Only this skill (areca-sdk, areca-mcp); default all
|
|
22
|
+
-s, --skill <name> Only this skill (areca-sdk, areca-mcp, areca-quickstart); default all
|
|
23
23
|
-g, --global Install into user-level folders instead of the project
|
|
24
24
|
--mcp-url <url> Connector URL (<cms>/api/mcp/<site-slug>) to register
|
|
25
25
|
--out <dir> Zip folder for chat apps and export (default: areca-skills)
|
|
@@ -245,6 +245,8 @@ function hintFor(name) {
|
|
|
245
245
|
return 'website code: setup, config, CLI, content, preview, deploy';
|
|
246
246
|
if (name === 'areca-mcp')
|
|
247
247
|
return 'AI content editing: connect, tools, workflow';
|
|
248
|
+
if (name === 'areca-quickstart')
|
|
249
|
+
return 'Set up Areca in a new site project (interview + wiring)';
|
|
248
250
|
return '';
|
|
249
251
|
}
|
|
250
252
|
async function chooseMcpUrl(options, cwd, interactive, required = false) {
|
package/dist/skills.d.ts
CHANGED
|
@@ -5,10 +5,15 @@ export type Skill = {
|
|
|
5
5
|
dir: string;
|
|
6
6
|
};
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Where the bundled skills live. Inside the monorepo the root `skills/` folder is
|
|
9
|
+
* the source of truth, so it wins over the `skills/` copy that `build` makes inside
|
|
10
|
+
* the package (that copy can go stale). An npm install has no repo root, so the
|
|
11
|
+
* packaged copy is used.
|
|
12
|
+
*
|
|
13
|
+
* `moduleDir` is the folder of this module (`src/` from source, `dist/` when built).
|
|
14
|
+
* It is a parameter so tests can point it at a temp layout.
|
|
10
15
|
*/
|
|
11
|
-
export declare function skillsRoot(): string;
|
|
16
|
+
export declare function skillsRoot(moduleDir?: string): string;
|
|
12
17
|
export declare function loadSkills(root?: string): Skill[];
|
|
13
18
|
/** Top-level `key: value` pairs of a SKILL.md frontmatter block. */
|
|
14
19
|
export declare function parseFrontmatter(source: string): Record<string, string>;
|
package/dist/skills.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
-
import { join, relative } from 'node:path';
|
|
2
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const MARKER = 'areca-sdk/SKILL.md';
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Where the bundled skills live. Inside the monorepo the root `skills/` folder is
|
|
7
|
+
* the source of truth, so it wins over the `skills/` copy that `build` makes inside
|
|
8
|
+
* the package (that copy can go stale). An npm install has no repo root, so the
|
|
9
|
+
* packaged copy is used.
|
|
10
|
+
*
|
|
11
|
+
* `moduleDir` is the folder of this module (`src/` from source, `dist/` when built).
|
|
12
|
+
* It is a parameter so tests can point it at a temp layout.
|
|
7
13
|
*/
|
|
8
|
-
export function skillsRoot() {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
export function skillsRoot(moduleDir = dirname(fileURLToPath(import.meta.url))) {
|
|
15
|
+
const repoRoot = resolve(moduleDir, '../../..');
|
|
16
|
+
const repoSkills = join(repoRoot, 'skills');
|
|
17
|
+
const packaged = resolve(moduleDir, '../skills');
|
|
18
|
+
const inRepo = existsSync(join(repoRoot, 'pnpm-workspace.yaml')) && existsSync(join(repoSkills, MARKER));
|
|
19
|
+
if (inRepo)
|
|
20
|
+
return repoSkills;
|
|
21
|
+
if (existsSync(join(packaged, MARKER)))
|
|
22
|
+
return packaged;
|
|
23
|
+
throw new Error(`Bundled skills not found (looked in ${repoSkills}, ${packaged})`);
|
|
17
24
|
}
|
|
18
25
|
export function loadSkills(root = skillsRoot()) {
|
|
19
26
|
return readdirSync(root, { withFileTypes: true })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@areca-cms/skills",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Agent skills for Areca CMS: the site SDK and the MCP server. Installs into Claude Code, Codex, Cursor, Copilot, OpenCode, Gemini CLI and 20+ other agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"areca",
|
|
@@ -3,7 +3,7 @@ name: areca-mcp
|
|
|
3
3
|
description: Connects an AI client to an Areca CMS site through its MCP server and uses its tools to write, edit, review and publish content. Covers the per-site connector URL, OAuth sign-in or personal keys, roles and go-live permission, the draft/ready/live workflow, field and Markdown formats, SEO, images, and every tool. Use when the user wants to connect Areca to an AI app or coding agent, or to create, update, approve, schedule or publish Areca CMS entries, upload images, or check what is live.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.
|
|
6
|
+
version: "0.5.0"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Areca MCP
|
|
@@ -20,7 +20,7 @@ Every Areca site has its own remote MCP server. Through it an AI can read and wr
|
|
|
20
20
|
|
|
21
21
|
## First calls (always)
|
|
22
22
|
|
|
23
|
-
1. `get_site_info`: returns your role, what you **cannot** do, the collections, the site content sections (`globals`)
|
|
23
|
+
1. `get_site_info`: returns your role, what you **cannot** do, the collections, the site content sections (`globals`), the site's publishing mode, whether a deployment target is configured (`deploymentConfigured`) and, on a multilingual site, its `languages`.
|
|
24
24
|
2. `get_collection_schema({ collection })`: returns exact field formats, an example payload and SEO guidance. Call it before every first write to a collection. For a site content section, `get_global({ global })` gives the same information.
|
|
25
25
|
|
|
26
26
|
Tools your role can't use are not listed at all. If the user asks for one of those actions, explain who can do it and don't look for workarounds.
|
|
@@ -36,6 +36,7 @@ schedule_entry -> scheduled goes live at a set time (also publishes o
|
|
|
36
36
|
|
|
37
37
|
- `status`: `draft` | `ready` | `scheduled` | `archived`. To answer "what is live" use the flags: `live` (on the production site now), `pendingRelease` (approved changes waiting for the next go live) and `editedSinceReady`.
|
|
38
38
|
- Drafts are safe. Nothing changes the live site until an entry is marked ready **and** a go live happens.
|
|
39
|
+
- Publishing mode: `production` (go live deploys to the live site) or `demo` (go live builds a release that `areca pull` fetches; demo releases never reach visitors). Agency admins switch it with `set_publishing_mode`. A site that has ever gone live cannot switch to demo, and production needs a deployment target set in Settings › Deployment.
|
|
39
40
|
- Only call `mark_ready`, `go_live`, `schedule_entry`, `rollback`, `delete_*` or `archive_entry` when the user explicitly asks.
|
|
40
41
|
- Writes return a `version`. Pass it as `expectedVersion` on the next `update_entry` or `update_global`. On a version conflict, call `get_entry` (or `get_global`), reapply the change and retry.
|
|
41
42
|
- Show the user the `previewUrl` that create and update return (it's signed and valid for about 1 hour). If the site has no production URL, preview isn't available.
|
|
@@ -47,7 +48,7 @@ schedule_entry -> scheduled goes live at a set time (also publishes o
|
|
|
47
48
|
| editor | read everything, create and edit drafts, upload images, edit alt text, preview |
|
|
48
49
|
| owner | everything an editor can, plus `mark_ready`, `unpublish_entry`, `archive_entry`, `cancel_schedule`, `delete_entry`, `restore_revision`, `delete_asset` |
|
|
49
50
|
| + go-live permission | `go_live`, `schedule_entry`, `rollback`, `cancel_build`. Granted per connection or key with "Allow going live" (owners and agency admins only). |
|
|
50
|
-
| agency admin | everything above, plus `upsert_collection`, `delete_collection`, `upsert_global` and `
|
|
51
|
+
| agency admin | everything above, plus `upsert_collection`, `delete_collection`, `upsert_global`, `delete_global`, `set_site_languages` and `set_publishing_mode` (needs 2FA) |
|
|
51
52
|
|
|
52
53
|
## Writing content
|
|
53
54
|
|
|
@@ -57,9 +58,20 @@ schedule_entry -> scheduled goes live at a set time (also publishes o
|
|
|
57
58
|
- **Clearing:** use `""` for a field or SEO text, `[]` for SEO lists and `false` for `noindex`/`nofollow`. Avoid `null` (`seo` rejects it). A key you leave out keeps its value.
|
|
58
59
|
- **SEO on every new entry:** `seo.title` (50-60 chars), `seo.description` (140-160), `focusKeyphrase`, `summary` (2-3 sentences) and 3-5 `keyTakeaways`. Add `faq` only when the body really answers those questions.
|
|
59
60
|
- **Site content (globals):** single sections such as company info or the home page. Read one with `get_global({ global })` and change it with `update_global({ global, fields?, seo?, expectedVersion? })`. It is not a collection, so `create_entry` and `list_entries` do not apply. Its `id` (from `get_global`) works with `mark_ready`, `schedule_entry`, `cancel_schedule`, `list_revisions`, `restore_revision` and `get_preview_url`. Use `discard_global_draft` to go back to the ready values. `seo` is only accepted when the section has SEO on.
|
|
60
|
-
- **Schema:**
|
|
61
|
+
- **Schema:** check the first line of the site's `areca.config.ts`. If it is `// Generated by \`areca manifest pull\`.`, the schema is managed in the CMS: change it with `upsert_collection` or `upsert_global`, then run `areca manifest pull`. If the config is hand-written, the schema is in code: change `areca.config.ts` and push it with `areca manifest push`. Both ways replace the whole field list, so send every field.
|
|
61
62
|
|
|
62
|
-
Full formats, the SEO object, limits and errors are in [references/content.md](references/content.md). Every tool with its inputs is in [references/tools.md](references/tools.md).
|
|
63
|
+
Full formats, the SEO object, limits and errors are in [references/content.md](references/content.md). Every tool with its inputs is in [references/tools.md](references/tools.md). Multilingual details are in [references/languages.md](references/languages.md).
|
|
64
|
+
|
|
65
|
+
## Multilingual sites
|
|
66
|
+
|
|
67
|
+
Only when `get_site_info` returns `languages`. The main language is the fallback; each other language is written on its own.
|
|
68
|
+
|
|
69
|
+
1. `get_site_info`: note `languages.main`, `languages.all` and each collection's `requiredLanguages`.
|
|
70
|
+
2. `create_entry` or `update_entry` (or `update_global`) for the main language, with no `locale`.
|
|
71
|
+
3. One `update_entry({ id, locale, fields, seo, slug, expectedVersion })` call per other language. Check `sharedFieldsUpdated` in each response: those fields changed in every language.
|
|
72
|
+
4. `get_entry({ id })` and read `translations`. Fill any missing required fields until each language is `complete`.
|
|
73
|
+
|
|
74
|
+
`mark_ready` refuses an entry until every required language is complete. Only mark ready when the user asks. Details, the `translatable` rules and the errors are in [references/languages.md](references/languages.md).
|
|
63
75
|
|
|
64
76
|
## Errors
|
|
65
77
|
|
|
@@ -68,6 +80,8 @@ Tool errors come back as normal results with `isError: true` and a message that
|
|
|
68
80
|
- `Validation failed`: call `get_collection_schema`.
|
|
69
81
|
- `changed since you last read it`: call `get_entry` and retry.
|
|
70
82
|
- `Only site owners…` or `Going live…`: tell the user who can do it.
|
|
83
|
+
- `is not one of this site's languages`: use a code from `get_site_info`. `This site has one language`: drop `locale`.
|
|
84
|
+
- A refusal from `mark_ready` or `schedule_entry` that names languages: fill in those languages with `update_entry` and `locale`.
|
|
71
85
|
- `Something went wrong on the Areca server (ref …)`: nothing is confirmed saved. Retry once, then report the ref.
|
|
72
86
|
|
|
73
87
|
Over HTTP, `401` means sign in again or reconnect. `403 mfa_required` means the agency admin must turn on 2FA. `429` means wait for `Retry-After` (120 requests/min per credential).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Multilingual sites
|
|
2
|
+
|
|
3
|
+
A site can publish in several languages. A site with one language behaves as described in the rest of the skill, and none of the `locale`, `translations`, `missingLanguage` or `translatable` parameters appear. Use this file only when `get_site_info` returns `languages`.
|
|
4
|
+
|
|
5
|
+
## Languages and the main language
|
|
6
|
+
|
|
7
|
+
`get_site_info` returns `languages`:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{ "main": "nl", "all": ["nl", "en"], "names": { "nl": "Dutch", "en": "English" } }
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- `main` is the fallback. Visitors get it when a translation is missing, and it holds the shared base values.
|
|
14
|
+
- `all` is the display order and always includes `main`.
|
|
15
|
+
- Codes are BCP 47 (`nl`, `en`, `nl-BE`). Use the exact code from `all` in `locale`.
|
|
16
|
+
|
|
17
|
+
`set_site_languages({ main, all })` changes them. Agency admins only.
|
|
18
|
+
|
|
19
|
+
| Parameter | Behaviour |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `main` | Required. Must be one of `all`. |
|
|
22
|
+
| `all` | Required. Every language, in display order, including `main`. At least one, at most the site limit. |
|
|
23
|
+
|
|
24
|
+
- Removing a language hides it: it stops shipping and leaves the editor, but its text stays in the entries and comes back if you add the language again.
|
|
25
|
+
- A site cannot go back to having no languages. To go back to one language, set `all` to the single code (the rest are hidden as above).
|
|
26
|
+
- Changing `main` deletes nothing. Entries and sections that are not complete in the new main language cannot be marked ready until they are. The result's `gaps` counts them, and the message says how many.
|
|
27
|
+
|
|
28
|
+
## Writing one language per call
|
|
29
|
+
|
|
30
|
+
`create_entry`, `update_entry`, `update_global` and `update_asset_alt` take `locale`. Leave it out for the main language.
|
|
31
|
+
|
|
32
|
+
- `fields`, `seo` and `slug` apply to the language you name. A translation's `slug` is that language's own URL. Send `""` to fall back to the main slug.
|
|
33
|
+
- Fields that are not translatable are shared. Changing one in any language changes it in every language, and the response lists them in `sharedFieldsUpdated`. Check that list before you assume a write stayed in one language.
|
|
34
|
+
- By default `text`, `textarea`, `richtext` and `url` fields are per language. Other types (number, date, image, reference, select and so on) are shared. `get_collection_schema` shows `translatable` for each field, and `get_site_info` lists `translatableFields` per collection and section.
|
|
35
|
+
|
|
36
|
+
`update_entry` only changes the keys you send. Pass `expectedVersion` from `get_entry` as usual.
|
|
37
|
+
|
|
38
|
+
## Checking translations
|
|
39
|
+
|
|
40
|
+
`get_entry` without `locale` returns the main language's values plus `translations`:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
"translations": {
|
|
44
|
+
"en": { "complete": false, "missing": ["fields.summary"] }
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- `complete` is true when every required field has a value in that language.
|
|
49
|
+
- `missing` lists the required fields that are empty there.
|
|
50
|
+
- With `locale`, `get_entry` returns that language's values (slug and seo included) instead, and no `translations`.
|
|
51
|
+
|
|
52
|
+
`list_entries({ collection, missingLanguage: "en" })` returns only entries whose draft is not complete in that language.
|
|
53
|
+
|
|
54
|
+
`get_global({ global, locale })` and `get_preview_url({ id, locale })` work the same way. A preview link with `locale` opens that language's page.
|
|
55
|
+
|
|
56
|
+
## Required languages
|
|
57
|
+
|
|
58
|
+
Each collection and section can require languages to be complete before it is marked ready. Set them with `requiredLanguages` (for example `["en"]`) on `upsert_collection` or `upsert_global`, or in `areca.config.ts`. `get_site_info` shows the current list per collection.
|
|
59
|
+
|
|
60
|
+
`mark_ready` and `schedule_entry` refuse an entry until every required language is complete. The error names the languages and the fields that are missing. Fill them in with `update_entry` and `locale`, then mark ready again. Only when the user asks.
|
|
61
|
+
|
|
62
|
+
## Per-language routes
|
|
63
|
+
|
|
64
|
+
`upsert_collection` also takes `routes`, a route pattern per language, each with `$slug`. For example `{"nl": "/vacatures/$slug"}`. Languages that are not listed use `routePattern`. Patterns do not contain the language prefix, because the site adds it. Send `{}` to remove them all.
|
|
65
|
+
|
|
66
|
+
`routes` and `requiredLanguages` are ignored on a site without languages. For a site that syncs its schema from code, put these in `areca.config.ts` and push with `areca manifest push` rather than calling `upsert_collection`.
|
|
67
|
+
|
|
68
|
+
## Translating with AI
|
|
69
|
+
|
|
70
|
+
There is no MCP tool for AI translation. The CMS editor's language bar offers "translate with AI", which fills empty fields from the main language. An agent that is asked to translate writes each language itself with `update_entry` and `locale`.
|
|
71
|
+
|
|
72
|
+
## Multilingual workflow
|
|
73
|
+
|
|
74
|
+
1. `get_site_info`: read `languages` (main and `all`), and each collection's `requiredLanguages` and `translatableFields`.
|
|
75
|
+
2. `get_collection_schema({ collection })`: check which fields are `translatable`, and use the `translation` example if the response has one.
|
|
76
|
+
3. `create_entry` or `update_entry` for the main language, with no `locale`.
|
|
77
|
+
4. For each other language, one `update_entry({ id, locale, fields, seo, slug, expectedVersion })` call. Read `sharedFieldsUpdated` in each response.
|
|
78
|
+
5. `get_entry({ id })` and check `translations`. Fill any missing required field, then repeat until every language is `complete`.
|
|
79
|
+
6. Show the user the `previewUrl`, or call `get_preview_url({ id, locale })` to check one language. Mark ready only when the user asks.
|
|
80
|
+
|
|
81
|
+
## Errors
|
|
82
|
+
|
|
83
|
+
- `This site has one language, so locale does not apply. Leave it out.`: remove `locale` from the call.
|
|
84
|
+
- `"xx" is not one of this site's languages (...)`: the error lists the codes the site has. Use one of them, or call `get_site_info`.
|
|
85
|
+
- `Only agency admins can change the site languages.`: tell the user an agency admin must change them.
|
|
86
|
+
- A mark-ready refusal for incomplete languages: fill in the named languages and fields, then retry.
|
|
@@ -6,19 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
| Tool | Access | Inputs | Returns |
|
|
8
8
|
| --- | --- | --- | --- |
|
|
9
|
-
| `get_site_info` | all | none | `site` (name, slug, productionUrl, publishingMode), `you` (role, capabilities), `cannotDo[]`, `collections[]`, `globals[]` (site content: key, label, enabled, fieldCount, seo, previewPath), `guide`. **Call first.** |
|
|
10
|
-
| `get_collection_schema` | all | `collection*` | Per-field key, type, required, format, options; example `fields` and `seo` payloads; SEO guide |
|
|
9
|
+
| `get_site_info` | all | none | `site` (name, slug, productionUrl, publishingMode, deploymentConfigured), `you` (role, capabilities), `cannotDo[]`, `collections[]`, `globals[]` (site content: key, label, enabled, fieldCount, seo, previewPath), `guide`. On a site with languages also `languages` (`main`, `all`, `names`) and, per collection and section, `requiredLanguages`, `translatableFields` and `routes`. **Call first.** |
|
|
10
|
+
| `get_collection_schema` | all | `collection*` | Per-field key, type, required, format, options (and `translatable` on sites with languages); example `fields` and `seo` payloads; SEO guide; `translation` example on sites with languages |
|
|
11
11
|
|
|
12
12
|
## Entries
|
|
13
13
|
|
|
14
14
|
| Tool | Access | Inputs | Returns |
|
|
15
15
|
| --- | --- | --- | --- |
|
|
16
|
-
| `list_entries` | all | `collection*`, `status?` (draft, ready, scheduled, archived), `search?`, `limit?` (1-100, default 20), `offset?` | `items[]` (id, slug, status, live, pendingRelease, title, version), `total`, `nextOffset` |
|
|
17
|
-
| `get_entry` | all | `id*`, `includePublished?` | `fields`, `seo`, `status`, `live`, `pendingRelease`, `editedSinceReady`, `version`. With `includePublished`, also `liveFields` and `approvedFields`. |
|
|
18
|
-
| `create_entry` | all | `collection*`, `fields?`, `seo?` | New draft + `previewUrl` |
|
|
19
|
-
| `update_entry` | all | `id*`, `fields?`, `seo?` (at least one), `expectedVersion?` | Updated draft + `previewUrl`. Keys you leave out keep their values. |
|
|
16
|
+
| `list_entries` | all | `collection*`, `status?` (draft, ready, scheduled, archived), `search?`, `limit?` (1-100, default 20), `offset?`, `missingLanguage?` (languages sites: only entries whose draft is not complete in that language) | `items[]` (id, slug, status, live, pendingRelease, title, version), `total`, `nextOffset` |
|
|
17
|
+
| `get_entry` | all | `id*`, `includePublished?`, `locale?` (languages sites) | `fields`, `seo`, `status`, `live`, `pendingRelease`, `editedSinceReady`, `version`. With `includePublished`, also `liveFields` and `approvedFields`. With `locale`, that language's values (slug and seo included) and `locale`. Without it on a languages site: the main language plus `translations` (`complete` and `missing` for each other language). |
|
|
18
|
+
| `create_entry` | all | `collection*`, `fields?`, `seo?`, `slug?`, `locale?` (languages sites) | New draft + `previewUrl`. `fields`, `seo` and `slug` apply to `locale` (default main). |
|
|
19
|
+
| `update_entry` | all | `id*`, `fields?`, `seo?`, `slug?` (at least one), `locale?` (languages sites), `expectedVersion?` | Updated draft + `previewUrl`. Keys you leave out keep their values. Languages sites: one language per call; `sharedFieldsUpdated` lists the non-translatable fields that changed in every language. |
|
|
20
20
|
| `list_revisions` | all | `id*` | Revision id, note, createdAt, createdBy |
|
|
21
|
-
| `get_preview_url` | all | `id
|
|
21
|
+
| `get_preview_url` | all | `id*`, `locale?` (languages sites) | `{ url }`, signed, about 1 hour. Fails without a site production URL. |
|
|
22
22
|
|
|
23
23
|
## Site content (globals)
|
|
24
24
|
|
|
@@ -26,8 +26,8 @@ Single sections such as company info or the home page. Editors and owners see en
|
|
|
26
26
|
|
|
27
27
|
| Tool | Access | Inputs | Returns |
|
|
28
28
|
| --- | --- | --- | --- |
|
|
29
|
-
| `get_global` | all | `global*` (key from `get_site_info`) | `id`, `key`, `label`, `status`, `live`, `pendingRelease`, `version`, `editedSinceReady`, `previewAvailable`, `values` (rich text as Markdown, images as `{assetId,url,alt}`, references as `{entryId}`), `seo` (only with SEO on), `fields` (format of each field), `example` |
|
|
30
|
-
| `update_global` | all | `global*`, `fields?`, `seo?` (at least one; refused without SEO on the section), `expectedVersion?` | Updated draft + `previewUrl`. Keys you leave out keep their values. |
|
|
29
|
+
| `get_global` | all | `global*` (key from `get_site_info`), `locale?` (languages sites) | `id`, `key`, `label`, `status`, `live`, `pendingRelease`, `version`, `editedSinceReady`, `previewAvailable`, `values` (rich text as Markdown, images as `{assetId,url,alt}`, references as `{entryId}`), `seo` (only with SEO on), `fields` (format of each field), `example` |
|
|
30
|
+
| `update_global` | all | `global*`, `fields?`, `seo?` (at least one; refused without SEO on the section), `locale?` (languages sites), `expectedVersion?` | Updated draft + `previewUrl`. Keys you leave out keep their values. |
|
|
31
31
|
| `discard_global_draft` | all | `global*` | Draft reset to the ready values, kept in history. Refused when the section was never ready. |
|
|
32
32
|
|
|
33
33
|
## Workflow
|
|
@@ -51,7 +51,7 @@ Single sections such as company info or the home page. Editors and owners see en
|
|
|
51
51
|
| `list_assets` | all | `search?`, `limit?` (1-100), `offset?` | assetId, filename, mimeType, width, height, alt, url |
|
|
52
52
|
| `get_asset` | all | `id*` | Asset + `usageCount` |
|
|
53
53
|
| `upload_asset_from_url` | all | `url*` (direct http(s) file link), `altText?`, `filename?` | Asset with `assetId` + `howToUse` |
|
|
54
|
-
| `update_asset_alt` | all | `id*`, `altText*` (`""` clears) | Asset |
|
|
54
|
+
| `update_asset_alt` | all | `id*`, `altText*` (`""` clears), `locale?` (languages sites: alt text for that language) | Asset |
|
|
55
55
|
| `delete_asset` | owner | `id*` | Refused while the asset is in use |
|
|
56
56
|
|
|
57
57
|
## Publishing
|
|
@@ -59,6 +59,7 @@ Single sections such as company info or the home page. Editors and owners see en
|
|
|
59
59
|
| Tool | Access | Inputs | Returns |
|
|
60
60
|
| --- | --- | --- | --- |
|
|
61
61
|
| `get_release_status` | all | none | `publishingMode`, `live`, `demo`, `activeJob`, `pendingCount`, `pendingChanges[]` |
|
|
62
|
+
| `set_publishing_mode` | agency | `mode*` (`demo` or `production`) | `publishingMode`, `deploymentConfigured`. `demo`: `go_live` builds a release that `areca pull` can fetch without a deployment; demo releases never reach visitors. `production`: `go_live` deploys to the live site and needs a deployment target (application ID and health check URL, set in Settings › Deployment). Refused with a conflict when switching to `demo` after the site has ever gone live, or to `production` without a deployment target. The same mode changes nothing and writes no audit entry. Each change is audited with the MCP caller. |
|
|
62
63
|
| `list_publications` | all | `limit?` (1-50, default 10) | Publications, newest first |
|
|
63
64
|
| `get_build_job` | all | `jobId*` | Status, attempts, timing, error |
|
|
64
65
|
| `go_live` | go-live | `note?` | Queues a build that publishes **all** ready changes and returns `publicationId` and `jobId`. Poll `get_build_job`. |
|
|
@@ -69,11 +70,19 @@ Single sections such as company info or the home page. Editors and owners see en
|
|
|
69
70
|
|
|
70
71
|
| Tool | Access | Inputs | Effect |
|
|
71
72
|
| --- | --- | --- | --- |
|
|
72
|
-
| `upsert_collection` | agency | `key*`, `label*`, `routePattern*`, `fields*` (up to 100: `key*`, `label*`, `type*`, `required?`, `options?`, `collection?`, `description?`, `after?`), `enabled?` | Creates the collection or **replaces** its field list. Prefer `areca.config.ts` + `areca manifest push` when the site syncs its schema from code. |
|
|
73
|
+
| `upsert_collection` | agency | `key*`, `label*`, `routePattern*`, `fields*` (up to 100: `key*`, `label*`, `type*`, `required?`, `options?`, `collection?`, `description?`, `after?`, `translatable?` on languages sites), `enabled?`, `requiredLanguages?`, `routes?` (languages sites) | Creates the collection or **replaces** its field list. Prefer `areca.config.ts` + `areca manifest push` when the site syncs its schema from code. |
|
|
73
74
|
| `delete_collection` | agency | `key*` | Deletes the collection and its entries. Destructive. |
|
|
74
|
-
| `upsert_global` | agency | `key*`, `label*`, `fields*` (as `upsert_collection`, plus `group?` heading; no `slug` type), `seo?`, `previewPath?` (e.g. `/about`, `""` removes it), `enabled?` | Creates the site content section or **replaces** its fields, SEO setting, preview path and enabled flag. Keeps its content. |
|
|
75
|
+
| `upsert_global` | agency | `key*`, `label*`, `fields*` (as `upsert_collection`, plus `group?` heading; no `slug` type), `seo?`, `previewPath?` (e.g. `/about`, `""` removes it), `enabled?`, `requiredLanguages?` (languages sites) | Creates the site content section or **replaces** its fields, SEO setting, preview path and enabled flag. Keeps its content. |
|
|
75
76
|
| `delete_global` | agency | `key*` | Deletes the section. Its content is kept in the deleted-content archive. Destructive. |
|
|
76
77
|
|
|
78
|
+
## Languages (agency)
|
|
79
|
+
|
|
80
|
+
| Tool | Access | Inputs | Returns |
|
|
81
|
+
| --- | --- | --- | --- |
|
|
82
|
+
| `set_site_languages` | agency | `main*` (must be in `all`), `all*` (every language in display order, including `main`) | `languages` (main, all, names) and `gaps`: entries and sections not complete in the new main language. Removing a language hides it and keeps its text. Languages cannot be turned off once set. |
|
|
83
|
+
|
|
84
|
+
On a site without languages none of the `locale`, `translations`, `missingLanguage`, `translatable` or `requiredLanguages` parameters appear, and their results are unchanged. See [languages.md](languages.md) for the workflow.
|
|
85
|
+
|
|
77
86
|
## Prompt
|
|
78
87
|
|
|
79
88
|
`write_post({ collection*, topic* })` returns a step-by-step writing brief: schema, images, draft and SEO. It ends with "mark ready or go live only when asked".
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: areca-quickstart
|
|
3
|
+
description: Sets up Areca CMS in a new or existing website project for a web agency. Detects the framework, interviews the user, creates the content model over MCP or in code, wires the site and publishes a first release. Use when the user wants to set up, connect or integrate Areca CMS, run the quickstart, add Areca to a website, or add collections like blog or vacancies.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
version: "0.5.0"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Areca quickstart
|
|
10
|
+
|
|
11
|
+
This skill sets up Areca CMS in one website project. You detect what the project already has, ask the user a few questions, then do the work. The user is an agency. The website is for one client.
|
|
12
|
+
|
|
13
|
+
The skill runs in two modes:
|
|
14
|
+
|
|
15
|
+
- **New setup:** no Areca files exist yet. Go through steps 0 to 7.
|
|
16
|
+
- **Re-run:** Areca is already set up. Go to [Re-run mode](#re-run-mode).
|
|
17
|
+
|
|
18
|
+
Plain steps, in order:
|
|
19
|
+
|
|
20
|
+
0. Detect the project.
|
|
21
|
+
1. Check the MCP connection.
|
|
22
|
+
2. Interview the user (four batches).
|
|
23
|
+
3. Show the content model and wait for approval.
|
|
24
|
+
4. Connect the project and create the schema.
|
|
25
|
+
5. Wire the project (scripts, framework, languages, pages).
|
|
26
|
+
6. Make the first release, pull the content and verify.
|
|
27
|
+
7. Summarise and hand over.
|
|
28
|
+
|
|
29
|
+
Keep the details in the reference files:
|
|
30
|
+
|
|
31
|
+
- [references/interview.md](references/interview.md): the question batches and the plan format.
|
|
32
|
+
- [references/recipes.md](references/recipes.md): collection and section recipes with fields.
|
|
33
|
+
- [references/connect.md](references/connect.md): MCP connection, creating the site, tokens, demo mode.
|
|
34
|
+
- [references/frameworks.md](references/frameworks.md): wiring code for TanStack Start, Next.js, Astro and plain Node.
|
|
35
|
+
- [references/first-release.md](references/first-release.md): sample entries, release, pull, checks and troubleshooting.
|
|
36
|
+
|
|
37
|
+
For API detail, read the `areca-sdk` skill (config, fields, CLI, content API) and the `areca-mcp` skill (tools, roles, workflow). Do not copy their detail into the project. Name the skill and use what it says. If those skills are not installed, read the docs in the `skills/` folder of https://github.com/ekozf/areca-cms instead.
|
|
38
|
+
|
|
39
|
+
## Ground rules
|
|
40
|
+
|
|
41
|
+
- Never delete a collection, field, section or language without explicit confirmation from the user.
|
|
42
|
+
- Never run `areca init --force`. It replaces `areca.config.ts` with an empty config.
|
|
43
|
+
- Never call `go_live` on your own. Ask first, every time. The same goes for `schedule_entry`, `rollback` and `set_publishing_mode`.
|
|
44
|
+
- Never confirm a field drop with `--yes` or `--confirm-drop` on your own.
|
|
45
|
+
- Never ask for a token or key in chat. Never print a token. See [Secrets](#secrets).
|
|
46
|
+
- Never install a package you were not asked to install. This includes an i18n library. Ask first.
|
|
47
|
+
- Confirm before you overwrite an existing file, or change an existing `package.json` script that is not ours.
|
|
48
|
+
- Do not experiment on a live production site. For an existing live site, use hidden collections (`enabled: false`) or a separate site. Dev environments are planned but not available yet.
|
|
49
|
+
- Respect the user's choices. If they say no to MCP, use code-first. If they say no to a route, skip it.
|
|
50
|
+
- Show a plan before you write files, and wait for the user to approve the content model.
|
|
51
|
+
|
|
52
|
+
## Step 0: Detect the project
|
|
53
|
+
|
|
54
|
+
Read these. Do not change anything yet.
|
|
55
|
+
|
|
56
|
+
1. `package.json`: framework and scripts.
|
|
57
|
+
- `@tanstack/react-start` means TanStack Start.
|
|
58
|
+
- `next` means Next.js.
|
|
59
|
+
- `astro` means Astro.
|
|
60
|
+
- `vite` alone, or no framework, means plain Vite or Node.
|
|
61
|
+
- Note the `dev` script and its port (for example `--port 3001`). If the script sets no port, use the framework's default and confirm it from the dev server output in step 6.
|
|
62
|
+
- Note `packageManager` if it is set.
|
|
63
|
+
2. Lockfile, to find the package manager: `pnpm-lock.yaml` means pnpm, `package-lock.json` means npm, `yarn.lock` means yarn, `bun.lock` or `bun.lockb` means bun. If there is more than one, use the `packageManager` field. If there is still no answer, ask.
|
|
64
|
+
3. Areca state: does `areca.config.ts` exist? Is `@areca-cms/site-sdk` in `dependencies`? Does `src/generated/content/areca.gen.ts` exist? If any is true, use [Re-run mode](#re-run-mode).
|
|
65
|
+
4. i18n: look for `@inlang/paraglide-js` or `project.inlang/`, `next-intl`, `i18next` or `react-i18next`, `@lingui/*`, `vue-i18n`, or an `i18n` block in the framework config (for example `astro.config.mjs`). If none, the answer is "none".
|
|
66
|
+
5. Routes and pages: `src/routes/` (TanStack), `app/` or `src/app/` or `pages/` (Next), `src/pages/` (Astro). Note any blog, team or job pages that already exist.
|
|
67
|
+
6. Node version: run `node -v`. Areca needs 22.6 or newer. Use 24 LTS if possible. Loading a TypeScript config needs 22.18 or newer, or `tsx`.
|
|
68
|
+
7. Env files: check whether `.env.local` exists and which keys it has. Never print values. For a token, print only its length:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
awk -F= '/^ARECA_(CMS_URL|SITE_TOKEN|SCHEMA_TOKEN)=/{print $1, "length", length($2)}' .env.local 2>/dev/null
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
8. Git: run `git status --short`. If the project is not a git repo, say so and offer `git init` before you write any file. If the tree has unrelated changes, tell the user before you start.
|
|
75
|
+
|
|
76
|
+
No framework yet (no `package.json`, or no framework in it)? Say so. Offer to scaffold a TanStack Start app with `pnpm dlx @tanstack/cli@latest create` (not `create-tsrouter-app`). Then continue from step 0 in the new project. This skill does not cover the scaffold itself.
|
|
77
|
+
|
|
78
|
+
Report what you found in a short list. Ask only about what you could not detect. Go to step 1.
|
|
79
|
+
|
|
80
|
+
## Step 1: Check the MCP connection
|
|
81
|
+
|
|
82
|
+
The Areca MCP server gives the agent its own tools. Look for a tool named `get_site_info` from an Areca server. The name may carry a prefix such as `mcp__areca-<slug>__get_site_info`.
|
|
83
|
+
|
|
84
|
+
- **Connected:** call `get_site_info`. Read `you.role`, `cannotDo`, `site.publishingMode`, `collections`, `globals` and `languages`.
|
|
85
|
+
- Role **agency admin**: the schema can be created over MCP (MCP-first, the default).
|
|
86
|
+
- Any other role: the schema must be created in code (code-first). Say why. Owners and editors cannot change the schema over MCP.
|
|
87
|
+
- **Not connected:** ask the user whether they want to connect. Explain what you need: the CMS URL and the site slug. The connector URL is `<cms-url>/api/mcp/<site-slug>`. Explain the sign-in (a browser opens on first use). Read [references/connect.md](references/connect.md) for the exact steps per app. Tell the user that the agent session may need a reload or restart after the connector is added.
|
|
88
|
+
- **Declined, or not possible now:** code-first. Say so once and move on.
|
|
89
|
+
|
|
90
|
+
If the site does not exist in the CMS yet, the user must create it in the CMS. Read the "Create the site" section in [references/connect.md](references/connect.md). Do not guess a site key or a token.
|
|
91
|
+
|
|
92
|
+
## Step 2: Interview the user
|
|
93
|
+
|
|
94
|
+
Read [references/interview.md](references/interview.md). It has four batches: A (project), B (content model), C (languages) and D (build and preview). Ask one batch at a time. Each batch has defaults and an "accept all defaults" reply.
|
|
95
|
+
|
|
96
|
+
- Use the detected values as defaults. Do not ask again what you already know.
|
|
97
|
+
- Record the answers. After batch D, show the plan in the format from `interview.md`. Ask the user to confirm it.
|
|
98
|
+
|
|
99
|
+
## Step 3: Show the content model and wait for approval
|
|
100
|
+
|
|
101
|
+
The approval in this step covers every MCP write and every file write that follows. Record it in your notes before you call any write tool, including `set_site_languages`. No recorded yes, no write.
|
|
102
|
+
|
|
103
|
+
For each collection and section in the plan, build the schema from [references/recipes.md](references/recipes.md). Show one table per collection or section:
|
|
104
|
+
|
|
105
|
+
| Key | Type | Required | Translatable | Notes |
|
|
106
|
+
| --- | --- | --- | --- | --- |
|
|
107
|
+
|
|
108
|
+
Also show the route for each collection (for example `/blog/$slug`) and the SEO setting for each section. When an extra was declined, show the fields that were removed because of it, in the table, for example a row "removed: author (authors declined)".
|
|
109
|
+
|
|
110
|
+
Ask: "Shall I create this content model?" Wait for a yes. If the user changes something, update the plan and show the changed tables again. Do not create anything before approval.
|
|
111
|
+
|
|
112
|
+
## Step 4: Connect the project and create the schema
|
|
113
|
+
|
|
114
|
+
Record the Step 3 approval before any MCP write, including `set_site_languages`.
|
|
115
|
+
|
|
116
|
+
### 4a. Install, init and tokens
|
|
117
|
+
|
|
118
|
+
1. Install the SDK with the detected package manager: `pnpm add @areca-cms/site-sdk`, `npm install @areca-cms/site-sdk`, `yarn add @areca-cms/site-sdk` or `bun add @areca-cms/site-sdk`. Skip this if it is already there.
|
|
119
|
+
2. Run `areca init` once. Use one of these two ways.
|
|
120
|
+
- **Preferred:** ask the user to run `<pm> exec areca init` in their own terminal. It asks for the CMS URL, the site token and the site key. The token prompt hides what is typed. Wait for the user to say it is done.
|
|
121
|
+
- **Alternative:** if the user is fine with it, the user first puts `ARECA_CMS_URL` and `ARECA_SITE_TOKEN` in `.env.local` (you do not paste the token). Then run the non-interactive form, with the URL and site key from the plan:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
<pm> exec areca init --yes --cms-url <url from the plan> --site-key <site key from the plan> --token "$(sed -n 's/^ARECA_SITE_TOKEN=//p' .env.local)"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Do not echo the command with the token in it. The `--token` flag is visible to other users on the machine for a moment. Mention that.
|
|
128
|
+
3. `init` writes `areca.config.ts` (if missing), `.env.example`, `.env.local`, `.gitignore` entries, `src/generated/content/manifest.json` and the scripts `sync-manifest` and `content:pull`. It also wraps `dev` in `areca run --` unless the script already loads env files. It does not install packages and does not add `areca.gen.ts`. Check the result with `git diff` and show the user a short list.
|
|
129
|
+
- `init` prints code-first next steps (`sync-manifest`, then publish). Ignore that text when you go MCP-first. The schema comes from MCP, and `sync-manifest` is not used.
|
|
130
|
+
4. Schema token (code-first only): the user adds `ARECA_SCHEMA_TOKEN=` to `.env.local` themselves, from Settings › Developer › Schema-write token. MCP-first does not need it.
|
|
131
|
+
5. Check the tokens with the length check from step 0. Do not print them. If a value is empty, say which key is empty and where to paste it. Continue only when the needed keys are set.
|
|
132
|
+
6. `.env.local` is gitignored. Leave its file permissions as they are. Do not run `chmod` on your own. If the user asks for stricter permissions, `chmod 600 .env.local` is the usual choice.
|
|
133
|
+
|
|
134
|
+
### 4b. Create the schema
|
|
135
|
+
|
|
136
|
+
**MCP-first (default when the role is agency admin):**
|
|
137
|
+
|
|
138
|
+
1. Call `get_site_info` again. Check that the site matches the site key in the plan.
|
|
139
|
+
2. If the plan has languages, call `set_site_languages` with `main` and `all`. Tell the user that languages cannot be turned off once set. Ask first if that was not already clear in the plan.
|
|
140
|
+
3. For each collection, call `get_collection_schema` for an existing one. Then call `upsert_collection` with `key`, `label`, `routePattern`, the full `fields` list, `requiredLanguages` and `routes` when needed. Fields replace the whole list, so always send every field. A `slug` field is added when missing, but include it anyway.
|
|
141
|
+
4. For each section, call `upsert_global` with `key`, `label`, the full `fields` list, `seo` and `previewPath`.
|
|
142
|
+
5. Call `get_site_info` again and compare with the plan. Report any difference.
|
|
143
|
+
6. Pull the schema into the project: `<pm> exec areca manifest pull`. This writes `areca.config.ts` from the CMS, so the schema is in Git. A file it wrote before (it starts with the header `// Generated by \`areca manifest pull\`.`) asks only before a removal (a collection, section, field, language, or the main language). If it stops for a removal, show the user the diff and get a yes. Then follow [first-release.md](references/first-release.md) (section 7) before you add `--yes`. A file without the header that already has collections (for example from an older SDK) asks once. With the user's yes, run `<pm> exec areca manifest pull --yes` once.
|
|
144
|
+
|
|
145
|
+
`manifest pull` rewrites the config file. Keep hand edits out of it. It keeps `siteKey`, `assets` and `i18n`.
|
|
146
|
+
|
|
147
|
+
**Code-first (fallback):**
|
|
148
|
+
|
|
149
|
+
1. Write `areca.config.ts` from the approved plan. Use `defineSiteContent` from `@areca-cms/site-sdk`. Use the field rules and the reserved names from the `areca-sdk` skill. Add `languages`, `i18n.paraglide` and `assets` only when the plan says so. Confirm before you overwrite a config that already has collections.
|
|
150
|
+
2. Check that the user has `ARECA_SCHEMA_TOKEN` set (step 4a.5).
|
|
151
|
+
3. Run `<pm> exec areca manifest push`. A push disables collections that are not in the config. If the CMS says a removed field still holds content, the push stops. Show the list to the user and ask. Do not add `--yes`.
|
|
152
|
+
|
|
153
|
+
If an MCP-first or code-first step fails, read the error and the `areca-sdk` or `areca-mcp` skill. Tell the user what failed. Do not try a different path without asking.
|
|
154
|
+
|
|
155
|
+
## Step 5: Wire the project
|
|
156
|
+
|
|
157
|
+
Do these in order. Show the user each file you will change before you change it when the file already exists.
|
|
158
|
+
|
|
159
|
+
1. **Scripts** in `package.json`. Keep the scripts `init` added. Add these, using the detected package manager:
|
|
160
|
+
- `content:sync`: `areca manifest pull && areca pull --out src/generated/content` (MCP-first). It asks only before a removal. A config from an older SDK (no header) asks once: see step 4b.6.
|
|
161
|
+
- `sync-manifest` (`areca manifest push`, needs `ARECA_SCHEMA_TOKEN`) is for code-first only. In MCP-first, leave it in place and tell the user it is not used.
|
|
162
|
+
- `prebuild`: `areca pull` (plus the Paraglide compile first when Paraglide is used). A build without content fails until the first release exists. That is expected.
|
|
163
|
+
- `predev` (optional): only after the first release. A failing `predev` stops the dev server.
|
|
164
|
+
- Do not change `dev` again. `init` already wraps it in `areca run --` when needed.
|
|
165
|
+
2. **Languages** (only if the plan has them). Set `languages` in `areca.config.ts` through MCP or by code. Set up Paraglide only if the user agreed to it. Install it only after approval. For TanStack Start the Paraglide recipe in [references/frameworks.md](references/frameworks.md) was verified end to end; follow it. Other i18n libraries: pass the locale yourself with `content.in(locale)`.
|
|
166
|
+
3. **Framework wiring**: read the section for the detected framework in [references/frameworks.md](references/frameworks.md). Add:
|
|
167
|
+
- a server-only content module (the code imports `content` from `areca.gen.ts`),
|
|
168
|
+
- list and detail pages for each collection in batch D,
|
|
169
|
+
- head tags from `seoHead` or `seoHeadHtml`,
|
|
170
|
+
- the home and about pages when they are in the plan,
|
|
171
|
+
- a preview route when the user asked for it,
|
|
172
|
+
- a health route only when the user plans go-live builds.
|
|
173
|
+
4. **Existing pages**: when the user chose "connect into existing pages", change only the data source. Keep the markup and styles. Show the diff.
|
|
174
|
+
5. **Build output**: keep `src/generated/content/*.json` out of Git. The `.gitignore` entries from `init` do that. Commit `areca.gen.ts` once it exists. Do not commit unless the user asks.
|
|
175
|
+
|
|
176
|
+
Do not render CMS content in browser code. The SDK content object and tokens are server-only. Use the framework's server functions, server components or build-time code.
|
|
177
|
+
|
|
178
|
+
## Step 6: First release, pull and verify
|
|
179
|
+
|
|
180
|
+
Read [references/first-release.md](references/first-release.md). The short version:
|
|
181
|
+
|
|
182
|
+
1. Check the publishing mode. Use demo mode for the first release. Production needs the user's explicit choice, and a site that already went live in production must not get sample content (see first-release.md, section 1).
|
|
183
|
+
2. Create one sample entry per collection, in dependency order (authors before posts, for example). The title starts with `[Sample]`, or the main text field when there is no title. Fill the SEO fields. Fill the main language and each required language.
|
|
184
|
+
3. Fill each required section with `update_global`. Use the real company details from the interview. For other copy, write short placeholder text and say so.
|
|
185
|
+
4. Mark everything ready. Tell the user what you are doing.
|
|
186
|
+
5. Ask: "Go live now in demo mode? This publishes N entries and M sections." Wait for a yes.
|
|
187
|
+
6. Go live, then poll `get_build_job` until the job is done. If the agent has no go-live permission, ask the user to press Go live in the CMS and wait for them.
|
|
188
|
+
7. Pull: `<pm> exec areca pull --out src/generated/content`. Use the direct command, not the `content:sync` script. The script also runs `manifest pull`, which stops without a terminal when that pull would remove something. Expect `Pulled publication …` and a `Types:` line.
|
|
189
|
+
8. Verify: typecheck, build, start the dev server, and check that a sample page returns HTTP 200 and shows its title. Use the checks in the first-release reference.
|
|
190
|
+
9. Ask the user whether to archive the sample entries or keep them as editor examples. Do not archive without a yes.
|
|
191
|
+
|
|
192
|
+
If the user has no sample to show, or the build fails for a reason you cannot fix, stop and report the exact error.
|
|
193
|
+
|
|
194
|
+
## Step 7: Finish
|
|
195
|
+
|
|
196
|
+
Give the user a short summary with this shape. Keep it plain.
|
|
197
|
+
|
|
198
|
+
```text
|
|
199
|
+
Areca CMS is set up in <project path>.
|
|
200
|
+
|
|
201
|
+
Created in the CMS:
|
|
202
|
+
- Collections: <key> (<route>), ...
|
|
203
|
+
- Sections: <key>, ...
|
|
204
|
+
- Languages: <main> (main), <others> | none
|
|
205
|
+
|
|
206
|
+
Files changed:
|
|
207
|
+
- areca.config.ts, .env.local (tokens: not shown), .gitignore
|
|
208
|
+
- src/generated/content/areca.gen.ts (commit this)
|
|
209
|
+
- <pages and modules you wrote>
|
|
210
|
+
|
|
211
|
+
Keep content up to date:
|
|
212
|
+
- <pm> run content:sync (MCP-first: pulls the schema and the published content)
|
|
213
|
+
- <pm> run content:pull (code-first: pulls published content only)
|
|
214
|
+
- After you edit areca.config.ts by hand (code-first): <pm> run sync-manifest
|
|
215
|
+
|
|
216
|
+
Add more later: run /areca-quickstart again. It skips what is done.
|
|
217
|
+
Going live: see the areca-sdk skill, references/production.md (Dokploy builds and the health route).
|
|
218
|
+
Docs: https://github.com/ekozf/areca-cms
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Remove lines that do not apply. Mention any step you skipped and why.
|
|
222
|
+
|
|
223
|
+
## Secrets
|
|
224
|
+
|
|
225
|
+
- Never ask for a token, key or password in chat. If the user pastes one anyway, do not repeat it. Tell them to remove it from the chat and rotate it in the CMS.
|
|
226
|
+
- Tokens live in `.env.local`. Only the user pastes them there, or runs `areca init` in their terminal.
|
|
227
|
+
- Check that a value is set with the length check. Never print the value. Never write it into a file that Git tracks (`.env.example` has empty values only).
|
|
228
|
+
- The site token and the schema token are server secrets. Never use a `VITE_`, `NEXT_PUBLIC_` or `PUBLIC_` prefix for them.
|
|
229
|
+
- A personal MCP key (`areca_mcp_…`) follows the same rules. OAuth needs no key, so prefer it.
|
|
230
|
+
|
|
231
|
+
## Re-run mode
|
|
232
|
+
|
|
233
|
+
Use this when `areca.config.ts`, the SDK dependency or `areca.gen.ts` already exists.
|
|
234
|
+
|
|
235
|
+
1. Do not install the SDK again. Do not run `areca init` again. Do not overwrite `.env.local`.
|
|
236
|
+
2. Show the current state: collections and sections from `areca.config.ts`, or from `get_site_info` if MCP is connected. Note the languages and the publishing mode.
|
|
237
|
+
3. Decide the schema source from the header of `areca.config.ts`:
|
|
238
|
+
- It has the header `// Generated by \`areca manifest pull\`.`: **MCP-first**. Change the schema with MCP (`upsert_collection`, `upsert_global`, `set_site_languages`) after the approval. Then run `<pm> run content:sync </dev/null`.
|
|
239
|
+
- Anything else: **code-first**. Edit `areca.config.ts` after the approval. Then run `<pm> run sync-manifest` (needs `ARECA_SCHEMA_TOKEN`), then `<pm> run content:pull`.
|
|
240
|
+
This is how to read the `areca-mcp` advice "if the site syncs its schema from code, prefer areca.config.ts": the header tells you which kind of site it is. Do not switch a site from one kind to the other without asking the user.
|
|
241
|
+
4. Ask what the user wants to add or change. Typical requests: a new collection (for example vacancies), a new field, a new language, a new page.
|
|
242
|
+
5. For new or changed parts, go through the same flow: the interview questions that apply, the approval gate (step 3), the schema (step 4b), the wiring (step 5), and a release (step 6). Skip the parts that are done.
|
|
243
|
+
6. For removals, fields that hold content, or languages: explain what is lost. Get explicit confirmation before any change.
|
|
244
|
+
7. For an existing live site, follow the note in the ground rules. Use hidden collections (`enabled: false`) or a separate site for experiments.
|
|
245
|
+
8. Finish with the step 7 summary, only for the parts that changed.
|