@kvasar/openclaw-storyblok-plugin 0.2.5 → 0.2.7

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.5",
4
+ "version": "0.2.7",
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.5",
3
+ "version": "0.2.7",
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",
@@ -4,7 +4,7 @@ description: Comprehensive skill for interacting with Storyblok CMS: query conte
4
4
  license: Proprietary
5
5
  metadata:
6
6
  author: Jordi Marti
7
- version: "2.5"
7
+ version: "2.4"
8
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
9
9
  ---
10
10
 
@@ -16,12 +16,15 @@ Non-obvious behaviors that cause silent mistakes:
16
16
 
17
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
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
+ - **`storyblok_update_story` is only for updating the story structure** — adding/removing components, reordering blocks, changing the story layout. It requires the full content object; always fetch first with `storyblok_get_story`, merge your changes, then send the complete object. Never use it for translations or field-level edits — partial content silently overwrites and loses existing fields.
19
20
  - **`publish=false` does NOT unpublish.** It saves as draft. To unpublish a live story, use `storyblok_unpublish_story`.
20
21
  - **`component_group_uuid` ≠ `component_group_id`.** When assigning a component to a folder, use the UUID field — not the numeric ID.
21
22
  - **Schema updates don't touch existing stories.** After `storyblok_update_component`, stories already using that component keep their old field values.
22
23
  - **`content` is a reserved component name.** Component `name` must be snake_case and must not be `content` alone.
23
24
  - **`force_update=true` causes a content conflict** if another user has the story open. Use only when necessary.
24
25
  - **Never create separate stories per language.** Always use field-level i18n keys inside the same story.
26
+ - **Storyblok rich text fields are structured JSON objects, not strings.** Always preserve the complete Storyblok rich text schema (including `_uid`, `type`, `content`, and other properties). Never stringify rich text content before sending it to the Management API. This applies to both standard and translated rich text fields (`field_i18n_xx`).
27
+ - **Never use `storyblok_update_story` to add language translations.** Use `storyblok_update_component` instead: fetch components with `storyblok_get_components`, iterate each relevant one with `storyblok_get_component`, add new `field_i18n_xx` keys, and call `storyblok_update_component`. Never remove existing translation keys unless the user explicitly asks.
25
28
 
26
29
  ---
27
30
 
@@ -35,11 +38,12 @@ Non-obvious behaviors that cause silent mistakes:
35
38
  | Inspect available block types | `storyblok_get_components` |
36
39
  | Full schema of one component | `storyblok_get_component` |
37
40
  | Create story | `storyblok_create_story` |
38
- | Edit story | `storyblok_update_story` |
41
+ | Update story structure (add/remove/reorder components) | `storyblok_update_story` (full object) |
39
42
  | Publish | `storyblok_publish_story` or `publish=true` on create/update |
40
43
  | Unpublish | `storyblok_unpublish_story` only |
41
- | Create Component | `storyblok_create_component` |
44
+ | Create/update component | `storyblok_create_component` |
42
45
  | Update the values of a component. |`storyblok_update_component` |
46
+
43
47
  ---
44
48
 
45
49
  ## Workflows
@@ -47,8 +51,10 @@ Non-obvious behaviors that cause silent mistakes:
47
51
  ### Content Management
48
52
 
49
53
  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).
54
+ 2. Build `content` as a structured object matching the component schema. For rich text fields (`type: "richtext"`), ensure the value is a valid Storyblok rich text JSON object with properties like `_uid`, `type`, `content`, etc. — never a plain string.
51
55
  3. Create or update the story.
56
+ 2. Use `storyblok_update_story` only to change story structure — adding/removing/reordering components or blocks. Always fetch first with `storyblok_get_story`, merge, then send the full object. Never use it for translations or field edits.
57
+ 3. For partial schema changes (add a field, rename a label), use `storyblok_update_component` instead — it patches only what you pass.
52
58
  4. Publish only on explicit user confirmation.
53
59
  5. To unpublish: `storyblok_unpublish_story` — never `update_story`.
54
60
 
@@ -56,7 +62,7 @@ Non-obvious behaviors that cause silent mistakes:
56
62
 
57
63
  1. Run `storyblok_get_components` to check if a component with the same name already exists.
58
64
  2. Decide type (`is_root`, `is_nestable`) before creating — restructuring after stories use it can break content.
59
- 3. To update the entire story content `use storyblok_update_story` (full object required). To update only component schema fields use `storyblok_update_component` (partial, only what you pass changes). Never update partial using `storyblok_update_story`
65
+ 3. To update the entire story content use `storyblok_update_story` (full object required). To update only component schema fields `storyblok_update_component` (partial, only what you pass changes). Existing story values are NOT affected by component schema changes.
60
66
  4. Mark user-facing text fields `"translatable": true`; leave technical fields non-translatable.
61
67
  5. Do not create or delete components without user confirmation.
62
68
 
@@ -86,29 +92,26 @@ For AI-generated copy, spawn a sub-session via `sessions_spawn` with the same to
86
92
  Always use field-level i18n inside the **same** story — never separate stories per language.
87
93
 
88
94
  - Default language: English (unless specified)
89
-
90
- -Store translations using Storyblok i18n field keys:
91
- -field_i18n_es
92
- -field_i18n_ca
93
- -field_i18n_de
94
- -etc.
95
- - Translation keys: `field_i18n_es`, `field_i18n_ca`, `field_i18n_de`, etc.
95
+ - Translation keys: `field_i18n_es`, `field_i18n_ca`, `field_i18n_de`, etc.
96
96
  - Use SEO-friendly English slugs
97
97
  - Ensure `localized_paths` includes all enabled locales
98
98
 
99
+ **Adding new language translations — correct workflow:**
100
+
101
+ **Never use `storyblok_update_story` to add translations.** Use `storyblok_update_component` instead.
102
+
103
+ 1. Call `storyblok_get_components` to get the full list of components used in the space.
104
+ 2. For each relevant component, call `storyblok_get_component` to inspect its current schema and existing translation fields.
105
+ 3. For each component, add the new `field_i18n_xx` keys to the schema — **do not remove existing translation keys** unless the user explicitly asks.
106
+ 4. Call `storyblok_update_component` for each component with the merged schema.
107
+
99
108
  ```json
100
109
  {
101
- "headline": "Why Most Strategies Fail",
110
+ "headline": { "type": "text", "pos": 0, "translatable": true },
102
111
  "headline_i18n_es": "Por qué fracasan la mayoría de las estrategias",
103
- "headline_i18n_ca": "Per què fracassen la majoria d'estratègies"
112
+ "headline_i18n_ca": "Per què fracassen la majoria d'estratègies",
113
+ "headline_i18n_de": "Warum die meisten Strategien scheitern"
104
114
  }
105
115
  ```
106
116
 
107
- After completing multilingual work, confirm: languages added, field-level keys used, no separate stories created.
108
-
109
- ## Notes
110
-
111
- - Always handle errors gracefully and report to the user.
112
- - Avoid publishing without explicit user consent.
113
- - For large exports, use pagination (`per_page`, `page`) to stay within response limits.
114
- - Respect rate limits: Storyblok API may have limits; consider adding delays if many requests.
117
+ After completing multilingual work, confirm: languages added, existing translations preserved, `storyblok_update_component` used (not `update_story`), no separate stories created.