@kvasar/openclaw-storyblok-plugin 0.2.7 → 0.2.9

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
@@ -59,5 +59,17 @@ All tools are namespaced with `storyblok_`. See tool descriptions in the agent f
59
59
  ## Notes
60
60
 
61
61
  - Management token is required for read and write operations.
62
- - Use preview token for read-only scenarios to limit exposure.
63
- - The plugin supports only Management API (v1).
62
+ - The plugin supports only Management API (v1).
63
+
64
+
65
+ ## Model Evaluation Matrix
66
+
67
+ | Model | Expected Performance |
68
+ |---------|---------------------|
69
+ | Claude Opus 4.8 | very High |
70
+ | Claude Opus 4.7 | High |
71
+ | GPT-5.5 | very High |
72
+ | GPT-5.4 | High |
73
+ | stepfun-ai/step-3.5-flash | Low |
74
+ | stepfun-ai/step-3.7-flash | Medium |
75
+ | z-ai/glm-5.1 | Medium |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-storyblok",
3
3
  "name": "Storyblok Integration",
4
- "version": "0.2.7",
4
+ "version": "0.2.9",
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.7",
3
+ "version": "0.2.9",
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.4"
7
+ version: "2.6"
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,15 +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.
20
- - **`publish=false` does NOT unpublish.** It saves as draft. To unpublish a live story, use `storyblok_unpublish_story`.
19
+ - **`storyblok_update_story` requires the full content object.** Always fetch first with `storyblok_get_story`, merge your changes, then send the complete object. Never send a partial objectit silently overwrites and loses existing fields, blocks, assets, and translations.
20
+ - **`storyblok_update_component` is for schema changes only.** Use it to add/modify field definitions in a component schema. Never use it to write actual translated content into a story.
21
+ - **Never create separate stories per language.** Always use field-level i18n keys inside the same story.
22
+ - **`publish=false` does NOT unpublish.** It saves as draft. To unpublish, use `storyblok_unpublish_story`.
21
23
  - **`component_group_uuid` ≠ `component_group_id`.** When assigning a component to a folder, use the UUID field — not the numeric ID.
22
24
  - **Schema updates don't touch existing stories.** After `storyblok_update_component`, stories already using that component keep their old field values.
23
25
  - **`content` is a reserved component name.** Component `name` must be snake_case and must not be `content` alone.
24
26
  - **`force_update=true` causes a content conflict** if another user has the story open. Use only when necessary.
25
- - **Never create separate stories per language.** Always use field-level i18n keys inside the same story.
26
27
  - **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.
28
28
 
29
29
  ---
30
30
 
@@ -38,11 +38,10 @@ Non-obvious behaviors that cause silent mistakes:
38
38
  | Inspect available block types | `storyblok_get_components` |
39
39
  | Full schema of one component | `storyblok_get_component` |
40
40
  | Create story | `storyblok_create_story` |
41
- | Update story structure (add/remove/reorder components) | `storyblok_update_story` (full object) |
41
+ | Update story structure or translated content | `storyblok_update_story` (full object required) |
42
+ | Add/modify translatable field definitions in a component schema | `storyblok_update_component` |
42
43
  | Publish | `storyblok_publish_story` or `publish=true` on create/update |
43
44
  | Unpublish | `storyblok_unpublish_story` only |
44
- | Create/update component | `storyblok_create_component` |
45
- | Update the values of a component. |`storyblok_update_component` |
46
45
 
47
46
  ---
48
47
 
@@ -51,18 +50,16 @@ Non-obvious behaviors that cause silent mistakes:
51
50
  ### Content Management
52
51
 
53
52
  1. If content type is unknown, run `storyblok_get_components` first.
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.
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.
58
- 4. Publish only on explicit user confirmation.
53
+ 2. To update a story (structure or content): fetch with `storyblok_get_story`, merge changes into the full object, send with `storyblok_update_story`. Never send partial content.
54
+ 3. To change a component schema (add a field definition, mark a field translatable): use `storyblok_update_component` — it patches only what you pass and does not affect existing story values.
55
+ 4. Save as draft unless the user explicitly asks to publish.
59
56
  5. To unpublish: `storyblok_unpublish_story` — never `update_story`.
60
57
 
61
58
  ### Component Management
62
59
 
63
60
  1. Run `storyblok_get_components` to check if a component with the same name already exists.
64
61
  2. Decide type (`is_root`, `is_nestable`) before creating — restructuring after stories use it can break content.
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.
62
+ 3. Use `storyblok_update_component` for partial schema patches only (add a field, rename a label, mark translatable). It does not affect existing story values.
66
63
  4. Mark user-facing text fields `"translatable": true`; leave technical fields non-translatable.
67
64
  5. Do not create or delete components without user confirmation.
68
65
 
@@ -89,29 +86,47 @@ For AI-generated copy, spawn a sub-session via `sessions_spawn` with the same to
89
86
 
90
87
  ## Multilingual Stories
91
88
 
92
- Always use field-level i18n inside the **same** story — never separate stories per language.
89
+ Always use field-level i18n keys inside the **same** story — never create separate stories per language.
93
90
 
94
91
  - Default language: English (unless specified)
95
- - Translation keys: `field_i18n_es`, `field_i18n_ca`, `field_i18n_de`, etc.
92
+ - i18n key format: `field__i18n__xx` (e.g. `headline__i18n__de`, `teaser__i18n__ca`)
96
93
  - Use SEO-friendly English slugs
97
94
  - Ensure `localized_paths` includes all enabled locales
98
95
 
99
- **Adding new language translations — correct workflow:**
96
+ ### Two separate cases
100
97
 
101
- **Never use `storyblok_update_story` to add translations.** Use `storyblok_update_component` instead.
98
+ **A) Translate existing story content** `storyblok_get_story` + `storyblok_update_story`
102
99
 
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.
100
+ **B) Add translatable field definitions to a component schema** `storyblok_get_component` + `storyblok_update_component`
107
101
 
108
- ```json
109
- {
110
- "headline": { "type": "text", "pos": 0, "translatable": true },
111
- "headline_i18n_es": "Por qué fracasan la mayoría de las estrategias",
112
- "headline_i18n_ca": "Per què fracassen la majoria d'estratègies",
113
- "headline_i18n_de": "Warum die meisten Strategien scheitern"
114
- }
115
- ```
102
+ Never mix these up: `storyblok_update_component` writes schema definitions, not story content.
103
+
104
+ ---
116
105
 
117
- After completing multilingual work, confirm: languages added, existing translations preserved, `storyblok_update_component` used (not `update_story`), no separate stories created.
106
+ ### A) Adding or updating a translation for an existing story
107
+
108
+ 1. Call `storyblok_get_story` with the numeric story ID to get the full current content.
109
+ 2. Inspect the content and identify the fields that need translation.
110
+ 3. Add the new i18n keys inside the same content object. Examples:
111
+ - `headline__i18n__de`
112
+ - `teaser__i18n__de`
113
+ - `text__i18n__de`
114
+ - `paragraphs__i18n__de`
115
+ 4. Preserve the full existing content object including `_uid`, `component`, nav references, nested blocks, assets, and all existing translations. **Do not remove any existing keys** unless the user explicitly asks.
116
+ 5. For rich text fields: preserve the full Storyblok rich text JSON structure. Translate only the `text` node values. Never stringify rich text.
117
+ 6. Call `storyblok_update_story` with the complete merged content object.
118
+ 7. Save as draft unless the user explicitly asks to publish.
119
+ 8. After updating, verify:
120
+ - New language fields exist
121
+ - Existing translations are still present
122
+ - Rich text is valid JSON (not a string)
123
+ - No separate story was created
124
+
125
+ ### B) Adding translatable field definitions to a component schema
126
+
127
+ 1. Call `storyblok_get_component` with the numeric component ID.
128
+ 2. Inspect the current schema and identify fields that need to be marked translatable.
129
+ 3. Add or update field definitions with `"translatable": true`. Do not remove existing fields unless the user asks.
130
+ 4. Call `storyblok_update_component` with the patched schema.
131
+
132
+ After completing multilingual work, confirm: languages added, existing translations preserved, correct tool used (`update_story` for content, `update_component` for schema), no separate stories created.