@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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-storyblok",
3
3
  "name": "Storyblok Integration",
4
- "version": "0.2.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@kvasar/openclaw-storyblok-plugin",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "OpenClaw plugin — interact with Storyblok CMS via Management API and Delivery API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -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
- 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
5
-
6
- author: Jordi Marti
7
- version: "2.1"
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
- This skill package provides agents with the ability to work with **Storyblok CMS** using the `openclaw-storyblok` plugin. It covers four main workflows:
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
- Examples:
15
+ Non-obvious behaviors that cause silent mistakes:
33
16
 
34
- - Hero
35
- - Grid
36
- - Section
37
- - Newsletter Section
38
- - Chapter
39
- - Full Width Image
40
- - Slider
41
- - CTA Banner
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
- #### Content Type Block
49
-
50
- Top-level content models representing an entry/page/document.
51
-
52
- Examples:
53
-
54
- - Landing Page
55
- - Post
56
- - Authors
57
- - Product
58
- - Page
59
- - Team Members
60
- - FAQ Article
61
- - Case Study
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
- #### Universal Block
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
- ### Component Folder Tools
47
+ ### Content Management
180
48
 
181
- | Tool | Required params | Optional params |
182
- |------|----------------|-----------------|
183
- | `storyblok_get_content_folders` | | `search`, `with_parent` |
184
- | `storyblok_update_component_folder` | `component_group_id` | `name`, `parent_id` (number or null) |
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
- > **Note:** `parent_id` can be set to `null` to move a folder to the root level.
55
+ ### Component Management
187
56
 
188
- ### Management Tools
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
- | Tool | Required params | Optional params |
191
- |------|----------------|-----------------|
192
- | `storyblok_create_story` | `name` | `slug`, `folder_id`, `parent_id`, `content`, `tag_list`, `is_folder`, `publish`, `release_id` |
193
- | `storyblok_update_story` | `story_id` | `name`, `slug`, `content`, `parent_id`, `tag_list`, `is_folder`, `publish`, `force_update`, `lang`, `release_id`, `group_id` |
194
- | `storyblok_publish_story` | `story_id` | `lang`, `release_id` |
195
- | `storyblok_unpublish_story` | `story_id` | `lang` |
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
- **Example: Update and publish**
72
+ ### Page Generation
294
73
 
295
- ```sh
296
- storyblok_update_story story_id="12345" content={...} publish=true
297
- ```
298
-
299
- **Example: Publish a story**
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
- ```sh
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
- ### 3. Multilingual Story Pattern
82
+ ---
307
83
 
308
- When creating or updating multilingual Storyblok stories:
84
+ ## Multilingual Stories
309
85
 
310
- -Use field-level i18n translations inside the SAME story
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
- Required behavior
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
- -Keep all translations inside the same story object
323
- -Ensure localized_paths contains all enabled locales
324
- -Use SEO-friendly English slugs for the main version
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 destratègies"
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
- **Rules:**
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.