@kvasar/openclaw-storyblok-plugin 0.2.2 → 0.2.4
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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/storyblok/SKILL.md +68 -490
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "openclaw-storyblok",
|
|
3
3
|
"name": "Storyblok Integration",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"description": "Provides tools to interact with Storyblok CMS via Management API and Delivery API. Supports stories, components, and space management.",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onStartup": false
|
package/package.json
CHANGED
|
@@ -1,536 +1,114 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: storyblok
|
|
3
|
-
description: Comprehensive skill for interacting with Storyblok CMS: query content, manage stories, generate pages, and sync with frontend repositories.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
author: Jordi Marti
|
|
7
|
-
version: "2.
|
|
3
|
+
description: Comprehensive skill for interacting with Storyblok CMS: query content, manage stories, create and update components, generate AI-assisted pages, and sync with frontend repositories. Use when the user mentions Storyblok, CMS content, stories, components, landing pages, or any content management task involving Storyblok.
|
|
4
|
+
license: Proprietary
|
|
5
|
+
metadata:
|
|
6
|
+
author: Jordi Marti
|
|
7
|
+
version: "2.4"
|
|
8
|
+
allowed-tools: storyblok_get_space, storyblok_get_story, storyblok_list_stories, storyblok_get_components, storyblok_get_component, storyblok_create_story, storyblok_update_story, storyblok_publish_story, storyblok_unpublish_story, storyblok_create_asset_folder, storyblok_delete_asset_folder, storyblok_get_asset_folder, storyblok_create_component, storyblok_get_content_folders, storyblok_update_component, storyblok_update_component_folder, sessions_spawn, read, write, edit
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
11
|
# Storyblok Integration Skill
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
1. **Content Query** – Retrieve spaces, stories, components, and listings.
|
|
17
|
-
2. **Content Management** – Create, update, publish, and unpublish stories.
|
|
18
|
-
3. **Page Generation** – Use AI-assisted reasoning to create new landing pages.
|
|
19
|
-
4. **Sync Workflow** – Synchronize content or schemas between Storyblok and a frontend repository.
|
|
20
|
-
|
|
21
|
-
## Core Concepts
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
### Storyblok Block Types
|
|
25
|
-
|
|
26
|
-
Storyblok components can be organized into three structural categories:
|
|
27
|
-
|
|
28
|
-
#### Nestable Block
|
|
29
|
-
|
|
30
|
-
Reusable blocks that are inserted **inside other blocks or pages**.
|
|
13
|
+
## Gotchas
|
|
31
14
|
|
|
32
|
-
|
|
15
|
+
Non-obvious behaviors that cause silent mistakes:
|
|
33
16
|
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- Feature Grid
|
|
43
|
-
|
|
44
|
-
Use these when building modular page layouts.
|
|
17
|
+
- **`storyblok_get_story` requires a numeric ID only.** If you have a slug or UUID, first call `storyblok_list_stories` with `with_slug` or `by_uuids` to resolve the numeric ID.
|
|
18
|
+
- **`storyblok_list_stories` does not return `content`.** Use `storyblok_get_story` for full content, or add `with_summary=true` for a lightweight field-type summary.
|
|
19
|
+
- **`publish=false` does NOT unpublish.** It saves as draft. To unpublish a live story, use `storyblok_unpublish_story`.
|
|
20
|
+
- **`component_group_uuid` ≠ `component_group_id`.** When assigning a component to a folder, use the UUID field — not the numeric ID.
|
|
21
|
+
- **Schema updates don't touch existing stories.** After `storyblok_update_component`, stories already using that component keep their old field values.
|
|
22
|
+
- **`content` is a reserved component name.** Component `name` must be snake_case and must not be `content` alone.
|
|
23
|
+
- **`force_update=true` causes a content conflict** if another user has the story open. Use only when necessary.
|
|
24
|
+
- **Never create separate stories per language.** Always use field-level i18n keys inside the same story.
|
|
45
25
|
|
|
46
26
|
---
|
|
47
27
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Use these as standalone entries in Storyblok.
|
|
28
|
+
## Which tool to use
|
|
29
|
+
|
|
30
|
+
| Goal | Tool |
|
|
31
|
+
|------|------|
|
|
32
|
+
| Space info | `storyblok_get_space` |
|
|
33
|
+
| Single story with full content | `storyblok_get_story` (numeric ID) |
|
|
34
|
+
| Find stories / list / filter | `storyblok_list_stories` |
|
|
35
|
+
| Inspect available block types | `storyblok_get_components` |
|
|
36
|
+
| Full schema of one component | `storyblok_get_component` |
|
|
37
|
+
| Create story | `storyblok_create_story` |
|
|
38
|
+
| Edit story | `storyblok_update_story` |
|
|
39
|
+
| Publish | `storyblok_publish_story` or `publish=true` on create/update |
|
|
40
|
+
| Unpublish | `storyblok_unpublish_story` only |
|
|
41
|
+
| Create/update component | `storyblok_create_component` / `storyblok_update_component` |
|
|
64
42
|
|
|
65
43
|
---
|
|
66
44
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
A block that can be used **both as a content type and nested block**.
|
|
70
|
-
|
|
71
|
-
Examples:
|
|
72
|
-
|
|
73
|
-
- FAQ Section
|
|
74
|
-
- Testimonials
|
|
75
|
-
- Rich Text Section
|
|
76
|
-
- Gallery
|
|
77
|
-
- Reusable Promo Page
|
|
78
|
-
- Contact Section
|
|
79
|
-
|
|
80
|
-
Use when flexibility is needed across multiple content structures.
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## Tool Reference
|
|
85
|
-
|
|
86
|
-
### Content Tools
|
|
87
|
-
|
|
88
|
-
### Content Tools
|
|
89
|
-
|
|
90
|
-
| Tool | Required params | Optional params |
|
|
91
|
-
|------|----------------|-----------------|
|
|
92
|
-
| `storyblok_get_space` | — | — |
|
|
93
|
-
| `storyblok_get_story` | `identifier` (ID ) |
|
|
94
|
-
| `storyblok_list_stories` | — | See parameter reference below |
|
|
95
|
-
| `storyblok_get_components` | — | `version`, `language` |
|
|
96
|
-
| `storyblok_get_component` | `component_id` | — |
|
|
97
|
-
|
|
98
|
-
#### `storyblok_list_stories` — Parameter Reference
|
|
99
|
-
|
|
100
|
-
**Pagination**
|
|
101
|
-
| Param | Type | Description |
|
|
102
|
-
|-------|------|-------------|
|
|
103
|
-
| `page` | number | Page number for paginated results |
|
|
104
|
-
| `per_page` | number | Number of results per page |
|
|
105
|
-
|
|
106
|
-
**Search**
|
|
107
|
-
| Param | Type | Description |
|
|
108
|
-
|-------|------|-------------|
|
|
109
|
-
| `text_search` | string | Full-text search across name, slug, full slug, and all content fields (UIDs, field values, asset filenames, rich text). Same as the search box in the Content UI. |
|
|
110
|
-
| `search` | string | Lighter search: name, slug, or full slug only |
|
|
111
|
-
| `reference_search` | string | Search referenced stories/assets by UUID, name, or asset URL |
|
|
112
|
-
| `contain_component` | string | Filter by nestable block name(s). Comma-separated for multiple |
|
|
113
|
-
| `filter_query` | string | Filter by content type fields. Syntax: `filter_query[field][operation]=value`. Supports comma-separated values |
|
|
114
|
-
|
|
115
|
-
**Sorting**
|
|
116
|
-
| Param | Type | Description |
|
|
117
|
-
|-------|------|-------------|
|
|
118
|
-
| `sort_by` | string | Sort by story property or content field. Examples: `created_at:desc`, `content.FIELD_NAME:asc`. Append `:int` or `:float` to sort numeric fields |
|
|
119
|
-
|
|
120
|
-
**Fetch by ID / UUID / Slug**
|
|
121
|
-
| Param | Type | Description |
|
|
122
|
-
|-------|------|-------------|
|
|
123
|
-
| `by_ids` | string | Comma-separated story IDs to retrieve |
|
|
124
|
-
| `excluding_ids` | string | Comma-separated story IDs to exclude |
|
|
125
|
-
| `by_uuids` | string | Comma-separated UUIDs to retrieve |
|
|
126
|
-
| `by_uuids_ordered` | string | Comma-separated UUIDs; response order matches input order |
|
|
127
|
-
| `with_slug` | string | Retrieve stories matching an exact full slug |
|
|
128
|
-
| `by_slugs` | string | Comma-separated full slugs. Supports wildcard: `posts/*` |
|
|
129
|
-
| `excluding_slugs` | string | Comma-separated full slugs to exclude. Supports wildcard: `posts*` |
|
|
130
|
-
| `starts_with` | string | Filter stories whose slug starts with this string |
|
|
131
|
-
|
|
132
|
-
**Hierarchy**
|
|
133
|
-
| Param | Type | Description |
|
|
134
|
-
|-------|------|-------------|
|
|
135
|
-
| `with_parent` | number | Filter by parent folder ID |
|
|
136
|
-
|
|
137
|
-
**Tags**
|
|
138
|
-
| Param | Type | Description |
|
|
139
|
-
|-------|------|-------------|
|
|
140
|
-
| `with_tag` | string | Filter by tag name(s). Comma-separated for multiple |
|
|
141
|
-
|
|
142
|
-
**Type Filters**
|
|
143
|
-
| Param | Type | Description |
|
|
144
|
-
|-------|------|-------------|
|
|
145
|
-
| `folder_only` | boolean | Return only folder-type stories |
|
|
146
|
-
| `story_only` | boolean | Return only non-folder stories |
|
|
147
|
-
| `in_trash` | boolean | Return only deleted (trashed) stories |
|
|
148
|
-
| `is_published` | boolean | `true` = published only · `false` = draft/unpublished only |
|
|
149
|
-
| `mine` | boolean | Return only stories assigned to the current user's token |
|
|
150
|
-
| `favourite` | boolean | Return only stories marked as favorites in the Content UI |
|
|
151
|
-
|
|
152
|
-
**Workflow & Releases**
|
|
153
|
-
| Param | Type | Description |
|
|
154
|
-
|-------|------|-------------|
|
|
155
|
-
| `in_workflow_stages` | string | Comma-separated workflow stage IDs |
|
|
156
|
-
| `in_release` | number | Retrieve stories grouped in a release (use release ID) |
|
|
157
|
-
|
|
158
|
-
**Scheduling**
|
|
159
|
-
| Param | Type | Description |
|
|
160
|
-
|-------|------|-------------|
|
|
161
|
-
| `scheduled_at_gt` | string | Stories scheduled after this ISO UTC timestamp |
|
|
162
|
-
| `scheduled_at_lt` | string | Stories scheduled before this ISO UTC timestamp |
|
|
163
|
-
|
|
164
|
-
**Response Shaping**
|
|
165
|
-
| Param | Type | Description |
|
|
166
|
-
|-------|------|-------------|
|
|
167
|
-
| `with_summary` | boolean | Include a `content_summary` object listing field types found in the story content |
|
|
168
|
-
|
|
169
|
-
### Component Tools
|
|
170
|
-
|
|
171
|
-
| Tool | Required params | Optional params |
|
|
172
|
-
|------|----------------|-----------------|
|
|
173
|
-
| `storyblok_create_component` | `name` | `display_name`, `schema`, `is_root`, `is_nestable`, `preview_field`, `preview_tmpl`, `component_group_uuid`, `icon`, `color`, `internal_tag_ids`, `content_type_asset_preview`, `image` |
|
|
174
|
-
| `storyblok_update_component` | `component_id` | `name`, `display_name`, `schema`, `is_root`, `is_nestable`, `preview_field`, `preview_tmpl`, `component_group_uuid`, `icon`, `color`, `internal_tag_ids`, `content_type_asset_preview`, `image` |
|
|
175
|
-
| `storyblok_get_component` | `component_id` | — |
|
|
176
|
-
|
|
177
|
-
> **Note:** Use `component_group_uuid` (not `component_group_id`) — this is the UUID of the component folder.
|
|
45
|
+
## Workflows
|
|
178
46
|
|
|
179
|
-
###
|
|
47
|
+
### Content Management
|
|
180
48
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
49
|
+
1. If content type is unknown, run `storyblok_get_components` first.
|
|
50
|
+
2. Build `content` as a structured object matching the component schema (JSON string also accepted but object preferred).
|
|
51
|
+
3. Create or update the story.
|
|
52
|
+
4. Publish only on explicit user confirmation.
|
|
53
|
+
5. To unpublish: `storyblok_unpublish_story` — never `update_story`.
|
|
185
54
|
|
|
186
|
-
|
|
55
|
+
### Component Management
|
|
187
56
|
|
|
188
|
-
|
|
57
|
+
1. Run `storyblok_get_components` to check if a component with the same name already exists.
|
|
58
|
+
2. Decide type (`is_root`, `is_nestable`) before creating — restructuring after stories use it can break content.
|
|
59
|
+
3. For updates, use minimal patches (add a field, update a label) rather than replacing the full schema.
|
|
60
|
+
4. Mark user-facing text fields `"translatable": true`; leave technical fields non-translatable.
|
|
61
|
+
5. Do not create or delete components without user confirmation.
|
|
189
62
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
### Asset Folder Tools
|
|
198
|
-
|
|
199
|
-
| Tool | Required params | Optional params |
|
|
200
|
-
|------|----------------|-----------------|
|
|
201
|
-
| `storyblok_create_asset_folder` | `name` | `parent_id` |
|
|
202
|
-
| `storyblok_delete_asset_folder` | `folder_id` | — |
|
|
203
|
-
| `storyblok_get_asset_folder` | `folder_id` | — |
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
### Parameter Notes
|
|
207
|
-
|
|
208
|
-
- Most tools accept optional parameters; only required fields are mandatory.
|
|
209
|
-
- For `storyblok_get_story`, you can specify `version` (draft/published) and `language`.
|
|
210
|
-
- For `storyblok_list_stories`, you can filter by `folder_id`, `parent_id`, `status`, `tag`, `per_page`, `page`, `sort_by`, `direction`.
|
|
211
|
-
- For management tools, `story_id` can be numeric ID or UUID.
|
|
212
|
-
- When constructing content objects, pass them as structured objects — never as JSON strings or stringified blobs.
|
|
213
|
-
|
|
214
|
-
#### `storyblok_get_story`
|
|
215
|
-
- `version`: `draft` or `published`. Defaults to `published`.
|
|
216
|
-
- `language`: optional language code to retrieve a specific translation.
|
|
217
|
-
|
|
218
|
-
#### `storyblok_list_stories`
|
|
219
|
-
- Filter options: `folder_id`, `parent_id`, `status`, `tag`, `per_page`, `page`, `sort_by`, `direction`.
|
|
220
|
-
- `story_id` can be a numeric ID or UUID.
|
|
221
|
-
|
|
222
|
-
#### `storyblok_update_story`
|
|
223
|
-
|
|
224
|
-
- `publish=true` publishes the story. `publish=false` saves as draft — it does **not** unpublish. Use `storyblok_unpublish_story` to unpublish.
|
|
225
|
-
- `force_update="true"` forces an update even if the story is locked by another user (causes a content conflict — use with caution). Has no effect if the story is locked as part of a workflow stage.
|
|
226
|
-
- `group_id`: UUID shared between stories defined as alternates (used for internationalization/variants).
|
|
227
|
-
- `lang`: publishes a specific language version individually (must be enabled in space internationalization settings).
|
|
228
|
-
- `content`: must be a structured object — never pass it as a JSON string or serialized value.
|
|
229
|
-
|
|
230
|
-
#### `storyblok_update_component`
|
|
231
|
-
|
|
232
|
-
- Component updates **do not** automatically update stories that already use this component. Existing story values are preserved.
|
|
233
|
-
- Use minimal updates — only change the fields that need modification. Avoid replacing the entire `schema` unless necessary.
|
|
234
|
-
- To add translatable fields, set `"translatable": true` in the field definition within the `schema`.
|
|
235
|
-
- Read-only fields like `id`, `created_at`, `updated_at`, `all_presets`, `real_name`, `internal_tags_list` cannot be updated.
|
|
236
|
-
- See section **3.1 Component Updates** for detailed guidance on schema migration and i18n considerations.
|
|
237
|
-
|
|
238
|
-
## Workflow Guides
|
|
239
|
-
|
|
240
|
-
### 1. Content Query
|
|
241
|
-
|
|
242
|
-
Use the query tools to explore and retrieve data.
|
|
243
|
-
|
|
244
|
-
**When to use what:**
|
|
245
|
-
|
|
246
|
-
- Need space info? → `storyblok_get_space`
|
|
247
|
-
- Need a specific story? → `storyblok_get_story` (provide `identifier`)
|
|
248
|
-
- Need a list of stories with filters? → `storyblok_list_stories` (set filters)
|
|
249
|
-
- Need to know available content block types? → `storyblok_get_components`
|
|
250
|
-
- Need full details of a specific component? → `storyblok_get_component` (provide `component_id`)
|
|
251
|
-
|
|
252
|
-
**Example: List all published stories in the last week**
|
|
253
|
-
|
|
254
|
-
```sh
|
|
255
|
-
storyblok_list_stories status="published" per_page=100
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Example: Get a story by slug**
|
|
259
|
-
|
|
260
|
-
```sh
|
|
261
|
-
storyblok_get_story identifier="my-landing-page" version="published"
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### 2. Content Management
|
|
265
|
-
|
|
266
|
-
Use the management tools to create, modify, and publish content.
|
|
267
|
-
|
|
268
|
-
**Workflow:**
|
|
269
|
-
|
|
270
|
-
- To create a new story: `storyblok_create_story` with `name` and optional `content`, `folder_id`, etc.
|
|
271
|
-
- Set `publish=true` to publish immediately on creation.
|
|
272
|
-
- The content is a JSON object matching your component structure.
|
|
273
|
-
- You can use `storyblok_get_components` first to see available block types.
|
|
274
|
-
- To edit a story: `storyblok_update_story` with `story_id` and fields to update.
|
|
275
|
-
- Set `publish=true` to publish changes immediately.
|
|
276
|
-
- Set `force_update=true` only if the story is locked and you need to override (causes content conflict).
|
|
277
|
-
- To link alternates (e.g. language variants), set `group_id` to the same UUID across stories.
|
|
278
|
-
- To publish: `storyblok_publish_story` with `story_id`.
|
|
279
|
-
- To unpublish: `storyblok_unpublish_story` with `story_id`. Never use `update_story` to unpublish.
|
|
280
|
-
|
|
281
|
-
**Example: Create a draft story**
|
|
282
|
-
|
|
283
|
-
```sh
|
|
284
|
-
storyblok_create_story name="New Homepage" content={"title":"Welcome","body":"<p>Hello</p>"}
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
**Example: Create and publish immediately**
|
|
288
|
-
|
|
289
|
-
```sh
|
|
290
|
-
storyblok_create_story name="New Homepage" content={...} publish=true
|
|
63
|
+
**Schema field example:**
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"headline": { "type": "text", "pos": 0, "translatable": true },
|
|
67
|
+
"image": { "type": "asset", "pos": 1, "filetypes": ["images"] },
|
|
68
|
+
"body": { "type": "richtext", "pos": 2 }
|
|
69
|
+
}
|
|
291
70
|
```
|
|
292
71
|
|
|
293
|
-
|
|
72
|
+
### Page Generation
|
|
294
73
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
74
|
+
- [ ] Clarify goal, tone, and key messages with the user
|
|
75
|
+
- [ ] `storyblok_get_components` — identify available blocks
|
|
76
|
+
- [ ] Design content structure, confirm with user before creating
|
|
77
|
+
- [ ] `storyblok_create_story` with the content object
|
|
78
|
+
- [ ] Publish only on explicit user confirmation
|
|
300
79
|
|
|
301
|
-
|
|
302
|
-
storyblok_publish_story story_id="12345" publish_notes="Initial release"
|
|
303
|
-
```
|
|
304
|
-
Storyblok i18n & Component Update Rules
|
|
80
|
+
For AI-generated copy, spawn a sub-session via `sessions_spawn` with the same tool permissions.
|
|
305
81
|
|
|
306
|
-
|
|
82
|
+
---
|
|
307
83
|
|
|
308
|
-
|
|
84
|
+
## Multilingual Stories
|
|
309
85
|
|
|
310
|
-
|
|
311
|
-
-Do NOT create separate stories per language unless explicitly requested
|
|
86
|
+
Always use field-level i18n inside the **same** story — never separate stories per language.
|
|
312
87
|
|
|
313
|
-
|
|
88
|
+
- Default language: English (unless specified)
|
|
314
89
|
|
|
315
|
-
-Default/main language must be English unless specified otherwise
|
|
316
|
-
-Translate content to requested locales
|
|
317
90
|
-Store translations using Storyblok i18n field keys:
|
|
318
91
|
-field_i18n_es
|
|
319
92
|
-field_i18n_ca
|
|
320
93
|
-field_i18n_de
|
|
321
94
|
-etc.
|
|
322
|
-
-
|
|
323
|
-
-
|
|
324
|
-
-
|
|
325
|
-
-Never duplicate stories for translations
|
|
326
|
-
|
|
327
|
-
Example
|
|
328
|
-
|
|
329
|
-
Correct:
|
|
95
|
+
- Translation keys: `field_i18n_es`, `field_i18n_ca`, `field_i18n_de`, etc.
|
|
96
|
+
- Use SEO-friendly English slugs
|
|
97
|
+
- Ensure `localized_paths` includes all enabled locales
|
|
330
98
|
|
|
99
|
+
```json
|
|
331
100
|
{
|
|
332
101
|
"headline": "Why Most Strategies Fail",
|
|
333
102
|
"headline_i18n_es": "Por qué fracasan la mayoría de las estrategias",
|
|
334
|
-
"headline_i18n_ca": "Per què fracassen la majoria d
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
Incorrect:
|
|
338
|
-
|
|
339
|
-
-Separate stories per language
|
|
340
|
-
-Duplicated content entries
|
|
341
|
-
-Missing localized_paths
|
|
342
|
-
|
|
343
|
-
#### Expected completion reporting
|
|
344
|
-
|
|
345
|
-
After multilingual operations, clearly report:
|
|
346
|
-
|
|
347
|
-
-Main language used
|
|
348
|
-
-Languages added
|
|
349
|
-
-That translations were stored using field-level i18n keys
|
|
350
|
-
-That no separate stories were created
|
|
351
|
-
|
|
352
|
-
### 3.1.- Component Updates
|
|
353
|
-
|
|
354
|
-
Storyblok components can be updated individually without recreating the full schema.
|
|
355
|
-
|
|
356
|
-
Use:
|
|
357
|
-
|
|
358
|
-
storyblok_update_component
|
|
359
|
-
|
|
360
|
-
* Use component updates for:
|
|
361
|
-
- Adding translatable fields
|
|
362
|
-
- Updating schema definitions
|
|
363
|
-
- Marking fields as translatable
|
|
364
|
-
- Updating labels/descriptions
|
|
365
|
-
- Extending components for i18n
|
|
366
|
-
- Updating preview fields
|
|
367
|
-
|
|
368
|
-
#### Important behavior
|
|
369
|
-
|
|
370
|
-
Updating a component schema does NOT automatically update stories already using that component.
|
|
371
|
-
|
|
372
|
-
After schema updates:
|
|
373
|
-
|
|
374
|
-
- Existing stories may require updates
|
|
375
|
-
- Missing i18n fields may need to be added manually
|
|
376
|
-
- Stories may require republishing
|
|
377
|
-
|
|
378
|
-
Existing story values are preserved automatically.
|
|
379
|
-
|
|
380
|
-
#### Example usage
|
|
381
|
-
|
|
382
|
-
```sh
|
|
383
|
-
# Add a new translatable field to component 4123
|
|
384
|
-
storyblok_update_component component_id="4123" schema={"subheadline":{"type":"text","pos":1,"translatable":true},"image":{"type":"asset","pos":2,"filetypes":["images"]}}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
```sh
|
|
388
|
-
# Update component display name and icon
|
|
389
|
-
storyblok_update_component component_id="4123" display_name="Hero Section" icon="photo" color="#ff6600"
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
#### i18n Component Schema Rules
|
|
393
|
-
|
|
394
|
-
When creating or updating schemas:
|
|
395
|
-
|
|
396
|
-
-Mark user-facing text fields with:
|
|
397
|
-
|
|
398
|
-
"translatable": true
|
|
399
|
-
|
|
400
|
-
-Keep technical/internal fields non-translatable
|
|
401
|
-
-Preserve existing schema fields unless explicitly removing them
|
|
402
|
-
-Avoid destructive schema replacements
|
|
403
|
-
|
|
404
|
-
Example:
|
|
405
|
-
|
|
406
|
-
{
|
|
407
|
-
"headline": {
|
|
408
|
-
"type": "text",
|
|
409
|
-
"translatable": true
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
##### Single Component Update Strategy
|
|
414
|
-
|
|
415
|
-
Prefer minimal schema updates instead of recreating full components.
|
|
416
|
-
|
|
417
|
-
Good:
|
|
418
|
-
|
|
419
|
-
- Add one new translatable field
|
|
420
|
-
- Update a single schema property
|
|
421
|
-
- Enable translations on existing fields
|
|
422
|
-
|
|
423
|
-
Bad:
|
|
424
|
-
|
|
425
|
-
- Recreate the full schema unnecessarily
|
|
426
|
-
- Accidentally remove existing fields
|
|
427
|
-
- Break existing stories
|
|
428
|
-
- Important Storyblok Behavior
|
|
429
|
-
|
|
430
|
-
Component schema updates do NOT retroactively overwrite story content.
|
|
431
|
-
|
|
432
|
-
After schema changes:
|
|
433
|
-
|
|
434
|
-
- Existing stories keep current values
|
|
435
|
-
- Stories may require migration/update logic
|
|
436
|
-
- Translation fields may need manual population
|
|
437
|
-
|
|
438
|
-
This matches official Storyblok component update behavior and helps avoid destructive schema operations.
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
### 4. Page Generation
|
|
442
|
-
|
|
443
|
-
This workflow combines AI reasoning with Storyblok tools to produce complete pages.
|
|
444
|
-
|
|
445
|
-
**Steps:**
|
|
446
|
-
|
|
447
|
-
1. Clarify the page goal with the user (topic, tone, key messages).
|
|
448
|
-
2. Fetch component schemas via `storyblok_get_components` to understand available block types.
|
|
449
|
-
3. Use reasoning to design a JSON content structure that uses those components.
|
|
450
|
-
4. Create the story with `storyblok_create_story`.
|
|
451
|
-
5. Optionally publish immediately with `storyblok_publish_story`.
|
|
452
|
-
|
|
453
|
-
The agent may also spawn a sub-session (using `sessions_spawn`) to generate the content with an AI model if needed.
|
|
454
|
-
|
|
455
|
-
### 5. Component Management
|
|
456
|
-
|
|
457
|
-
Components define the content structure of your space. Always design the schema carefully before creating — renaming or restructuring a component after stories use it can break existing content.
|
|
458
|
-
|
|
459
|
-
**When creating a component, decide its type first:**
|
|
460
|
-
|
|
461
|
-
| Type | `is_root` | `is_nestable` | Use case |
|
|
462
|
-
|------|-----------|---------------|----------|
|
|
463
|
-
| Content Type | `true` | `false` | Top-level entries (pages, posts) |
|
|
464
|
-
| Nestable | `false` | `true` | Reusable blocks inside pages |
|
|
465
|
-
| Universal | `true` | `true` | Can be used both ways |
|
|
466
|
-
|
|
467
|
-
**Schema field definition example:**
|
|
468
|
-
|
|
469
|
-
```json
|
|
470
|
-
{
|
|
471
|
-
"headline": {
|
|
472
|
-
"type": "text",
|
|
473
|
-
"pos": 0,
|
|
474
|
-
"translatable": true,
|
|
475
|
-
"description": "Main heading text"
|
|
476
|
-
},
|
|
477
|
-
"image": {
|
|
478
|
-
"type": "asset",
|
|
479
|
-
"pos": 1,
|
|
480
|
-
"filetypes": ["images"]
|
|
481
|
-
},
|
|
482
|
-
"body": {
|
|
483
|
-
"type": "richtext",
|
|
484
|
-
"pos": 2
|
|
485
|
-
}
|
|
103
|
+
"headline_i18n_ca": "Per què fracassen la majoria d'estratègies"
|
|
486
104
|
}
|
|
487
105
|
```
|
|
488
106
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
- `name` must be snake_case. Never use `content` alone — it is a reserved keyword.
|
|
492
|
-
- Always set at least one of `is_root` or `is_nestable` to `true`.
|
|
493
|
-
- Use `component_group_uuid` (not `component_group_id`) when assigning a component to a folder.
|
|
494
|
-
- Use `storyblok_get_components` first to check if a component with the same name already exists before creating.
|
|
495
|
-
- Use `storyblok_get_component` to inspect a specific component's full schema and presets.
|
|
496
|
-
- Do not create components without user confirmation — they affect the entire space.
|
|
497
|
-
|
|
498
|
-
## Session Awareness
|
|
499
|
-
|
|
500
|
-
This skill is designed to work in both main and sub-agent sessions. It can be used directly or spawned via `sessions_spawn` for parallel or isolated execution. When spawning, pass the same tool permissions to ensure access to Storyblok tools.
|
|
501
|
-
|
|
502
|
-
## README Usage Examples
|
|
503
|
-
|
|
504
|
-
### Quick Query
|
|
505
|
-
|
|
506
|
-
```
|
|
507
|
-
User: What stories are in folder 123?
|
|
508
|
-
Agent: storyblok_list_stories folder_id=123
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
### Create and Publish
|
|
512
|
-
|
|
513
|
-
```
|
|
514
|
-
User: Create a blog post titled "Latest Updates" with body "We've improved performance."
|
|
515
|
-
Agent: storyblok_create_story name="Latest Updates" content={"post_content":"We've improved performance."} publish=true
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
### Generate a Landing Page
|
|
519
|
-
|
|
520
|
-
```
|
|
521
|
-
User: Generate a landing page for our summer sale.
|
|
522
|
-
Agent: (fetches components, designs structure, creates story)
|
|
523
|
-
storyblok_get_components
|
|
524
|
-
storyblok_create_story name="Summer Sale 2026" content={...}
|
|
525
|
-
storyblok_publish_story story_id="..."
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
|
|
107
|
+
After completing multilingual work, confirm: languages added, field-level keys used, no separate stories created.
|
|
529
108
|
|
|
530
109
|
## Notes
|
|
531
110
|
|
|
532
111
|
- Always handle errors gracefully and report to the user.
|
|
533
112
|
- Avoid publishing without explicit user consent.
|
|
534
113
|
- For large exports, use pagination (`per_page`, `page`) to stay within response limits.
|
|
535
|
-
- Respect rate limits: Storyblok API may have limits; consider adding delays if many requests.
|
|
536
|
-
|
|
114
|
+
- Respect rate limits: Storyblok API may have limits; consider adding delays if many requests.
|