@areca-cms/skills 0.3.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.
@@ -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.
@@ -0,0 +1,123 @@
1
+ # Connect the CMS
2
+
3
+ This file covers four things: the MCP connection, creating the site in the CMS, tokens, and demo mode. Use the `areca-mcp` skill for the full connection list and the tool reference.
4
+
5
+ ## The connector URL
6
+
7
+ Every site has its own MCP endpoint:
8
+
9
+ ```text
10
+ <cms-url>/api/mcp/<site-slug>
11
+ ```
12
+
13
+ For example `https://cms.example.com/api/mcp/acme-site`. The site's **Connect AI** page in the CMS shows the exact URL. Use that page when you are unsure. The server name in the app is `areca-<site-slug>`.
14
+
15
+ The URL contains no secret. It is safe to commit in a project MCP file.
16
+
17
+ ## Sign-in options
18
+
19
+ - **OAuth (preferred):** add only the URL. On first use, the app opens a browser. The user signs in to Areca, picks what the AI may do, and approves. No key is stored in a file.
20
+ - **Personal key:** the user creates it in the CMS under Connect AI › Advanced: personal keys › Create AI key. It is shown once. It starts with `areca_mcp_`. Use it only when the app cannot do OAuth. The user adds it to `.env.local` or to the app's own secret store. Never paste it into chat.
21
+
22
+ ## Connect a coding agent
23
+
24
+ | App | Command or file |
25
+ | --- | --- |
26
+ | Claude Code | `claude mcp add --transport http areca-<slug> <url>`, then run `/mcp` and choose Authenticate. |
27
+ | Claude Code (project file) | `.mcp.json`: `{"mcpServers":{"areca-<slug>":{"type":"http","url":"<url>"}}}` |
28
+ | Cursor | `.cursor/mcp.json`: `{"mcpServers":{"areca-<slug>":{"url":"<url>"}}}` |
29
+ | VS Code / GitHub Copilot | `.vscode/mcp.json`: `{"servers":{"areca-<slug>":{"type":"http","url":"<url>"}}}` |
30
+ | Codex | `.codex/config.toml` with `[mcp_servers.areca-<slug>]` and `url = "<url>"`, then `codex mcp login areca-<slug>` |
31
+ | Other apps | The app's remote or HTTP MCP server setting, with the URL. The Connect AI page has the steps for each app. |
32
+
33
+ Rules for file-based config:
34
+
35
+ - Merge into the existing file. Keep the other servers.
36
+ - Do not replace a file the user already has without asking.
37
+ - Commit only the URL-based config. Never commit a key.
38
+
39
+ ## Install the Areca skills too (optional)
40
+
41
+ This command writes the Areca skills and the connector into the coding agents the user picks:
42
+
43
+ ```bash
44
+ npx @areca-cms/skills add --mcp-url <url>
45
+ ```
46
+
47
+ It asks which agents to use. With `-y` it also needs `--agent`. Offer it only if the user wants the skills in the same step.
48
+
49
+ ## Check the role
50
+
51
+ Call `get_site_info`. Read `you.role` and `cannotDo`.
52
+
53
+ | Role | What you can do |
54
+ | --- | --- |
55
+ | Editor | Read, create and edit drafts. |
56
+ | Owner | Also mark ready, archive and delete. |
57
+ | Owner with "Allow going live" | Also go live and schedule. |
58
+ | Agency admin | Also change the schema (`upsert_collection`, `upsert_global`) and languages (`set_site_languages`). Also change the publishing mode. |
59
+
60
+ - Schema changes need an agency admin. If the user is not one, use code-first.
61
+ - Going live needs "Allow going live" on the connection, or an owner who presses Go live in the CMS.
62
+ - Agency admins need two-factor authentication on. A `403 mfa_required` means it is not on. The user must turn it on in the account settings.
63
+
64
+ ## Reload after connecting
65
+
66
+ After the connector is added, the agent session may not see the tools yet.
67
+
68
+ - In Claude Code, run `/mcp` and choose Authenticate, then check that the server is connected.
69
+ - In other apps, reload the window or restart the session.
70
+ - Then call `get_site_info` again. If the tools still do not appear, check the URL and the sign-in, and read the troubleshooting table below.
71
+
72
+ ## Create the site in the CMS
73
+
74
+ Creating a site and its tokens happens in the CMS, by a person with agency access. The agent cannot do it over MCP. Walk the user through these steps. Do not guess a key or a token.
75
+
76
+ 1. In the CMS, open **Agency**. Create the client if it does not exist: **New client**, a name, and the suggested slug.
77
+ 2. Open the client. On the **Sites** tab, select **New site**.
78
+ 3. Enter the **Site name**. Keep the suggested **Site key**. It must match `siteKey` in `areca.config.ts`. Write it down.
79
+ 4. Enter the **Production URL**. It is required. Use `http://localhost:<dev port>` for now (for example `http://localhost:3001`). It enables preview links.
80
+ 5. Select **Create site**.
81
+ 6. The next screen shows the site token. **It is shown once.** Copy it and store it in a password manager. Then select **I've saved it**.
82
+ 7. The schema-write token is only needed for code-first. Get it in the site's **Settings › Developer**, under **Schema-write token**, with **Rotate schema token**. Copy it when it is shown, the same way.
83
+
84
+ If the user lost a token, rotate it in the site's **Settings › Developer** tab. Rotating a token stops the old one at once. Any build that still uses it fails until its `.env.local` is updated.
85
+
86
+ ## Where each token goes
87
+
88
+ | Token | Where | Used by |
89
+ | --- | --- | --- |
90
+ | Site token | `.env.local` as `ARECA_SITE_TOKEN=` | `areca init`, `areca pull`, `areca manifest pull`, the content reads |
91
+ | Schema-write token | `.env.local` as `ARECA_SCHEMA_TOKEN=` | `areca manifest push` only (code-first) |
92
+ | MCP personal key | `.env.local` as `ARECA_MCP_KEY=` (only if the app needs it) | the MCP client |
93
+
94
+ Rules:
95
+
96
+ - The user pastes tokens into `.env.local`, or runs `areca init` in their terminal, which asks for the token with hidden input.
97
+ - Check a value by its length. Never print it.
98
+ - Never put a token in a `VITE_`, `NEXT_PUBLIC_` or `PUBLIC_` variable.
99
+ - Keep `.env.local` out of Git. `areca init` adds it to `.gitignore`. Check it.
100
+
101
+ ## Demo mode and production mode
102
+
103
+ Each site has a publishing mode. New sites start in production.
104
+
105
+ - **Demo** ("Demo — no production deployment"): going live creates a demo release. `areca pull` can fetch it. Visitors never see it. No server is needed. Use it for the first release.
106
+ - **Production**: going live builds and deploys the website. It needs a Dokploy deployment target, an application ID and a health check URL. See the `areca-sdk` skill, `references/production.md`.
107
+
108
+ Set the mode in the CMS under **Settings › Deployment › Mode**. An agency admin can also ask the agent to set it. Ask the user before you change the mode.
109
+
110
+ - A site that has ever gone live in production cannot switch to demo. Change the mode in Settings › Deployment instead, or use another site for the demo.
111
+
112
+ ## Troubleshooting the connection
113
+
114
+ | Symptom | What to do |
115
+ | --- | --- |
116
+ | 401, "Sign in to connect" | Run the app's sign-in step (for example `/mcp` in Claude Code, or `codex mcp login`). |
117
+ | 401, "Key is for a different site" | Use the connector URL of the key's site. |
118
+ | 401, "This app is no longer connected" | The user removed it in Connect AI. Add the connector again. |
119
+ | 403, `mfa_required` | An agency admin must turn on two-factor authentication. |
120
+ | 404, "Site not found" | The site slug in the URL is wrong. Check it on the Connect AI page. |
121
+ | Schema tools missing | The role is not agency admin. Use code-first. |
122
+ | Go-live tools missing | Reconnect with "Allow going live" ticked (owners only), or ask an owner to press Go live. |
123
+ | `429` | Wait for the `Retry-After` time. The limit is 120 requests per minute per credential. |
@@ -0,0 +1,181 @@
1
+ # First release
2
+
3
+ The first release gives the project something to pull. `areca pull` fails with "No publication exists" until a release is live, and `areca.gen.ts` is only written by a successful pull. So the release comes before the first build check.
4
+
5
+ Plan:
6
+
7
+ 1. Check the publishing mode.
8
+ 2. Create sample entries.
9
+ 3. Fill the sections.
10
+ 4. Mark everything ready.
11
+ 5. Ask, then go live.
12
+ 6. Wait for the build to finish.
13
+ 7. Pull.
14
+ 8. Verify.
15
+ 9. Decide what to do with the samples.
16
+
17
+ Steps 2 to 6 use MCP tools. Without MCP, see [Code-first](#code-first-without-mcp).
18
+
19
+ ## 1. Check the publishing mode
20
+
21
+ Call `get_site_info`. Read `site.publishingMode` and `site.deploymentConfigured`. To learn whether the site was ever live, call `list_publications`: any publication with status `live`, or with `publishingMode: "production"` and a `deployedAt` date, means it has gone live.
22
+
23
+ Older CMS versions do not report `deploymentConfigured` and do not list `set_publishing_mode`. Then treat the deployment as not configured, and ask the user to change the mode in the UI (below).
24
+
25
+ - **Demo:** continue.
26
+ - **Production, never live:** explain the choice. Demo means the release is pulled by `areca pull` and never shown to visitors. Production means the site builds and deploys. For the first release, use demo.
27
+ - Agency admin, and `set_publishing_mode` is in your tool list: ask the user for a yes, then call it with `mode: "demo"`.
28
+ - Anyone else: ask the user to change it in **Settings › Deployment › Mode** (Demo, no production deployment), then wait.
29
+ - **Production, already live:** stop. Do not go live. A live production site must not get sample content. Ask the user whether to use a separate demo site. Read [connect.md](connect.md) for demo mode.
30
+
31
+ ## 2. Create sample entries
32
+
33
+ Get the schema for each collection before you write (`get_collection_schema`). Create in dependency order: referenced entries first. For example, authors before posts, departments before vacancies.
34
+
35
+ For each collection:
36
+
37
+ - The title starts with `[Sample]`, for example `[Sample] Our first post`. If the collection has no title field, put the prefix on its main text field instead (for example the `name` of categories).
38
+ - Pass the slug inside `fields`, as the `example` in `get_collection_schema` does: `fields: { slug: "sample-our-first-post", ... }`. It is lowercase with dashes.
39
+ - Fill every required field with realistic content. Keep it short, but complete.
40
+ - Use the company name and details from the interview where they fit.
41
+ - Fill the full SEO object. Follow the rules in the `areca-mcp` skill (title 50 to 60 characters, description 140 to 160, focus keyphrase, a 2 to 3 sentence summary, 3 to 5 key takeaways, FAQ only when the body answers questions).
42
+ - Images: do not guess image links. Use an image only when the user gives you a direct link, through `upload_asset_from_url` with alt text. Otherwise leave image fields empty.
43
+ - Rich text is Markdown, not HTML.
44
+
45
+ On a multilingual site:
46
+
47
+ - Write the main language with `create_entry` (no `locale`).
48
+ - Write each other language with one `update_entry` per language, with `locale` set. Fill the required fields in every required language.
49
+ - Check `translations` with `get_entry` before you mark it ready.
50
+
51
+ Then check the result with `list_entries` (status `draft`) and `get_entry` for one sample.
52
+
53
+ ## 3. Fill the sections
54
+
55
+ For each section in the plan:
56
+
57
+ 1. `get_global` with the section key. Note the `id` and the `fields`.
58
+ 2. `update_global` with every required field. Use the company details from the interview for `companyInfo`. For other copy, write short placeholder text, and say so to the user.
59
+ 3. For `seo: true` sections, fill `seo` with the same rules as entries.
60
+ 4. If the section needs a page preview, check that `previewPath` is set.
61
+
62
+ ## 4. Mark everything ready
63
+
64
+ `mark_ready` approves each entry and section for the next release. It does not change the live site yet. It needs an owner or an agency admin.
65
+
66
+ Mark ready every sample entry and every section that has its required fields. Report any refusal. A refusal that names languages means a language is still missing: fill it, then try again.
67
+
68
+ ## 5. Ask, then go live
69
+
70
+ Before you call `go_live`, ask the user:
71
+
72
+ > "Go live now in demo mode? This publishes N entries and M sections to the demo release. Visitors do not see it. Shall I continue?"
73
+
74
+ Only continue on a clear yes. `go_live` needs "Allow going live" on the connection, or an owner or agency admin. If the connection lacks it, ask the user to press **Go live** in the CMS, and wait for them.
75
+
76
+ When you have the yes, call `go_live` with a short note, for example "Quickstart first release". It returns `publicationId` and `jobId`.
77
+
78
+ ## 6. Wait for the build
79
+
80
+ Poll `get_build_job` with the `jobId`. Wait about 10 seconds between calls.
81
+
82
+ - Active statuses: `queued`, `building`, `validating`, `deploying`. Keep polling.
83
+ - Final statuses: `succeeded`, `failed`, `cancelled`. Stop.
84
+
85
+ Stop after about 5 minutes. Then ask the user to look at the release in the CMS.
86
+
87
+ On `failed`, read `error` and show it to the user. Common causes are a required section that is not ready, or a schema problem. Fix the cause with the user's yes, then start again from step 4.
88
+
89
+ Also call `get_release_status` once at the end. Check that `pendingChanges` is empty.
90
+
91
+ ## 7. Pull
92
+
93
+ Run the pull directly. The schema is already in `areca.config.ts` from step 4b, so there is no need for `manifest pull` here:
94
+
95
+ ```bash
96
+ <pm> exec areca pull --out src/generated/content
97
+ ```
98
+
99
+ Expect output like:
100
+
101
+ ```text
102
+ Pulled publication <id> (<hash>): posts=3, authors=2, ...
103
+ Types: src/generated/content/areca.gen.ts
104
+ ```
105
+
106
+ - The `Types:` line means `areca.gen.ts` now exists. Tell the user to commit it.
107
+ - A `Warning:` line about an older publication means it was built before the schema was embedded. Ask the user to go live again.
108
+ - Without a terminal, `manifest pull` stops only when the pull would remove something: a collection, section, field, language, or the main language. It names the removal and asks for `--yes`. Then tell the user the removal you expect (from the plan), and ask for a yes. Use `--yes` only after that yes. Or ask the user to run `<pm> exec areca manifest pull` in their terminal, where it prints the diff and asks. Additions and changes apply without a question.
109
+ - A config without the header (see step 8.0) stops once even when nothing is removed. This is the one-time upgrade. Use `--yes` only after the user says yes.
110
+
111
+ ## 8. Verify
112
+
113
+ Run these checks in order. Stop at the first failure and report it.
114
+
115
+ 0. The one-command flow. Run `<pm> run content:sync </dev/null` once. It runs `areca manifest pull`, then `areca pull`. Expect `./areca.config.ts is already up to date` and then the pull output. Without a terminal, the manifest pull never waits for a key. If something would be removed, it stops with an error that names the removal. Then show the user the `-` lines of the diff and ask before you add `--yes`.
116
+ - A config written by `areca manifest pull` has the header ``// Generated by `areca manifest pull`.``. Only removals ask for a yes.
117
+ - A config from an older SDK has no header. The first run stops once with `already defines N collection(s). Re-run with --yes to overwrite it.`. Ask the user for a yes, then run `<pm> exec areca manifest pull --yes` once. After that the file has the header.
118
+
119
+ 1. Typecheck. The first time, this is after the pull: `areca.gen.ts` is written by the pull. For TanStack, generate the route tree first (`<pm> run generate-routes`, or `<pm> exec tsr generate`). Then use the project's script, or `<pm> exec tsc --noEmit`. Expect no errors in the new files.
120
+ 2. Build. `<pm> run build`. Expect success. If the build reads content, it must find the pulled files.
121
+ 3. Dev server. Start it with `<pm> run dev` in the background. Use the port from step 0.
122
+ 4. Pages. For each list route (for example `/blog` and `/vacancies`, and their Dutch versions `/nl/blog` and `/nl/vacatures`), check that it returns `200`. For each sample entry, request its page and check the status:
123
+
124
+ ```bash
125
+ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:<port>/blog/sample-our-first-post
126
+ ```
127
+
128
+ Expect `200`. Check that the sample title appears in the HTML:
129
+
130
+ ```bash
131
+ curl -s http://localhost:<port>/blog/sample-our-first-post | grep -c "Our first post"
132
+ ```
133
+
134
+ Do this for one page of each list and each detail route. Use the real route from the plan.
135
+ 5. Home and about pages: `200`, and the hero or heading text from the sections.
136
+ 6. Health route (only if it was added): `curl -s http://localhost:<port>/api/health` should show `"ok":true` and a `publicationId`.
137
+ 7. Preview (only if it was added): open the URL that `get_preview_url` returns for a sample entry. It needs the production URL in the CMS to be the local dev URL. Expect the page to show a draft banner or the draft text.
138
+ 8. Stop the dev server when you are done, unless the user wants it running.
139
+
140
+ Report the results in a short list: what passed, what did not, and the URLs you checked.
141
+
142
+ ## 9. The samples
143
+
144
+ Ask the user:
145
+
146
+ > "Keep the sample entries as examples for your editors, or archive them?"
147
+
148
+ - **Keep:** leave them. Tell the user to edit or delete them in the CMS when the real content is ready.
149
+ - **Archive:** call `archive_entry` only after a yes. It needs an owner. Archived entries leave the live site at the next go live.
150
+ - Do not delete anything. Delete is not part of this skill.
151
+
152
+ ## Code-first (without MCP)
153
+
154
+ Without MCP, the agent cannot create entries or mark them ready. The user does that in the CMS:
155
+
156
+ 1. Ask the user to open the site in the CMS and create one sample entry per collection (the title, or the main text field, starts with `[Sample]`).
157
+ 2. Ask the user to fill in the required sections (site content) in the CMS.
158
+ 3. Ask the user to mark the entries ready, and then to go live in demo mode from the **Go-live panel**.
159
+ 4. When the user says it is done, run `<pm> run content:pull`, then do the checks in step 8.
160
+
161
+ If the schema was written in code, `areca pull` works after the release.
162
+
163
+ ## Troubleshooting
164
+
165
+ | Symptom | Cause and fix |
166
+ | --- | --- |
167
+ | `No publication exists for this site. Publish content in the CMS before running areca pull.` | No release is live. Finish steps 4 to 6, then pull. |
168
+ | `401` on pull, manifest pull or push | The token is wrong, rotated, or the wrong kind. The pull and the manifest pull use the site token. The push needs the schema token. Check the length with the step 0 check. Rotate in **Settings › Developer** if needed, then update `.env.local`. Restart the dev server after a change, because env files load at start. |
169
+ | `403` with `mfa_required` | The agency admin must turn on two-factor authentication. Schema and language tools are blocked until then. |
170
+ | Go live is refused because a required section is not ready | Fill the required fields with `update_global`, then `mark_ready` the section. |
171
+ | `Removing <key.field> deletes content` or `FieldDropsRequiredError` | Nothing was pushed. Show the list to the user. Only confirm with their explicit yes, using `--confirm-drop <key.field>`. |
172
+ | `Publication does not match its schema` | An entry breaks the schema. The message names the entry and field. Fix the entry, go live again, then pull. Nothing was written. |
173
+ | `No content file for collection "<key>"` | Run the pull. Check the key: a `blog-posts` key is read as `blogPosts` in code. |
174
+ | `Expected publication X, received Y` | `ARECA_SNAPSHOT_ID` is set in the environment. Unset it for local work. It is for pinned builds only. |
175
+ | `Failed to load TypeScript config … Use Node.js 22.18 or newer, or retry with tsx` | Upgrade Node, or run the command through `tsx`: `<pm> exec tsx ./node_modules/@areca-cms/site-sdk/dist/cli.js pull`. |
176
+ | Build fails with a missing module under `src/paraglide` | The Paraglide compile did not run before the pull. Run the compile first, as in [frameworks.md](frameworks.md). |
177
+ | `areca manifest pull` says "Remove … Re-run with --yes to confirm" | The pull would remove a collection, section, field, or language. It is not a terminal, so it cannot ask. Show the user the diff (run it in their terminal), then confirm. Use `--yes` only after the yes. |
178
+ | `areca manifest pull` says it "already defines N collection(s). Re-run with --yes" | The config was not written by `manifest pull` (no header) and it has collections. N counts the site content sections too. Show the user the diff, then confirm as above. After the one-time `--yes`, the header is there and only removals ask. |
179
+ | Preview link shows "expired" or "invalid" | Preview links last about an hour. Create a new link with `get_preview_url`. |
180
+ | `Something went wrong on the Areca server (ref …)` | Nothing is confirmed saved. Retry once, then report the ref to the user. |
181
+ | Pages show no content after the pull | The dev server started before the pull. Restart it. Check that `src/generated/content/manifest.json` has a `publicationId`. |