@contentrain/skills 0.5.2 → 0.6.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/README.md
CHANGED
|
@@ -127,7 +127,7 @@ This reduces always-loaded context from thousands of lines to just the essential
|
|
|
127
127
|
|
|
128
128
|
`@contentrain/skills` is kept in lockstep with the MCP tool registry via cross-package parity tests (`tests/mcp-parity.test.ts`):
|
|
129
129
|
|
|
130
|
-
- `skills/contentrain/references/mcp-tools.md` must have an `### <tool>` heading for every tool in the MCP `TOOL_NAMES` registry (currently
|
|
130
|
+
- `skills/contentrain/references/mcp-tools.md` must have an `### <tool>` heading for every tool in the MCP `TOOL_NAMES` registry (currently 24: 19 core + 5 media).
|
|
131
131
|
- Key skills (normalize, translate) must not reference legacy `contentrain/{operation}/...` branch prefixes — MCP now emits `cr/*`.
|
|
132
132
|
|
|
133
133
|
When MCP's surface changes, these tests fail until the skill docs catch up.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrain/skills",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "AI agent skills for Contentrain — workflow procedures, framework integration guides",
|
|
6
6
|
"type": "module",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"tsdown": "^0.21.0",
|
|
62
62
|
"typescript": "^5.7.0",
|
|
63
63
|
"vitest": "^3.0.0",
|
|
64
|
-
"@contentrain/mcp": "1.
|
|
64
|
+
"@contentrain/mcp": "1.10.0"
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
67
67
|
"build": "tsdown src/index.ts --format esm,cjs --dts",
|
|
@@ -357,3 +357,67 @@ Run git-backed batch operations on existing content entries.
|
|
|
357
357
|
- `copy_locale` MUST NOT be used on non-i18n models
|
|
358
358
|
- Bulk operations create branches and commits like other write tools
|
|
359
359
|
- Validate afterward when content shape may have changed
|
|
360
|
+
|
|
361
|
+
## Media Tools
|
|
362
|
+
|
|
363
|
+
Media tools are a deterministic passthrough to the provider's media stack. They are **registered only when the provider exposes one** (e.g. Studio MCP Cloud) — local stdio servers and plain GitHub/GitLab providers never list them. The flow: list assets → pick a `media/...` path → reference it in media/image/file fields via `contentrain_content_save` (paths are normalized to absolute delivery URLs when the provider sets `mediaBaseUrl`).
|
|
364
|
+
|
|
365
|
+
### contentrain_media_list
|
|
366
|
+
|
|
367
|
+
List media assets with optional filtering and cursor pagination. Read-only.
|
|
368
|
+
|
|
369
|
+
| Parameter | Type | Required | Description |
|
|
370
|
+
|-----------|------|----------|-------------|
|
|
371
|
+
| `search` | string | No | Substring match on filename/path/alt |
|
|
372
|
+
| `tag` | string | No | Only assets carrying this tag |
|
|
373
|
+
| `limit` | number | No | Page size (1–100, provider may clamp) |
|
|
374
|
+
| `cursor` | string | No | Opaque cursor from a previous response |
|
|
375
|
+
|
|
376
|
+
Returns `{ assets[], next_cursor?, total? }`. Each asset carries `id`, `path` (`media/...`), optional `url`, `mime`, `size`, `alt`, `tags`, `createdAt`, `meta`.
|
|
377
|
+
|
|
378
|
+
### contentrain_media_get
|
|
379
|
+
|
|
380
|
+
Get a single media asset by id. Read-only.
|
|
381
|
+
|
|
382
|
+
| Parameter | Type | Required | Description |
|
|
383
|
+
|-----------|------|----------|-------------|
|
|
384
|
+
| `id` | string | Yes | Asset id from `contentrain_media_list` |
|
|
385
|
+
|
|
386
|
+
Returns `{ asset }` or an error with a discovery hint for unknown ids.
|
|
387
|
+
|
|
388
|
+
### contentrain_media_ingest
|
|
389
|
+
|
|
390
|
+
Ingest an asset from a source URL. The provider fetches the URL server-side under its own SSRF/MIME/size policy — MCP never fetches it. The only open-world tool (`openWorldHint: true`).
|
|
391
|
+
|
|
392
|
+
| Parameter | Type | Required | Description |
|
|
393
|
+
|-----------|------|----------|-------------|
|
|
394
|
+
| `url` | string | Yes | Source URL to fetch server-side |
|
|
395
|
+
| `filename` | string | No | Target filename override |
|
|
396
|
+
| `alt` | string | No | Alt text |
|
|
397
|
+
| `tags` | string[] | No | Tags to attach (max 20) |
|
|
398
|
+
|
|
399
|
+
Returns `{ status: "ingested", asset }` — use `asset.path` in content fields afterward.
|
|
400
|
+
|
|
401
|
+
### contentrain_media_update
|
|
402
|
+
|
|
403
|
+
Update asset metadata. Never touches the binary.
|
|
404
|
+
|
|
405
|
+
| Parameter | Type | Required | Description |
|
|
406
|
+
|-----------|------|----------|-------------|
|
|
407
|
+
| `id` | string | Yes | Asset id to update |
|
|
408
|
+
| `alt` | string | No | New alt text |
|
|
409
|
+
| `tags` | string[] | No | Replacement tag list (max 20) |
|
|
410
|
+
| `filename` | string | No | New filename |
|
|
411
|
+
|
|
412
|
+
Returns `{ status: "updated", asset }`.
|
|
413
|
+
|
|
414
|
+
### contentrain_media_delete
|
|
415
|
+
|
|
416
|
+
Delete an asset from the media stack. Destructive — content entries referencing its path are NOT rewritten; check references first with `contentrain_content_list`.
|
|
417
|
+
|
|
418
|
+
| Parameter | Type | Required | Description |
|
|
419
|
+
|-----------|------|----------|-------------|
|
|
420
|
+
| `id` | string | Yes | Asset id to delete |
|
|
421
|
+
| `confirm` | boolean | Yes | Must be `true` to confirm |
|
|
422
|
+
|
|
423
|
+
Returns `{ status: "deleted", id }`.
|
|
@@ -10,6 +10,18 @@ Follow these guidelines when populating image, video, or file fields in any cont
|
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## Storage & Reference Models
|
|
14
|
+
|
|
15
|
+
Media references are stored in one of two models. Identify which one the project uses before populating image, video, or file fields. The asset rules below (dimensions, formats, size limits, naming) apply to **both**; only the **Asset Organization** section (paths under `assets_path`, relative references) is specific to the local-file model.
|
|
16
|
+
|
|
17
|
+
1. **Local file model (default / OSS).** Media lives on disk under `config.json > assets_path` (default `.contentrain/assets/`) and is referenced by a **relative path from the project root** (e.g. `.contentrain/assets/blog/hero.webp`). To turn relative paths into URLs at read time, set `config.json > cdn.url` (or `contentrain generate --cdnBaseUrl <base>`) and use the `media()` resolver baked into the `@contentrain/query` generated client — `media('media/...') → {cdn.url}/{path}`.
|
|
18
|
+
|
|
19
|
+
2. **Studio CDN model.** Media lives in the Studio CDN/object store and is referenced by a relative storage path (`media/...`) returned by the media library. Pass either that `media/...` path or its URL to `contentrain_content_save`: in **cloud mode** the value is **automatically normalized to an absolute public delivery URL** on save (`{base}/{path}`), in both media fields and markdown bodies, so the committed content renders in a browser anywhere with no SDK. In **local mode** the relative path is kept verbatim. The rewrite is idempotent and never touches external URLs (`http(s)://`, `//`, `data:`) or already-absolute delivery URLs — so for external images (a CDN or Unsplash URL), just save the URL directly.
|
|
20
|
+
|
|
21
|
+
Never hand-build delivery URLs or guess the CDN base. Save the path or URL the media library gives you; the platform resolves it.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
13
25
|
## Image Dimensions (Recommended)
|
|
14
26
|
|
|
15
27
|
1. Use these standard dimensions unless the project's `context.json` specifies overrides:
|
|
@@ -78,6 +78,22 @@ const doc = document('blog-post').bySlug('getting-started')
|
|
|
78
78
|
| `.where(field, op, value)` | Operator filter (same ops as QueryBuilder) |
|
|
79
79
|
| `.include(relation)` | Resolve relation fields |
|
|
80
80
|
|
|
81
|
+
### Media
|
|
82
|
+
|
|
83
|
+
Media / image / file field values are plain strings. How you turn them into a URL depends on the storage model:
|
|
84
|
+
|
|
85
|
+
- **Studio-CDN content** already carries absolute delivery URLs — the write path normalizes `media/...` references on save — so use the field value directly, no resolution needed.
|
|
86
|
+
- **Relative-path content** (OSS / local-file model, values like `media/...`) resolves through an optional `media()` helper baked into the generated client. Set `config.json > cdn.url` (or run `contentrain generate --cdnBaseUrl <base>`) and the client exports it:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { media } from '#contentrain'
|
|
90
|
+
|
|
91
|
+
media('media/original/hero.webp') // → '{cdn.url}/media/original/hero.webp'
|
|
92
|
+
media('https://images.unsplash.com/x.jpg') // → unchanged (external pass-through)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`media()` is omitted when no base is configured, and is idempotent — external URLs (`http(s)://`, `//`, `data:`) and already-absolute delivery URLs pass through untouched. It is the **local-mode** counterpart of CDN mode's `client.media()` (which returns a `MediaAccessor` over the media manifest, below).
|
|
96
|
+
|
|
81
97
|
## CDN Mode (Remote Data)
|
|
82
98
|
|
|
83
99
|
For server-side or client-side apps that fetch content from Contentrain Studio CDN:
|
|
@@ -151,6 +167,7 @@ const history = await conv.history(response.conversationId)
|
|
|
151
167
|
- Locale fallback chain: explicit → config default → first available
|
|
152
168
|
- Generated files in `.contentrain/client/` are **immutable** — always regenerate, never edit
|
|
153
169
|
- Run `contentrain generate` after any model change
|
|
170
|
+
- **Media**: Studio-CDN fields already carry absolute URLs; for relative `media/...` values set `config.cdn.url` (or `generate --cdnBaseUrl`) and resolve with the generated `media()` helper
|
|
154
171
|
|
|
155
172
|
## Framework Integration
|
|
156
173
|
|