@areca-cms/skills 0.1.1 → 0.2.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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to `@areca-cms/skills`.
4
4
 
5
+ ## 0.2.0 (2026-10-11)
6
+
7
+ ### Features
8
+
9
+ - copy media into client sites on areca pull (da09a0c)
10
+
5
11
  ## 0.1.1 (2026-10-10)
6
12
 
7
13
  No user-facing changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@areca-cms/skills",
3
- "version": "0.1.1",
3
+ "version": "0.2.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.1.1"
6
+ version: "0.2.0"
7
7
  ---
8
8
 
9
9
  # Areca MCP
@@ -24,7 +24,7 @@ Unknown field keys are refused, and the error lists the valid ones. Entry data i
24
24
  - Use `##` for sections and `###` or `####` for subsections. Other heading levels are clamped.
25
25
  - Separate paragraphs with a blank line. `**bold**`, `*italic*`, `[link](https://…)`, lists, `>` quotes and tables all work.
26
26
  - Images: `![alt text](asset:<assetId>)`. The asset must be in this client's Library. Read-back keeps the `asset:` form, so the text can be sent again as is.
27
- - Never send HTML: it is not rendered, and the tags end up as visible text. A full https image URL works for images, but uploaded assets are better.
27
+ - Never send HTML: it is not rendered, and the tags end up as visible text. A full https image URL is copied into the Library on save; if the copy fails it stays external and the result lists it in `warnings`. Uploaded assets are still better, because you set their alt text.
28
28
 
29
29
  ## SEO object (`seo` on create/update)
30
30
 
@@ -3,7 +3,7 @@ name: areca-sdk
3
3
  description: Connects a website project to Areca CMS with the @areca-cms/site-sdk package. Covers setup, tokens and env vars, areca.config.ts collections and field types, the areca CLI (init, manifest push/pull, pull, run), reading pulled content, rich text, SEO head tags, draft preview routes and Go-live builds. Use when a project imports @areca-cms/site-sdk, has an areca.config.ts, mentions ARECA_* env vars, or the user wants to add, render or deploy Areca CMS content.
4
4
  license: MIT
5
5
  metadata:
6
- version: "0.1.1"
6
+ version: "0.2.0"
7
7
  ---
8
8
 
9
9
  # Areca site SDK
@@ -31,7 +31,7 @@ pnpm exec areca init # interactive; writes config, env files, s
31
31
  pnpm exec areca init --cms-url https://cms.example.com --token "$ARECA_SITE_TOKEN" --site-key acme-site --yes
32
32
  ```
33
33
 
34
- `init` writes `areca.config.ts`, `.env.example`, `.env.local` (`ARECA_CMS_URL`, `ARECA_SITE_TOKEN`), `.gitignore` entries, `src/generated/content/manifest.json`, and the package scripts `sync-manifest` and `content:pull`. It also wraps `dev` in `areca run --`. Use `--force` to overwrite an existing config. `--out` and `--config` change the paths.
34
+ `init` writes `areca.config.ts` (including an `assets` block), `.env.example`, `.env.local` (`ARECA_CMS_URL`, `ARECA_SITE_TOKEN`), `.gitignore` entries (content and media folders), `src/generated/content/manifest.json`, and the package scripts `sync-manifest` and `content:pull`. It also wraps `dev` in `areca run --`. Use `--force` to overwrite an existing config. `--out` and `--config` change the paths. Media flags: `--assets-dir <dir>` (default `public/areca`), `--assets-public-path <path>` (only for folders outside `public/`), `--no-assets`. On an existing config, init inserts an `assets` block if there is none.
35
35
 
36
36
  | Env var | Needed for | Where the user gets it |
37
37
  | --- | --- | --- |
@@ -75,15 +75,24 @@ export default defineSiteContent({
75
75
  - Field types: `text`, `textarea`, `richtext`, `image`, `date`, `datetime`, `select` (`options`), `reference` (`collection`), `slug`, `boolean`, `number`, `url`. Optional per field: `required`, `description`, `after` (date or datetime key this must be on or after).
76
76
  - Keys match `^[A-Za-z][A-Za-z0-9_-]{0,63}$`. Collection keys must be unique case-insensitively. Reserved: `manifest`, `constructor`, `prototype`, `__proto__`, and Windows device names (`con`, `prn`, `aux`, `nul`, `com1`, `lpt1`, ...).
77
77
  - A push is the **full** manifest. Collections left out are disabled (their entries are kept). The CMS adds a required `slug` field if one is missing. Limits: 100 collections, 100 fields each, 256 KiB.
78
- - `areca manifest pull --config areca.config.ts [--yes]` regenerates the config from the CMS. It replaces the whole file and keeps `siteKey`. Without a TTY it needs `--yes` if the config already has collections.
78
+ - `areca manifest pull --config areca.config.ts [--yes]` regenerates the config from the CMS. It replaces the whole file and keeps `siteKey` and `assets`. Without a TTY it needs `--yes` if the config already has collections.
79
+
80
+ ### Media (`assets`)
81
+
82
+ ```ts
83
+ assets: { download: true, dir: "public/areca" /*, publicPath: "/areca" */ }, // top level of defineSiteContent
84
+ ```
85
+
86
+ `areca pull` copies every file the content uses (image fields, SEO images, rich-text images and file links) into `dir` and rewrites URLs to `<publicPath>/<name>-<id>.<ext>`, so the deployed site never calls the CMS. `publicPath` is derived for folders under `public/`; set it for others (e.g. SvelteKit `static/`). SEO image URLs become absolute with the site's production URL. `download: false` keeps CMS URLs. The setting is local only; `manifest push` does not send it. A failed download fails the pull without changing the current content.
79
87
 
80
88
  ## CLI
81
89
 
82
90
  ```text
83
- areca init [--cms-url <url>] [--token <t>] [--site-key <key>] [--out <dir>] [--config <path>] [--yes] [--force]
91
+ areca init [--cms-url <url>] [--token <t>] [--site-key <key>] [--out <dir>] [--config <path>]
92
+ [--assets-dir <dir>] [--assets-public-path <path>] [--no-assets] [--yes] [--force]
84
93
  areca manifest push [config] # needs ARECA_SCHEMA_TOKEN (+ URL and site token)
85
94
  areca manifest pull [--config <path>] [--yes]
86
- areca pull [--out <dir>] [--publication <id>] # default out: src/generated/content
95
+ areca pull [--out <dir>] [--publication <id>] [--config <path>] # default out: src/generated/content; media: public/areca
87
96
  areca run -- <command> # run a command with .env.local/.env loaded
88
97
  ```
89
98
 
@@ -106,7 +115,7 @@ const post = articles.find((a) => a.slug === slug);
106
115
  ```
107
116
 
108
117
  - Entry: `{ id, slug, publishedAt, data, seo? }`. The field values live in `data`. You write the types yourself because there is no codegen.
109
- - `ImageValue` = `{ url, width|null, height|null, alt, mimeType }`, where `url` is absolute on the CMS origin. `ReferenceValue` = `{ collection, slug, id }`. Optional and image fields can be `null` or missing, so check them.
118
+ - `ImageValue` = `{ url, width|null, height|null, alt, mimeType }`, where `url` is the local path after `areca pull` (e.g. `/areca/hero-3f2a91c0.jpg`), or an absolute CMS URL with `assets.download: false`. Serve the media folder with the site (it is part of `public/` by default). `ReferenceValue` = `{ collection, slug, id }`. Optional and image fields can be `null` or missing, so check them.
110
119
  - `readContent` reads files at runtime, so ship `src/generated/content/` (including `.publications/`) with the server build or container. For TanStack Start, call it inside a `createServerFn` handler, never in route or component code.
111
120
 
112
121
  ## Rich text
@@ -29,13 +29,13 @@ ESM only. Import paths and their exports:
29
29
  | `fetchSnapshot(opts?: { publicationId?: string }): Promise<Snapshot>` | `GET /api/sites/snapshot/current[?publicationId=]` | site token |
30
30
  | `fetchPreview(token: string): Promise<PreviewResult>` | `GET /api/sites/preview?token=` | signed preview token |
31
31
 
32
- Types: `ArecaClient`, `ArecaClientOptions`, `SiteContentConfig`, `CollectionConfig` (`{ route; label?; fields: Field[] }`), `Field` (`{ key; label; type: FieldType; required?; options?; collection?; description?; after? }`), `FieldType`, `SiteManifest`, `Snapshot` (`{ publicationId, siteKey, createdAt, hash, collections: Record<string, SnapshotEntry[]> }`), `SnapshotEntry` (`{ id, slug, publishedAt: string | null, data: Record<string, unknown>, seo?: SeoMeta }`), `ImageValue`, `ReferenceValue`, `RichTextValue`, `SeoMeta`, `PreviewResult`, `PulledContentManifest`, `HeadMeta`, `HeadLink`, `HeadScript`, `SeoHeadOptions`, `SeoHeadResult`.
32
+ Types: `ArecaClient`, `ArecaClientOptions`, `SiteContentConfig`, `CollectionConfig` (`{ route; label?; fields: Field[] }`), `Field` (`{ key; label; type: FieldType; required?; options?; collection?; description?; after? }`), `FieldType`, `SiteManifest`, `Snapshot` (`{ publicationId, siteKey, createdAt, hash, collections: Record<string, SnapshotEntry[]>, assets?: SnapshotAsset[], siteUrl? }`), `SnapshotAsset` (`{ id, storageKey, url, filename, mimeType, size }`), `AssetsConfig` (`{ download?, dir?, publicPath? }`), `SnapshotEntry` (`{ id, slug, publishedAt: string | null, data: Record<string, unknown>, seo?: SeoMeta }`), `ImageValue`, `ReferenceValue`, `RichTextValue`, `SeoMeta`, `PreviewResult`, `PulledContentManifest`, `HeadMeta`, `HeadLink`, `HeadScript`, `SeoHeadOptions`, `SeoHeadResult`.
33
33
 
34
34
  ## `@areca-cms/site-sdk/pull` (Node only)
35
35
 
36
36
  | Export | Signature | Notes |
37
37
  | --- | --- | --- |
38
- | `pullContent` | `({ outDir: string; client?: ArecaClient; publicationId?: string }) => Promise<Snapshot>` | Writes `outDir/.publications/publication-<random>/<collection>.json`, then atomically swaps `manifest.json`, which records the `publicationId`. Defaults `publicationId` to `ARECA_SNAPSHOT_ID`. A failed pull keeps the previous generation. |
38
+ | `pullContent` | `({ outDir: string; client?: ArecaClient; publicationId?: string; assets?: { dir: string; publicPath: string } }) => Promise<PullContentResult>` | With `assets`, downloads media into `dir` (absolute) and rewrites URLs to `publicPath`. Writes `outDir/.publications/publication-<random>/<collection>.json`, then atomically swaps `manifest.json`, which records the `publicationId`. Keeps the current and two previous generations. Defaults `publicationId` to `ARECA_SNAPSHOT_ID`. A failed pull keeps the previous generation. Result (`PullContentResult`) adds `localAssets?` and `warnings`. The `assets` option type is `ResolvedAssets`. |
39
39
  | `readContentManifest` | `(outDir: string) => PulledContentManifest` | `{ publicationId, hash, createdAt, collections counts, ... }` |
40
40
  | `readContent` | `<T = SnapshotEntry>(outDir: string, collectionKey: string, manifest?: PulledContentManifest) => T[]` | Throws `No content file for collection "x" ... Run \`areca pull\` first.` |
41
41
 
@@ -54,6 +54,7 @@ Set the CMS health check URL to this route, e.g. `https://www.example.com/api/he
54
54
  - The CMS deploy passes the build arg `ARECA_SNAPSHOT_ID`, and `areca pull` fetches exactly that publication. Declare the arg right before the pull step so the cache is busted for each release.
55
55
  - Pass `ARECA_SITE_TOKEN` as a build secret, not as an ARG or ENV in the image.
56
56
  - Copy `src/generated` into the runtime image when the server reads content at runtime.
57
+ - Media lands in `public/areca` before the build, so the framework bundles it with other static files. With a custom `assets.dir`, make sure the build or image includes it.
57
58
 
58
59
  ```dockerfile
59
60
  ARG ARECA_CMS_URL