diff --git a/README.md b/README.md
index 3cbfc4d..7d0b2e5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# OpenWebUI Extensions
-[](#contributors-)
+[](#contributors-)
English | [中文](./README_CN.md)
@@ -24,10 +24,10 @@ A collection of enhancements, plugins, and prompts for [open-webui](https://gith
| Rank | Plugin | Version | Downloads | Views | 📅 Updated |
| :---: | :--- | :---: | :---: | :---: | :---: |
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) |  |  |  |  |
-| 🥈 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) |  |  |  |  |
+| 🥈 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) |  |  |  |  |
| 🥉 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) |  |  |  |  |
| 4️⃣ | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) |  |  |  |  |
-| 5️⃣ | [OpenWebUI Skills Manager Tool](https://openwebui.com/posts/openwebui_skills_manager_tool_b4bce8e4) |  |  |  |  |
+| 5️⃣ | [OpenWebUI Skills Manager Tool](https://openwebui.com/posts/openwebui_skills_manager_tool_b4bce8e4) |  |  |  |  |
| 6️⃣ | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) |  |  |  |  |
### 📈 Total Downloads Trend
@@ -217,8 +217,6 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
 ZOLO 🐛 🤔 |
 Johan Grande 🤔 |
 Alessandro Baroni 🤔 |
-  dvystrcil 💻 |
-  Colin Chen 🐛 💻 |
diff --git a/README_CN.md b/README_CN.md
index 275eb8d..bf651a2 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -21,10 +21,10 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
| 排名 | 插件 | 版本 | 下载 | 浏览 | 📅 更新 |
| :---: | :--- | :---: | :---: | :---: | :---: |
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) |  |  |  |  |
-| 🥈 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) |  |  |  |  |
+| 🥈 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) |  |  |  |  |
| 🥉 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) |  |  |  |  |
| 4️⃣ | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) |  |  |  |  |
-| 5️⃣ | [OpenWebUI Skills Manager Tool](https://openwebui.com/posts/openwebui_skills_manager_tool_b4bce8e4) |  |  |  |  |
+| 5️⃣ | [OpenWebUI Skills Manager Tool](https://openwebui.com/posts/openwebui_skills_manager_tool_b4bce8e4) |  |  |  |  |
| 6️⃣ | [AI Task Instruction Generator](https://openwebui.com/posts/ai_task_instruction_generator_9bab8b37) |  |  |  |  |
### 📈 总下载量累计趋势
diff --git a/docs/plugins/tools/index.md b/docs/plugins/tools/index.md
index b381d8d..a0464ef 100644
--- a/docs/plugins/tools/index.md
+++ b/docs/plugins/tools/index.md
@@ -5,5 +5,5 @@ OpenWebUI native Tool plugins that can be used across models.
## Available Tool Plugins
- [Batch Install Plugins from GitHub](batch-install-plugins-tool.md) (v1.1.0) - One-click batch install plugins from GitHub repositories with an interactive selection dialog and multi-language support.
-- [OpenWebUI Skills Manager Tool](openwebui-skills-manager-tool.md) (v0.3.2) - Native skill management with multi-line `SKILL.md` frontmatter description support.
+- [OpenWebUI Skills Manager Tool](openwebui-skills-manager-tool.md) (v0.3.3) - Native skill management with multi-line `SKILL.md` frontmatter description support.
- [Smart Mind Map Tool](smart-mind-map-tool.md) (v1.0.1) - Intelligently analyzes text content and proactively generates interactive mind maps to help users structure and visualize knowledge.
diff --git a/docs/plugins/tools/index.zh.md b/docs/plugins/tools/index.zh.md
index c12501e..59bc378 100644
--- a/docs/plugins/tools/index.zh.md
+++ b/docs/plugins/tools/index.zh.md
@@ -5,5 +5,5 @@
## 可用 Tool 插件
- [Batch Install Plugins from GitHub](batch-install-plugins-tool.zh.md) (v1.1.0) - 一键从 GitHub 仓库批量安装插件,支持交互式选择对话框和多语言。
-- [OpenWebUI Skills 管理工具](openwebui-skills-manager-tool.zh.md) (v0.3.2) - 支持多行 `SKILL.md` frontmatter 描述的原生技能管理工具。
+- [OpenWebUI Skills 管理工具](openwebui-skills-manager-tool.zh.md) (v0.3.3) - 支持多行 `SKILL.md` frontmatter 描述的原生技能管理工具。
- [智能思维导图工具 (Smart Mind Map Tool)](smart-mind-map-tool.zh.md) (v1.0.1) - 智能分析文本内容并主动生成交互式思维导图,帮助用户结构化与可视化知识。
diff --git a/docs/plugins/tools/openwebui-skills-manager-tool.md b/docs/plugins/tools/openwebui-skills-manager-tool.md
index a565478..9dd7d94 100644
--- a/docs/plugins/tools/openwebui-skills-manager-tool.md
+++ b/docs/plugins/tools/openwebui-skills-manager-tool.md
@@ -1,6 +1,6 @@
# 🧰 OpenWebUI Skills Manager Tool
-| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.2 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
+| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.3 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
| :--- | ---: |
|  |  |  |  |  |  |  |
@@ -23,9 +23,8 @@ When the selection dialog opens, search for this plugin, check it, and continue.
## What's New
-- **⚡ OpenWebUI 0.9.x Compatibility**: Added runtime async detection and compatibility layer for OpenWebUI 0.9.x+ asynchronous database models (Skills), with graceful sync fallback for older versions.
-- **📝 Multi-line Frontmatter Descriptions**: `install_skill` now correctly parses `description: >` and `description: |` blocks in remote `SKILL.md` files, so imported skill descriptions no longer truncate to a single line.
-- **↩️ Better Metadata Fallbacks**: If a skill frontmatter provides `title` without `name`, the installer now uses that title before falling back to directory-based names.
+- **🛡️ Confirmation Before Destructive Actions**: New `REQUIRE_CONFIRMATION` valve (default `True`) prompts the user via `__event_call__` before `update_skill`, `delete_skill`, and overwrite paths in `create_skill`/`install_skill`. Cancellations return a structured `{cancelled: true, ...}` result with localized status messages.
+- **🌐 Localized Confirmation Strings**: All new confirmation titles, messages, and cancellation statuses are translated across the 12 supported locales.
> [!TIP]
> **💡 Looking to batch install global plugins (Actions, Filters, Pipes, Tools)?**
diff --git a/docs/plugins/tools/openwebui-skills-manager-tool.zh.md b/docs/plugins/tools/openwebui-skills-manager-tool.zh.md
index 4800519..44acc35 100644
--- a/docs/plugins/tools/openwebui-skills-manager-tool.zh.md
+++ b/docs/plugins/tools/openwebui-skills-manager-tool.zh.md
@@ -1,6 +1,6 @@
# 🧰 OpenWebUI Skills 管理工具
-| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v0.3.2 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) |
+| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v0.3.3 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) |
| :--- | ---: |
|  |  |  |  |  |  |  |
@@ -23,9 +23,8 @@
## 最新更新
-- **⚡ OpenWebUI 0.9.x 兼容性**:新增运行时异步检测和兼容性适配层,支持 OpenWebUI 0.9.x 及以上版本的异步数据库模型(Skills),同时完美回退支持旧版本的同步调用。
-- **📝 支持多行 Frontmatter 描述**:`install_skill` 现在可以正确解析远程 `SKILL.md` 里的 `description: >` 和 `description: |`,导入后的技能描述不再被截断成单行。
-- **↩️ 更稳的元数据回退**:当 frontmatter 只有 `title` 没有 `name` 时,安装器会优先使用 `title`,避免退回到通用目录名。
+- **🛡️ 破坏性操作确认**:新增 `REQUIRE_CONFIRMATION` 阀门(默认 `True`),在执行 `update_skill`、`delete_skill` 以及 `create_skill`/`install_skill` 触发覆盖前通过 `__event_call__` 弹出用户确认。取消时返回结构化的 `{cancelled: true, ...}` 结果,并发出本地化的状态消息。
+- **🌐 本地化确认文案**:所有新增的确认标题、提示信息和取消状态文案均已翻译至支持的 12 种语言。
> [!TIP]
> **💡 想要批量安装/管理全局插件 (Actions, Filters, Pipes, Tools)?**
diff --git a/docs/plugins/tools/openwebui-skills-manager.md b/docs/plugins/tools/openwebui-skills-manager.md
index 45aa385..9dd7d94 100644
--- a/docs/plugins/tools/openwebui-skills-manager.md
+++ b/docs/plugins/tools/openwebui-skills-manager.md
@@ -1,6 +1,6 @@
# 🧰 OpenWebUI Skills Manager Tool
-| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.1 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
+| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.3 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
| :--- | ---: |
|  |  |  |  |  |  |  |
@@ -23,9 +23,8 @@ When the selection dialog opens, search for this plugin, check it, and continue.
## What's New
-- **📝 Multi-line Frontmatter Descriptions**: `install_skill` now correctly parses `description: >` and `description: |` blocks in remote `SKILL.md` files, so imported skill descriptions no longer truncate to a single line.
-- **↩️ Better Metadata Fallbacks**: If a skill frontmatter provides `title` without `name`, the installer now uses that title before falling back to directory-based names.
-- **🧪 Regression Coverage**: Added focused tests for folded/literal YAML blocks and CRLF line endings to keep external skill imports stable.
+- **🛡️ Confirmation Before Destructive Actions**: New `REQUIRE_CONFIRMATION` valve (default `True`) prompts the user via `__event_call__` before `update_skill`, `delete_skill`, and overwrite paths in `create_skill`/`install_skill`. Cancellations return a structured `{cancelled: true, ...}` result with localized status messages.
+- **🌐 Localized Confirmation Strings**: All new confirmation titles, messages, and cancellation statuses are translated across the 12 supported locales.
> [!TIP]
> **💡 Looking to batch install global plugins (Actions, Filters, Pipes, Tools)?**
diff --git a/docs/plugins/tools/openwebui-skills-manager.zh.md b/docs/plugins/tools/openwebui-skills-manager.zh.md
index 366266a..44acc35 100644
--- a/docs/plugins/tools/openwebui-skills-manager.zh.md
+++ b/docs/plugins/tools/openwebui-skills-manager.zh.md
@@ -1,6 +1,6 @@
# 🧰 OpenWebUI Skills 管理工具
-| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v0.3.1 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) |
+| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v0.3.3 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) |
| :--- | ---: |
|  |  |  |  |  |  |  |
@@ -23,9 +23,8 @@
## 最新更新
-- **📝 支持多行 Frontmatter 描述**:`install_skill` 现在可以正确解析远程 `SKILL.md` 里的 `description: >` 和 `description: |`,导入后的技能描述不再被截断成单行。
-- **↩️ 更稳的元数据回退**:当 frontmatter 只有 `title` 没有 `name` 时,安装器会优先使用 `title`,避免退回到通用目录名。
-- **🧪 回归测试补齐**:新增 folded/literal YAML 块和 CRLF 换行场景测试,保证外部技能导入行为稳定。
+- **🛡️ 破坏性操作确认**:新增 `REQUIRE_CONFIRMATION` 阀门(默认 `True`),在执行 `update_skill`、`delete_skill` 以及 `create_skill`/`install_skill` 触发覆盖前通过 `__event_call__` 弹出用户确认。取消时返回结构化的 `{cancelled: true, ...}` 结果,并发出本地化的状态消息。
+- **🌐 本地化确认文案**:所有新增的确认标题、提示信息和取消状态文案均已翻译至支持的 12 种语言。
> [!TIP]
> **💡 想要批量安装/管理全局插件 (Actions, Filters, Pipes, Tools)?**
diff --git a/plugins/tools/openwebui-skills-manager/README.md b/plugins/tools/openwebui-skills-manager/README.md
index a565478..4548a43 100644
--- a/plugins/tools/openwebui-skills-manager/README.md
+++ b/plugins/tools/openwebui-skills-manager/README.md
@@ -1,6 +1,6 @@
# 🧰 OpenWebUI Skills Manager Tool
-| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.2 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
+| By [Fu-Jie](https://github.com/Fu-Jie) · v0.3.3 | [⭐ Star this repo](https://github.com/Fu-Jie/openwebui-extensions) |
| :--- | ---: |
|  |  |  |  |  |  |  |
@@ -23,9 +23,8 @@ When the selection dialog opens, search for this plugin, check it, and continue.
## What's New
-- **⚡ OpenWebUI 0.9.x Compatibility**: Added runtime async detection and compatibility layer for OpenWebUI 0.9.x+ asynchronous database models (Skills), with graceful sync fallback for older versions.
-- **📝 Multi-line Frontmatter Descriptions**: `install_skill` now correctly parses `description: >` and `description: |` blocks in remote `SKILL.md` files, so imported skill descriptions no longer truncate to a single line.
-- **↩️ Better Metadata Fallbacks**: If a skill frontmatter provides `title` without `name`, the installer now uses that title before falling back to directory-based names.
+- **🛡️ Confirmation Before Destructive Actions**: New `REQUIRE_CONFIRMATION` valve (default `True`) prompts the user via `__event_call__` before `update_skill`, `delete_skill`, and overwrite paths in `create_skill`/`install_skill`. Cancellations return a structured `{cancelled: true, ...}` result with localized status messages.
+- **🌐 Localized Confirmation Strings**: All new confirmation titles, messages, and cancellation statuses are translated across the 12 supported locales.
> [!TIP]
> **💡 Looking to batch install global plugins (Actions, Filters, Pipes, Tools)?**
@@ -279,6 +278,7 @@ All installations enforce:
| Parameter | Default | Description |
| --- | --- | --- |
| `SHOW_STATUS` | `True` | Show operation status updates in OpenWebUI status bar. |
+| `REQUIRE_CONFIRMATION` | `True` | Require an interactive yes/no confirmation before destructive actions (`update_skill`, `delete_skill`, and overwrite on `create_skill`/`install_skill`). Disable to allow these without prompting. |
| `ALLOW_OVERWRITE_ON_CREATE` | `False` | Allow `create_skill`/`install_skill` to overwrite same-name skill by default. |
| `INSTALL_FETCH_TIMEOUT` | `12.0` | URL fetch timeout in seconds for skill installation. |
| `TRUSTED_DOMAINS` | `github.com,huggingface.co,githubusercontent.com` | Comma-separated list of primary trusted domains for downloads (always enforced). Subdomains automatically allowed (e.g., `github.com` allows `api.github.com`). See [Domain Whitelist Guide](https://github.com/Fu-Jie/openwebui-extensions/blob/main/plugins/tools/openwebui-skills-manager/docs/DOMAIN_WHITELIST.md). |
diff --git a/plugins/tools/openwebui-skills-manager/README_CN.md b/plugins/tools/openwebui-skills-manager/README_CN.md
index 4800519..a14c067 100644
--- a/plugins/tools/openwebui-skills-manager/README_CN.md
+++ b/plugins/tools/openwebui-skills-manager/README_CN.md
@@ -1,6 +1,6 @@
# 🧰 OpenWebUI Skills 管理工具
-| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v0.3.2 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) |
+| 作者:[Fu-Jie](https://github.com/Fu-Jie) · v0.3.3 | [⭐ 点个 Star 支持项目](https://github.com/Fu-Jie/openwebui-extensions) |
| :--- | ---: |
|  |  |  |  |  |  |  |
@@ -23,9 +23,8 @@
## 最新更新
-- **⚡ OpenWebUI 0.9.x 兼容性**:新增运行时异步检测和兼容性适配层,支持 OpenWebUI 0.9.x 及以上版本的异步数据库模型(Skills),同时完美回退支持旧版本的同步调用。
-- **📝 支持多行 Frontmatter 描述**:`install_skill` 现在可以正确解析远程 `SKILL.md` 里的 `description: >` 和 `description: |`,导入后的技能描述不再被截断成单行。
-- **↩️ 更稳的元数据回退**:当 frontmatter 只有 `title` 没有 `name` 时,安装器会优先使用 `title`,避免退回到通用目录名。
+- **🛡️ 破坏性操作确认**:新增 `REQUIRE_CONFIRMATION` 阀门(默认 `True`),在执行 `update_skill`、`delete_skill` 以及 `create_skill`/`install_skill` 触发覆盖前通过 `__event_call__` 弹出用户确认。取消时返回结构化的 `{cancelled: true, ...}` 结果,并发出本地化的状态消息。
+- **🌐 本地化确认文案**:所有新增的确认标题、提示信息和取消状态文案均已翻译至支持的 12 种语言。
> [!TIP]
> **💡 想要批量安装/管理全局插件 (Actions, Filters, Pipes, Tools)?**
@@ -279,6 +278,7 @@ description: "做一些有用的事"
| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `SHOW_STATUS` | `True` | 是否在 OpenWebUI 状态栏显示操作状态。 |
+| `REQUIRE_CONFIRMATION` | `True` | 在执行破坏性操作(`update_skill`、`delete_skill`,以及 `create_skill`/`install_skill` 触发覆盖)前要求用户进行一次是/否确认。关闭后,这些操作将不再弹出提示直接执行。 |
| `ALLOW_OVERWRITE_ON_CREATE` | `False` | 是否允许 `create_skill`/`install_skill` 默认覆盖同名技能。 |
| `INSTALL_FETCH_TIMEOUT` | `12.0` | 从 URL 安装技能时的请求超时时间(秒)。 |
| `TRUSTED_DOMAINS` | `github.com,huggingface.co,githubusercontent.com` | 逗号分隔的主信任域名清单(**必须启用**)。子域名会自动放行(如 `github.com` 允许 `api.github.com`)。详见 [域名白名单指南](https://github.com/Fu-Jie/openwebui-extensions/blob/main/plugins/tools/openwebui-skills-manager/docs/DOMAIN_WHITELIST.md)。 |
diff --git a/plugins/tools/openwebui-skills-manager/openwebui_skills_manager.py b/plugins/tools/openwebui-skills-manager/openwebui_skills_manager.py
index 2c13573..2f49f3a 100644
--- a/plugins/tools/openwebui-skills-manager/openwebui_skills_manager.py
+++ b/plugins/tools/openwebui-skills-manager/openwebui_skills_manager.py
@@ -3,7 +3,7 @@
author: Fu-Jie
author_url: https://github.com/Fu-Jie/openwebui-extensions
funding_url: https://github.com/open-webui
-version: 0.3.2
+version: 0.3.3
openwebui_id: b4bce8e4-08e7-4f90-bea7-dc31d463a0bb
requirements:
description: Standalone OpenWebUI tool for managing native Workspace Skills (list/show/install/create/update/delete) for any model.
@@ -71,6 +71,20 @@
"msg_updated": "Skill updated successfully.",
"msg_deleted": "Skill deleted successfully.",
"msg_installed": "Skill installed successfully.",
+ "confirm_update_title": "Update skill?",
+ "confirm_update_message": "Update skill \"{name}\".\nDescription: {description}",
+ "confirm_delete_title": "Delete skill?",
+ "confirm_delete_message": "Permanently delete skill \"{name}\". This cannot be undone.\nDescription: {description}",
+ "status_update_cancelled": "Update cancelled by user.",
+ "status_delete_cancelled": "Deletion cancelled by user.",
+ "msg_update_cancelled": "Skill update cancelled by user.",
+ "msg_delete_cancelled": "Skill deletion cancelled by user.",
+ "confirm_overwrite_title": "Overwrite existing skill?",
+ "confirm_overwrite_message": "Overwrite skill \"{name}\". Its description and content will be replaced.\nCurrent description: {description}",
+ "status_overwrite_cancelled": "Overwrite cancelled by user.",
+ "msg_overwrite_cancelled": "Skill overwrite cancelled by user.",
+ "err_confirmation_unavailable": "Cannot prompt for confirmation in this context (no interactive event channel). Disable REQUIRE_CONFIRMATION in valves to proceed without prompting.",
+ "no_description": "(no description)",
}
TRANSLATIONS = {
@@ -111,6 +125,20 @@
"msg_updated": "技能更新成功。",
"msg_deleted": "技能删除成功。",
"msg_installed": "技能安装成功。",
+ "confirm_update_title": "更新技能?",
+ "confirm_update_message": "更新技能 \"{name}\"。\n描述:{description}",
+ "confirm_delete_title": "删除技能?",
+ "confirm_delete_message": "将永久删除技能 \"{name}\"。此操作无法撤销。\n描述:{description}",
+ "status_update_cancelled": "用户已取消更新。",
+ "status_delete_cancelled": "用户已取消删除。",
+ "msg_update_cancelled": "技能更新已由用户取消。",
+ "msg_delete_cancelled": "技能删除已由用户取消。",
+ "confirm_overwrite_title": "覆盖已存在的技能?",
+ "confirm_overwrite_message": "覆盖技能 \"{name}\"。其描述和内容将被替换。\n当前描述:{description}",
+ "status_overwrite_cancelled": "用户已取消覆盖。",
+ "msg_overwrite_cancelled": "技能覆盖已由用户取消。",
+ "err_confirmation_unavailable": "当前上下文无法弹出确认提示(无交互事件通道)。请在阀门设置中关闭 REQUIRE_CONFIRMATION 以跳过确认。",
+ "no_description": "(无描述)",
},
"zh-TW": {
"status_listing": "正在列出你的技能...",
@@ -147,6 +175,20 @@
"msg_updated": "技能更新成功。",
"msg_deleted": "技能刪除成功。",
"msg_installed": "技能安裝成功。",
+ "confirm_update_title": "更新技能?",
+ "confirm_update_message": "更新技能 \"{name}\"。\n描述:{description}",
+ "confirm_delete_title": "刪除技能?",
+ "confirm_delete_message": "將永久刪除技能 \"{name}\"。此操作無法復原。\n描述:{description}",
+ "status_update_cancelled": "使用者已取消更新。",
+ "status_delete_cancelled": "使用者已取消刪除。",
+ "msg_update_cancelled": "技能更新已由使用者取消。",
+ "msg_delete_cancelled": "技能刪除已由使用者取消。",
+ "confirm_overwrite_title": "覆寫已存在的技能?",
+ "confirm_overwrite_message": "覆寫技能 \"{name}\"。其描述和內容將被取代。\n目前描述:{description}",
+ "status_overwrite_cancelled": "使用者已取消覆寫。",
+ "msg_overwrite_cancelled": "技能覆寫已由使用者取消。",
+ "err_confirmation_unavailable": "目前上下文無法彈出確認提示(無互動事件通道)。請在閥門設定中關閉 REQUIRE_CONFIRMATION 以略過確認。",
+ "no_description": "(無描述)",
},
"zh-HK": {
"status_listing": "正在列出你的技能...",
@@ -183,6 +225,20 @@
"msg_updated": "技能更新成功。",
"msg_deleted": "技能刪除成功。",
"msg_installed": "技能安裝成功。",
+ "confirm_update_title": "更新技能?",
+ "confirm_update_message": "更新技能 \"{name}\"。\n描述:{description}",
+ "confirm_delete_title": "刪除技能?",
+ "confirm_delete_message": "將永久刪除技能 \"{name}\"。此操作無法復原。\n描述:{description}",
+ "status_update_cancelled": "使用者已取消更新。",
+ "status_delete_cancelled": "使用者已取消刪除。",
+ "msg_update_cancelled": "技能更新已由使用者取消。",
+ "msg_delete_cancelled": "技能刪除已由使用者取消。",
+ "confirm_overwrite_title": "覆寫已存在的技能?",
+ "confirm_overwrite_message": "覆寫技能 \"{name}\"。其描述和內容將被取代。\n目前描述:{description}",
+ "status_overwrite_cancelled": "使用者已取消覆寫。",
+ "msg_overwrite_cancelled": "技能覆寫已由使用者取消。",
+ "err_confirmation_unavailable": "目前上下文無法彈出確認提示(無互動事件通道)。請在閥門設定中關閉 REQUIRE_CONFIRMATION 以略過確認。",
+ "no_description": "(無描述)",
},
"ja-JP": {
"status_listing": "スキル一覧を取得しています...",
@@ -219,6 +275,20 @@
"msg_updated": "スキルを更新しました。",
"msg_deleted": "スキルを削除しました。",
"msg_installed": "スキルをインストールしました。",
+ "confirm_update_title": "スキルを更新しますか?",
+ "confirm_update_message": "スキル \"{name}\" を更新します。\n説明: {description}",
+ "confirm_delete_title": "スキルを削除しますか?",
+ "confirm_delete_message": "スキル \"{name}\" を完全に削除します。この操作は取り消せません。\n説明: {description}",
+ "status_update_cancelled": "ユーザーが更新をキャンセルしました。",
+ "status_delete_cancelled": "ユーザーが削除をキャンセルしました。",
+ "msg_update_cancelled": "スキルの更新がユーザーによりキャンセルされました。",
+ "msg_delete_cancelled": "スキルの削除がユーザーによりキャンセルされました。",
+ "confirm_overwrite_title": "既存のスキルを上書きしますか?",
+ "confirm_overwrite_message": "スキル \"{name}\" を上書きします。説明と内容が置き換えられます。\n現在の説明: {description}",
+ "status_overwrite_cancelled": "ユーザーが上書きをキャンセルしました。",
+ "msg_overwrite_cancelled": "スキルの上書きがユーザーによりキャンセルされました。",
+ "err_confirmation_unavailable": "現在のコンテキストでは確認プロンプトを表示できません(対話型イベントチャネルなし)。確認なしで実行するにはバルブの REQUIRE_CONFIRMATION を無効にしてください。",
+ "no_description": "(説明なし)",
},
"ko-KR": {
"status_listing": "스킬 목록을 불러오는 중...",
@@ -255,6 +325,20 @@
"msg_updated": "스킬이 업데이트되었습니다.",
"msg_deleted": "스킬이 삭제되었습니다.",
"msg_installed": "스킬이 설치되었습니다.",
+ "confirm_update_title": "스킬을 업데이트하시겠습니까?",
+ "confirm_update_message": "스킬 \"{name}\"을(를) 업데이트합니다.\n설명: {description}",
+ "confirm_delete_title": "스킬을 삭제하시겠습니까?",
+ "confirm_delete_message": "스킬 \"{name}\"을(를) 영구적으로 삭제합니다. 이 작업은 되돌릴 수 없습니다.\n설명: {description}",
+ "status_update_cancelled": "사용자가 업데이트를 취소했습니다.",
+ "status_delete_cancelled": "사용자가 삭제를 취소했습니다.",
+ "msg_update_cancelled": "스킬 업데이트가 사용자에 의해 취소되었습니다.",
+ "msg_delete_cancelled": "스킬 삭제가 사용자에 의해 취소되었습니다.",
+ "confirm_overwrite_title": "기존 스킬을 덮어쓰시겠습니까?",
+ "confirm_overwrite_message": "스킬 \"{name}\"을(를) 덮어씁니다. 설명과 내용이 교체됩니다.\n현재 설명: {description}",
+ "status_overwrite_cancelled": "사용자가 덮어쓰기를 취소했습니다.",
+ "msg_overwrite_cancelled": "스킬 덮어쓰기가 사용자에 의해 취소되었습니다.",
+ "err_confirmation_unavailable": "현재 컨텍스트에서 확인 프롬프트를 표시할 수 없습니다(대화형 이벤트 채널 없음). 확인 없이 진행하려면 밸브에서 REQUIRE_CONFIRMATION을 비활성화하세요.",
+ "no_description": "(설명 없음)",
},
"fr-FR": {
"status_listing": "Liste des skills en cours...",
@@ -291,6 +375,20 @@
"msg_updated": "Skill mis à jour avec succès.",
"msg_deleted": "Skill supprimé avec succès.",
"msg_installed": "Skill installé avec succès.",
+ "confirm_update_title": "Mettre à jour le skill ?",
+ "confirm_update_message": "Mettre à jour le skill \"{name}\".\nDescription : {description}",
+ "confirm_delete_title": "Supprimer le skill ?",
+ "confirm_delete_message": "Supprimer définitivement le skill \"{name}\". Cette action est irréversible.\nDescription : {description}",
+ "status_update_cancelled": "Mise à jour annulée par l'utilisateur.",
+ "status_delete_cancelled": "Suppression annulée par l'utilisateur.",
+ "msg_update_cancelled": "Mise à jour du skill annulée par l'utilisateur.",
+ "msg_delete_cancelled": "Suppression du skill annulée par l'utilisateur.",
+ "confirm_overwrite_title": "Écraser le skill existant ?",
+ "confirm_overwrite_message": "Écraser le skill \"{name}\". Sa description et son contenu seront remplacés.\nDescription actuelle : {description}",
+ "status_overwrite_cancelled": "Écrasement annulé par l'utilisateur.",
+ "msg_overwrite_cancelled": "Écrasement du skill annulé par l'utilisateur.",
+ "err_confirmation_unavailable": "Impossible d'afficher une invite de confirmation dans ce contexte (aucun canal d'événement interactif). Désactivez REQUIRE_CONFIRMATION dans les valves pour continuer sans invite.",
+ "no_description": "(aucune description)",
},
"de-DE": {
"status_listing": "Deine Skills werden aufgelistet...",
@@ -324,6 +422,20 @@
"msg_updated": "Skill erfolgreich aktualisiert.",
"msg_deleted": "Skill erfolgreich gelöscht.",
"msg_installed": "Skill erfolgreich installiert.",
+ "confirm_update_title": "Skill aktualisieren?",
+ "confirm_update_message": "Skill \"{name}\" aktualisieren.\nBeschreibung: {description}",
+ "confirm_delete_title": "Skill löschen?",
+ "confirm_delete_message": "Skill \"{name}\" dauerhaft löschen. Dies kann nicht rückgängig gemacht werden.\nBeschreibung: {description}",
+ "status_update_cancelled": "Aktualisierung vom Benutzer abgebrochen.",
+ "status_delete_cancelled": "Löschung vom Benutzer abgebrochen.",
+ "msg_update_cancelled": "Skill-Aktualisierung vom Benutzer abgebrochen.",
+ "msg_delete_cancelled": "Skill-Löschung vom Benutzer abgebrochen.",
+ "confirm_overwrite_title": "Vorhandenen Skill überschreiben?",
+ "confirm_overwrite_message": "Skill \"{name}\" überschreiben. Seine Beschreibung und sein Inhalt werden ersetzt.\nAktuelle Beschreibung: {description}",
+ "status_overwrite_cancelled": "Überschreiben vom Benutzer abgebrochen.",
+ "msg_overwrite_cancelled": "Skill-Überschreiben vom Benutzer abgebrochen.",
+ "err_confirmation_unavailable": "In diesem Kontext kann keine Bestätigung angezeigt werden (kein interaktiver Ereigniskanal). Deaktiviere REQUIRE_CONFIRMATION in den Valves, um ohne Bestätigung fortzufahren.",
+ "no_description": "(keine Beschreibung)",
},
"es-ES": {
"status_listing": "Listando tus skills...",
@@ -357,6 +469,20 @@
"msg_updated": "Skill actualizado correctamente.",
"msg_deleted": "Skill eliminado correctamente.",
"msg_installed": "Skill instalado correctamente.",
+ "confirm_update_title": "¿Actualizar skill?",
+ "confirm_update_message": "Actualizar skill \"{name}\".\nDescripción: {description}",
+ "confirm_delete_title": "¿Eliminar skill?",
+ "confirm_delete_message": "Eliminar permanentemente el skill \"{name}\". Esta acción no se puede deshacer.\nDescripción: {description}",
+ "status_update_cancelled": "Actualización cancelada por el usuario.",
+ "status_delete_cancelled": "Eliminación cancelada por el usuario.",
+ "msg_update_cancelled": "Actualización del skill cancelada por el usuario.",
+ "msg_delete_cancelled": "Eliminación del skill cancelada por el usuario.",
+ "confirm_overwrite_title": "¿Sobrescribir skill existente?",
+ "confirm_overwrite_message": "Sobrescribir el skill \"{name}\". Su descripción y contenido serán reemplazados.\nDescripción actual: {description}",
+ "status_overwrite_cancelled": "Sobrescritura cancelada por el usuario.",
+ "msg_overwrite_cancelled": "Sobrescritura del skill cancelada por el usuario.",
+ "err_confirmation_unavailable": "No se puede mostrar la confirmación en este contexto (no hay canal de eventos interactivo). Desactiva REQUIRE_CONFIRMATION en las valves para continuar sin confirmación.",
+ "no_description": "(sin descripción)",
},
"it-IT": {
"status_listing": "Elenco delle skill in corso...",
@@ -390,6 +516,20 @@
"msg_updated": "Skill aggiornata con successo.",
"msg_deleted": "Skill eliminata con successo.",
"msg_installed": "Skill installata con successo.",
+ "confirm_update_title": "Aggiornare la skill?",
+ "confirm_update_message": "Aggiornare la skill \"{name}\".\nDescrizione: {description}",
+ "confirm_delete_title": "Eliminare la skill?",
+ "confirm_delete_message": "Eliminare definitivamente la skill \"{name}\". L'operazione non può essere annullata.\nDescrizione: {description}",
+ "status_update_cancelled": "Aggiornamento annullato dall'utente.",
+ "status_delete_cancelled": "Eliminazione annullata dall'utente.",
+ "msg_update_cancelled": "Aggiornamento della skill annullato dall'utente.",
+ "msg_delete_cancelled": "Eliminazione della skill annullata dall'utente.",
+ "confirm_overwrite_title": "Sovrascrivere la skill esistente?",
+ "confirm_overwrite_message": "Sovrascrivere la skill \"{name}\". La descrizione e il contenuto saranno sostituiti.\nDescrizione attuale: {description}",
+ "status_overwrite_cancelled": "Sovrascrittura annullata dall'utente.",
+ "msg_overwrite_cancelled": "Sovrascrittura della skill annullata dall'utente.",
+ "err_confirmation_unavailable": "Impossibile mostrare la conferma in questo contesto (nessun canale di eventi interattivo). Disattiva REQUIRE_CONFIRMATION nelle valvole per procedere senza conferma.",
+ "no_description": "(nessuna descrizione)",
},
"vi-VN": {
"status_listing": "Đang liệt kê kỹ năng của bạn...",
@@ -423,6 +563,20 @@
"msg_updated": "Cập nhật kỹ năng thành công.",
"msg_deleted": "Xóa kỹ năng thành công.",
"msg_installed": "Cài đặt kỹ năng thành công.",
+ "confirm_update_title": "Cập nhật kỹ năng?",
+ "confirm_update_message": "Cập nhật kỹ năng \"{name}\".\nMô tả: {description}",
+ "confirm_delete_title": "Xóa kỹ năng?",
+ "confirm_delete_message": "Xóa vĩnh viễn kỹ năng \"{name}\". Hành động này không thể hoàn tác.\nMô tả: {description}",
+ "status_update_cancelled": "Người dùng đã hủy cập nhật.",
+ "status_delete_cancelled": "Người dùng đã hủy xóa.",
+ "msg_update_cancelled": "Người dùng đã hủy cập nhật kỹ năng.",
+ "msg_delete_cancelled": "Người dùng đã hủy xóa kỹ năng.",
+ "confirm_overwrite_title": "Ghi đè kỹ năng đã tồn tại?",
+ "confirm_overwrite_message": "Ghi đè kỹ năng \"{name}\". Mô tả và nội dung sẽ bị thay thế.\nMô tả hiện tại: {description}",
+ "status_overwrite_cancelled": "Người dùng đã hủy ghi đè.",
+ "msg_overwrite_cancelled": "Người dùng đã hủy ghi đè kỹ năng.",
+ "err_confirmation_unavailable": "Không thể hiển thị xác nhận trong ngữ cảnh này (không có kênh sự kiện tương tác). Tắt REQUIRE_CONFIRMATION trong valves để tiếp tục mà không cần xác nhận.",
+ "no_description": "(không có mô tả)",
},
"id-ID": {
"status_listing": "Sedang menampilkan daftar skill Anda...",
@@ -456,6 +610,20 @@
"msg_updated": "Skill berhasil diperbarui.",
"msg_deleted": "Skill berhasil dihapus.",
"msg_installed": "Skill berhasil dipasang.",
+ "confirm_update_title": "Perbarui skill?",
+ "confirm_update_message": "Perbarui skill \"{name}\".\nDeskripsi: {description}",
+ "confirm_delete_title": "Hapus skill?",
+ "confirm_delete_message": "Hapus skill \"{name}\" secara permanen. Tindakan ini tidak dapat dibatalkan.\nDeskripsi: {description}",
+ "status_update_cancelled": "Pembaruan dibatalkan oleh pengguna.",
+ "status_delete_cancelled": "Penghapusan dibatalkan oleh pengguna.",
+ "msg_update_cancelled": "Pembaruan skill dibatalkan oleh pengguna.",
+ "msg_delete_cancelled": "Penghapusan skill dibatalkan oleh pengguna.",
+ "confirm_overwrite_title": "Timpa skill yang ada?",
+ "confirm_overwrite_message": "Timpa skill \"{name}\". Deskripsi dan kontennya akan diganti.\nDeskripsi saat ini: {description}",
+ "status_overwrite_cancelled": "Penimpaan dibatalkan oleh pengguna.",
+ "msg_overwrite_cancelled": "Penimpaan skill dibatalkan oleh pengguna.",
+ "err_confirmation_unavailable": "Tidak dapat menampilkan konfirmasi dalam konteks ini (tidak ada saluran event interaktif). Nonaktifkan REQUIRE_CONFIRMATION di valves untuk melanjutkan tanpa konfirmasi.",
+ "no_description": "(tanpa deskripsi)",
},
}
@@ -614,6 +782,46 @@ async def _emit_status(
)
+async def _request_confirmation(
+ event_call: Optional[Any],
+ title: str,
+ message: str,
+) -> Optional[bool]:
+ """Prompt the user for a yes/no confirmation via __event_call__.
+ Returns True if confirmed, False if the user declined, or None if no
+ interactive event channel is available (caller decides how to handle).
+ """
+ if not event_call:
+ return None
+ try:
+ result = await _call_openwebui_compat(
+ event_call,
+ {
+ "type": "confirmation",
+ "data": {"title": title, "message": message},
+ },
+ )
+ except Exception as e:
+ logger.warning(f"Confirmation prompt failed: {e}")
+ return None
+ # Only trust an explicit bool True/False from the event channel.
+ # Any other truthy value (e.g. an error dict returned on channel disconnect)
+ # must be treated as unavailable so callers can block the destructive action.
+ if isinstance(result, bool):
+ return result
+ return None
+
+
+def _format_description_for_prompt(description: Any, lang: str, max_len: int = 200) -> str:
+ """Render a skill description for inclusion in a confirmation dialog."""
+ text = str(description or "").strip()
+ if not text:
+ return _t(lang, "no_description")
+ if len(text) > max_len:
+ return text[: max_len - 1].rstrip() + "…"
+ return text
+
+
def _require_skills_model():
"""Ensure OpenWebUI Skills model APIs are available."""
if Skills is None or SkillForm is None or SkillMeta is None:
@@ -1133,6 +1341,7 @@ async def _install_single_skill(
lang: str,
overwrite: bool,
__event_emitter__: Optional[Any] = None,
+ __event_call__: Optional[Any] = None,
) -> Dict[str, Any]:
"""Internal method to install a single skill from URL."""
try:
@@ -1208,6 +1417,40 @@ async def _install_single_skill(
"error": f"Skill already exists: {final_name}",
"hint": "Pass overwrite=true to replace the existing skill.",
}
+ if valves.REQUIRE_CONFIRMATION:
+ confirmed = await _request_confirmation(
+ __event_call__,
+ _t(lang, "confirm_overwrite_title"),
+ _t(
+ lang,
+ "confirm_overwrite_message",
+ name=final_name,
+ description=_format_description_for_prompt(
+ getattr(existing, "description", ""), lang
+ ),
+ ),
+ )
+ if confirmed is None:
+ # Batch caller aggregates per-URL results; do not raise.
+ return {
+ "error": _t(lang, "err_confirmation_unavailable"),
+ "url": url,
+ }
+ if not confirmed:
+ await _emit_status(
+ valves,
+ __event_emitter__,
+ _t(lang, "status_overwrite_cancelled"),
+ done=True,
+ )
+ return {
+ "cancelled": True,
+ "action": "overwrite_cancelled",
+ "id": sid,
+ "name": final_name,
+ "source_url": url,
+ "message": _t(lang, "msg_overwrite_cancelled"),
+ }
updated = await _call_openwebui_compat(
Skills.update_skill_by_id,
sid,
@@ -1281,6 +1524,10 @@ class Valves(BaseModel):
default=True,
description="Whether to show operation status updates.",
)
+ REQUIRE_CONFIRMATION: bool = Field(
+ default=True,
+ description="Require an interactive yes/no confirmation before destructive actions (update_skill, delete_skill, and overwrite on create_skill/install_skill). Disable to allow these without prompting.",
+ )
ALLOW_OVERWRITE_ON_CREATE: bool = Field(
default=True,
description="Allow create_skill/install_skill to overwrite same-name skill by default.",
@@ -1516,6 +1763,7 @@ async def install_skill(
lang=lang,
overwrite=overwrite,
__event_emitter__=__event_emitter__,
+ __event_call__=__event_call__,
)
# Track installed name to detect duplicates
@@ -1578,6 +1826,7 @@ async def install_skill(
lang=lang,
overwrite=overwrite,
__event_emitter__=__event_emitter__,
+ __event_call__=__event_call__,
)
return result
@@ -1643,6 +1892,35 @@ async def create_skill(
}
sid = str(getattr(existing, "id", "") or "")
+ if self.valves.REQUIRE_CONFIRMATION:
+ confirmed = await _request_confirmation(
+ __event_call__,
+ _t(lang, "confirm_overwrite_title"),
+ _t(
+ lang,
+ "confirm_overwrite_message",
+ name=skill_name,
+ description=_format_description_for_prompt(
+ getattr(existing, "description", ""), lang
+ ),
+ ),
+ )
+ if confirmed is None:
+ raise ValueError(_t(lang, "err_confirmation_unavailable"))
+ if not confirmed:
+ await _emit_status(
+ self.valves,
+ __event_emitter__,
+ _t(lang, "status_overwrite_cancelled"),
+ done=True,
+ )
+ return {
+ "cancelled": True,
+ "action": "overwrite_cancelled",
+ "id": sid,
+ "name": skill_name,
+ "message": _t(lang, "msg_overwrite_cancelled"),
+ }
updated = await _call_openwebui_compat(
Skills.update_skill_by_id,
sid,
@@ -1766,6 +2044,36 @@ async def update_skill(
if not updates:
raise ValueError(_t(lang, "err_no_update_fields"))
+ if self.valves.REQUIRE_CONFIRMATION:
+ current_name = str(getattr(skill, "name", "") or sid)
+ confirmed = await _request_confirmation(
+ __event_call__,
+ _t(lang, "confirm_update_title"),
+ _t(
+ lang,
+ "confirm_update_message",
+ name=current_name,
+ description=_format_description_for_prompt(
+ getattr(skill, "description", ""), lang
+ ),
+ ),
+ )
+ if confirmed is None:
+ raise ValueError(_t(lang, "err_confirmation_unavailable"))
+ if not confirmed:
+ await _emit_status(
+ self.valves,
+ __event_emitter__,
+ _t(lang, "status_update_cancelled"),
+ done=True,
+ )
+ return {
+ "cancelled": True,
+ "id": sid,
+ "name": current_name,
+ "message": _t(lang, "msg_update_cancelled"),
+ }
+
updated = await _call_openwebui_compat(Skills.update_skill_by_id, sid, updates, prefer_thread_for_sync=True)
updated_name = str(
getattr(updated, "name", "")
@@ -1823,6 +2131,36 @@ async def delete_skill(
sid = str(getattr(skill, "id", "") or "")
sname = str(getattr(skill, "name", "") or "")
+
+ if self.valves.REQUIRE_CONFIRMATION:
+ confirmed = await _request_confirmation(
+ __event_call__,
+ _t(lang, "confirm_delete_title"),
+ _t(
+ lang,
+ "confirm_delete_message",
+ name=sname or "unknown",
+ description=_format_description_for_prompt(
+ getattr(skill, "description", ""), lang
+ ),
+ ),
+ )
+ if confirmed is None:
+ raise ValueError(_t(lang, "err_confirmation_unavailable"))
+ if not confirmed:
+ await _emit_status(
+ self.valves,
+ __event_emitter__,
+ _t(lang, "status_delete_cancelled"),
+ done=True,
+ )
+ return {
+ "cancelled": True,
+ "id": sid,
+ "name": sname,
+ "message": _t(lang, "msg_delete_cancelled"),
+ }
+
await _call_openwebui_compat(Skills.delete_skill_by_id, sid, prefer_thread_for_sync=True)
deleted_name = sname or sid or "unknown"
diff --git a/plugins/tools/openwebui-skills-manager/v0.3.3.md b/plugins/tools/openwebui-skills-manager/v0.3.3.md
new file mode 100644
index 0000000..5e826f0
--- /dev/null
+++ b/plugins/tools/openwebui-skills-manager/v0.3.3.md
@@ -0,0 +1,20 @@
+# OpenWebUI Skills Manager v0.3.3 Release Notes
+
+This release adds an opt-in confirmation flow for destructive operations and translates all new prompts across the 12 supported locales. It also routes the confirmation event call through the existing OpenWebUI sync/async compatibility wrapper for consistency with the rest of the tool.
+
+### New Features
+- New `REQUIRE_CONFIRMATION` valve (default `True`) prompts the user via `__event_call__` before `update_skill`, `delete_skill`, and overwrite paths in `create_skill` / `install_skill`.
+- Cancellations short-circuit cleanly and return a structured `{cancelled: true, action, id, name, message, ...}` result, plus a localized status update so the assistant can report the outcome.
+- When no interactive event channel is available, the tool surfaces a localized error pointing operators to the new valve instead of silently proceeding.
+
+### Bug Fixes
+- N/A — this release is feature-only.
+
+### Enhancements
+- Added confirmation/cancellation translations (title, message, status, error, "no description" placeholder) for all 12 supported locales.
+- Documented the new valve in both `README.md` and `README_CN.md` valves tables.
+- `_request_confirmation` routes through `_call_openwebui_compat` for consistency with the rest of the OpenWebUI integration surface.
+
+### Migration Notes
+- Default behavior changes: existing flows that call `update_skill`, `delete_skill`, or trigger overwrite in `create_skill` / `install_skill` will now show a confirmation prompt by default. Set `REQUIRE_CONFIRMATION` to `False` to restore the previous "execute immediately" behavior.
+- No Valve key was renamed or removed.
diff --git a/plugins/tools/openwebui-skills-manager/v0.3.3_CN.md b/plugins/tools/openwebui-skills-manager/v0.3.3_CN.md
new file mode 100644
index 0000000..eae7637
--- /dev/null
+++ b/plugins/tools/openwebui-skills-manager/v0.3.3_CN.md
@@ -0,0 +1,20 @@
+# OpenWebUI Skills Manager v0.3.3 版本发布说明
+
+本次发布为破坏性操作引入了可选的确认流程,并将所有新增提示翻译至 12 种支持的语言。同时将确认事件调用接入既有的 OpenWebUI 同步/异步兼容封装,保持与工具其余部分的一致性。
+
+### 新功能
+- 新增 `REQUIRE_CONFIRMATION` 阀门(默认 `True`),在执行 `update_skill`、`delete_skill` 以及 `create_skill` / `install_skill` 触发覆盖前通过 `__event_call__` 向用户弹出确认。
+- 用户取消时操作立即中断,返回结构化的 `{cancelled: true, action, id, name, message, ...}` 结果,并附带本地化状态信息,便于助手向用户汇报。
+- 当上下文不存在交互式事件通道时,工具会抛出本地化错误提示并指引运维人员关闭该阀门,而不是悄无声息地继续执行。
+
+### 问题修复
+- 无 —— 本次为纯功能版本。
+
+### 优化提升
+- 新增确认/取消相关翻译(标题、提示、状态、错误、“无描述”占位符)覆盖所有 12 种支持语言。
+- 在 `README.md` 与 `README_CN.md` 的阀门表中补充了对新阀门的说明。
+- `_request_confirmation` 通过 `_call_openwebui_compat` 调度事件回调,与 OpenWebUI 集成层其余部分保持一致。
+
+### 迁移说明
+- 默认行为变化:现有调用 `update_skill`、`delete_skill` 或在 `create_skill` / `install_skill` 触发覆盖的流程,将默认弹出确认对话框。如需恢复“直接执行”的旧行为,请将 `REQUIRE_CONFIRMATION` 设为 `False`。
+- 没有重命名或移除任何 Valve 键。