Skip to content

[Feature] Enhance command tool with improved normalization and blacklist support#599

Merged
dingyi222666 merged 4 commits into
v1-devfrom
feat/command
Oct 17, 2025
Merged

[Feature] Enhance command tool with improved normalization and blacklist support#599
dingyi222666 merged 4 commits into
v1-devfrom
feat/command

Conversation

@dingyi222666
Copy link
Copy Markdown
Member

This PR enhances the command tool system with improved command name normalization and adds blacklist support for better control over exposed commands.

New Features

  • Enhanced Command Name Normalization: Added comprehensive Chinese-to-English mapping for command names, supporting 150+ common command terms (e.g., 帮助→help, 查询→query, 执行→execute). This ensures better compatibility when dealing with Chinese command names.

  • Command Blacklist Support: Added configurable command blacklist feature that allows filtering out specific commands and their sub-commands from the tool system. Commands can be blocked by exact name or prefix matching (e.g., blocking "command" also blocks "command.xxx").

  • Improved Schema Descriptions: Tool arguments and options now include proper descriptions in the Zod schema, providing better context for AI models when using these tools.

Bug Fixes

  • Fixed command name normalization to handle edge cases where names contain only special characters
  • Improved handling of multilingual descriptions (added support for en-US fallback)

Other Changes

  • Updated koishi-plugin-chatluna-storage-service peer dependency from v0.0.10 to v0.0.11 across all packages
  • Simplified command prompt generation by removing redundant formatting
  • Added new locale entries for command blacklist configuration
  • Reformatted package.json files for consistency

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @dingyi222666, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly upgrades the command tool system by introducing robust command name normalization, including extensive Chinese-to-English translation, and a new configurable blacklist feature to control command exposure. It also refines tool schema descriptions for better AI model understanding and includes minor bug fixes and dependency updates, making the command system more flexible and intelligent.

Highlights

  • Enhanced Command Name Normalization: Implemented comprehensive Chinese-to-English mapping for over 150 common command terms, improving compatibility and consistency in command processing.
  • Command Blacklist Support: Added a configurable feature to block specific commands and their sub-commands, enhancing control over exposed functionalities within the tool system.
  • Improved Schema Descriptions: Tool arguments and options now include proper descriptions directly within the Zod schema, providing better context and clarity for AI models when utilizing these tools.
  • Refined Multilingual Description Handling: The system now includes 'en-US' as a fallback for multilingual descriptions, improving robustness for internationalization.
  • Dependency Update: The peer dependency for koishi-plugin-chatluna-storage-service has been updated from v0.0.10 to v0.0.11 across all relevant packages.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 17, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (26)
  • packages/adapter-azure-openai/package.json is excluded by !**/*.json
  • packages/adapter-claude/package.json is excluded by !**/*.json
  • packages/adapter-deepseek/package.json is excluded by !**/*.json
  • packages/adapter-dify/package.json is excluded by !**/*.json
  • packages/adapter-doubao/package.json is excluded by !**/*.json
  • packages/adapter-gemini/package.json is excluded by !**/*.json
  • packages/adapter-hunyuan/package.json is excluded by !**/*.json
  • packages/adapter-ollama/package.json is excluded by !**/*.json
  • packages/adapter-openai-like/package.json is excluded by !**/*.json
  • packages/adapter-openai/package.json is excluded by !**/*.json
  • packages/adapter-qwen/package.json is excluded by !**/*.json
  • packages/adapter-rwkv/package.json is excluded by !**/*.json
  • packages/adapter-spark/package.json is excluded by !**/*.json
  • packages/adapter-wenxin/package.json is excluded by !**/*.json
  • packages/adapter-zhipu/package.json is excluded by !**/*.json
  • packages/core/package.json is excluded by !**/*.json
  • packages/extension-long-memory/package.json is excluded by !**/*.json
  • packages/extension-mcp/package.json is excluded by !**/*.json
  • packages/extension-tools/package.json is excluded by !**/*.json
  • packages/extension-variable/package.json is excluded by !**/*.json
  • packages/renderer-image/package.json is excluded by !**/*.json
  • packages/service-embeddings/package.json is excluded by !**/*.json
  • packages/service-image/package.json is excluded by !**/*.json
  • packages/service-search/package.json is excluded by !**/*.json
  • packages/service-vector-store/package.json is excluded by !**/*.json
  • packages/shared-adapter/package.json is excluded by !**/*.json

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

在配置中新增公有字段 commandBlacklist(字符串数组),并将该黑名单传入命令插件以过滤命令(含子命令与带前缀的命令);同时调整命令名称规范化、描述获取逻辑及 PickCommandType 类型。

Changes

内聚体 / 文件(s) 变更摘要
配置扩展
\packages/extension-tools/src/config.ts``
Config 接口添加公有字段 commandBlacklist: string[];在配置 schema(export const Config)中加入 commandBlacklist 项,类型为字符串数组,role='table',默认值为 ['command','channel','inspect','plugin','user','usage']
命令过滤与类型扩展
\packages/extension-tools/src/plugins/command.ts``
getCommandList 签名新增 blacklist 参数并默认 [],在构建命令映射与处理 rawCommandList 时应用黑名单过滤(包含子命令和含 chatluna 前缀的命令);PickCommandType 新增可选 confirm?: boolean;引入并使用 normalizeCommandName(含中英映射、字母数字规范化、以及以 randomUUID 的 fallback);getDescription 优先级调整为 zh-CN -> '' -> en-US -> 'No description';简化 generateSingleCommandPrompt 返回内容。

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Config as Config (含 commandBlacklist)
    participant CmdPlugin as command plugin
    participant Registry as Command Registry

    Note over User,Config: 启动或加载配置
    User->>Config: 读取配置
    Config-->>CmdPlugin: 提供 commandList 与 commandBlacklist

    Note over CmdPlugin,Registry: 获取原始命令
    CmdPlugin->>Registry: 请求 rawCommandList
    Registry-->>CmdPlugin: 返回 rawCommandList

    Note over CmdPlugin: 新增过滤与规范化流程
    CmdPlugin->>CmdPlugin: 根据 commandBlacklist 进行过滤(含子命令/前缀)
    CmdPlugin->>CmdPlugin: normalizeCommandName(中英映射、alnum、UUID fallback)
    CmdPlugin->>CmdPlugin: getDescription(zh-CN -> '' -> en-US -> fallback)

    CmdPlugin-->>User: 返回过滤并规范化后的命令列表
Loading

代码审查难度评估

🎯 4(Complex) | ⏱️ ~45 分钟

理由:变更涉及公共配置、插件函数签名和类型扩展、命令过滤与规范化逻辑、以及多语言描述处理等多方面,需要检查边界条件、黑名单匹配(子命令/前缀)、以及规范化与唯一性 fallback 的正确性。

可能相关的 PR

诗句

🐇 我是小兔守命令,黑名单把杂项拦,
名称净化换新颜,描述多语暖心间,
若无名我生 UUID,插件表中更安然 ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed PR标题"[Feature] Enhance command tool with improved normalization and blacklist support"清晰地反映了本次变更的主要内容。根据raw_summary,此PR的核心改动包括:添加了commandBlacklist配置字段、增强了命令名称规范化功能(包括中英文映射),以及扩展了命令过滤能力。标题准确概括了这些主要改动,具体而非含糊,能让团队成员快速理解此PR的核心目的。
Description Check ✅ Passed PR描述详细阐述了本次变更的所有主要方面,包括增强的命令名称规范化功能、命令黑名单支持、改进的Schema描述、bug修复以及其他更改。这些描述与raw_summary和pr_objectives中记录的实际代码变更保持一致,涵盖了添加commandBlacklist配置、更新getCommandList函数签名、中英文映射等核心改动。描述内容充分、有组织、且直接关联到本PR的实际改动。

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces significant enhancements to the command tool system. The addition of a command blacklist and improved command name normalization, especially with Chinese-to-English mapping, are great features for better control and compatibility. The refactoring to include argument and option descriptions directly in the Zod schema is a solid improvement for AI model interaction.

I've identified a potential issue with the new command normalization logic that could lead to name collisions, and I've suggested a fix. I also found a small area of code duplication in the schema generation that could be refactored for better maintainability.

Overall, these are valuable additions that improve the robustness and usability of the command tool. Great work!

Comment thread packages/extension-tools/src/plugins/command.ts
Comment thread packages/extension-tools/src/plugins/command.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (6)
packages/extension-tools/src/config.ts (1)

163-174: Schema 默认值合适,建议加 description 并在 UI 标明“前缀匹配”。

当前仅标注了 role('table') 与默认列表。建议添加描述,明确“命中精确名或以该前缀开头的子命令(a.b)也会被过滤”。

可按下述方式补充描述与示例:

-            commandBlacklist: Schema.array(Schema.string())
-                .role('table')
+            commandBlacklist: Schema.array(Schema.string())
+                .role('table')
+                .description('要屏蔽的命令名或前缀(命中后其所有子命令一并屏蔽,例如 "command" 也会屏蔽 "command.xxx")')
                 .default([
                     'command',
                     'channel',
                     'inspect',
                     'plugin',
                     'user',
                     'usage'
                 ])
packages/extension-tools/src/plugins/command.ts (5)

35-35: 规范化后的工具名可能碰撞,建议加去重后缀。

多个不同命令(中英映射/清洗后)可能归并到同一 normalizedName,注册的 toolId 会被覆盖。建议在冲突时为尾部追加短哈希(基于原始 name)。


184-193: Zod 类型可强化:数值/整数使用 coerce 与 int,布尔使用 coerce.boolean。

这样能更稳健地从字符串入参解析为目标类型,并约束整数/正整数场景。

可参考:

-            const zodType = this.getZodType(arg.type)
+            const zodType = this.getZodType(arg.type)
...
-            schemaShape[arg.name] = arg.required
+            schemaShape[arg.name] = arg.required
                 ? zodTypeWithDescription
                 : zodTypeWithDescription.optional()

并在 getZodType 中(文件内现有函数):

-    private getZodType(type: string): z.ZodTypeAny {
+    private getZodType(type: string): z.ZodTypeAny {
       switch (type) {
         case 'text':
         case 'string':
         case 'date':
-          return z.string()
+          return z.string()
         case 'integer':
         case 'posint':
         case 'natural':
         case 'number':
-          return z.number()
+          return type === 'integer' || type === 'posint' || type === 'natural'
+            ? z.coerce.number().int().min(type === 'natural' ? 0 : 1)
+            : z.coerce.number()
         case 'boolean':
-          return z.boolean()
+          return z.coerce.boolean()
         default:
           return z.string()
       }
     }

(如不希望引入 coerce,可保持现状。)

Also applies to: 194-203, 206-209


531-533: 动态正则来自变量键,存在 ReDoS 风险与不必要开销。

键为常量映射时无需正则,建议用 split/join 或 replaceAll。

基于静态分析提示(regexp-from-variable)。
可改为:

-    for (const [chinese, english] of Object.entries(chineseToEnglish)) {
-        result = result.replace(new RegExp(chinese, 'g'), english)
-    }
+    for (const [chinese, english] of Object.entries(chineseToEnglish)) {
+        result = result.split(chinese).join(english)
+    }

536-540: 建议统一小写,避免同名不同大小写导致重复。

清洗后追加 toLowerCase(),减少工具名冲突面。

-    result = result.replace(/[^a-zA-Z0-9.]/g, '')
+    result = result.replace(/[^a-zA-Z0-9.]/g, '').toLowerCase()

27-31: 黑名单生效与名称规范化的行为请补测。

建议覆盖:

  • 黑名单前缀命中与子命令级联过滤;
  • 名称全中文/仅符号/数字开头的回退前缀;
  • 多命令映射为同一规范名时的冲突处理(期望告警或自动去重)。

需要我补一组最小复现的单元测试样例吗?

Also applies to: 358-550

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aeb1cd2 and 2750bf0.

⛔ Files ignored due to path filters (7)
  • package.json is excluded by !**/*.json
  • packages/adapter-gemini/package.json is excluded by !**/*.json
  • packages/core/package.json is excluded by !**/*.json
  • packages/extension-mcp/package.json is excluded by !**/*.json
  • packages/extension-tools/package.json is excluded by !**/*.json
  • packages/extension-tools/src/locales/en-US.schema.yml is excluded by !**/*.yml
  • packages/extension-tools/src/locales/zh-CN.schema.yml is excluded by !**/*.yml
📒 Files selected for processing (2)
  • packages/extension-tools/src/config.ts (2 hunks)
  • packages/extension-tools/src/plugins/command.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension-tools/src/plugins/command.ts (1)
packages/extension-tools/src/config.ts (3)
  • Config (4-50)
  • Config (52-258)
  • name (265-265)
🪛 ast-grep (0.39.6)
packages/extension-tools/src/plugins/command.ts

[warning] 531-531: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(chinese, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint
  • GitHub Check: build
🔇 Additional comments (5)
packages/extension-tools/src/plugins/command.ts (4)

27-31: 将黑名单透传到 getCommandList:方向正确。

入口处将 config.commandBlacklist 传入,符合新配置设计。无阻塞问题。


74-75: 提示文案简化 OK。

单命令提示精简为一行,直观明了。


82-88: 描述回退顺序合理,涵盖 zh-CN/空键/en-US。

多语言兜底逻辑明确。


92-94: 签名扩展良好,默认空数组安全。

blacklist 默认 [] 可避免调用方遗漏参数导致异常。

packages/extension-tools/src/config.ts (1)

23-23: commandBlacklist 已在 i18n 中包含完整说明,无需进一步改动

已确认 packages/extension-tools/src/locales/en-US.schema.ymlzh-CN.schema.yml 都包含了该字段的详细描述:

  • 中文: 屏蔽的一级指令列表(包括所有子指令)。默认屏蔽敏感的管理类指令。
  • 英文: Blacklist of top-level commands to block (including all sub-commands). Sensitive management commands are blocked by default.

描述已说明支持子命令一并屏蔽的功能,原建议已得到实现。

Comment thread packages/extension-tools/src/plugins/command.ts
Comment thread packages/extension-tools/src/plugins/command.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
packages/extension-tools/src/plugins/command.ts (4)

165-204: 去重封装:参数与选项的 Zod 构建逻辑重复。

可抽为一个小的辅助函数,减少重复与分支。

-        this.command.arguments.forEach((arg) => {
-            const zodType = this.getZodType(arg.type)
-            const description = getDescription(arg.description)
-            const zodTypeWithDescription = zodType.describe(description)
-
-            schemaShape[arg.name] = arg.required
-                ? zodTypeWithDescription
-                : zodTypeWithDescription.optional()
-        })
+        const addPropertyToSchema = (prop: {
+            name: string
+            type: string
+            description: string | Record<string, string>
+            required: boolean
+        }) => {
+            if (prop.name === 'help') return
+            const zodType = this.getZodType(prop.type)
+            const desc = getDescription(prop.description)
+            const zType = zodType.describe(desc)
+            schemaShape[prop.name] = prop.required ? zType : zType.optional()
+        }
+
+        this.command.arguments.forEach(addPropertyToSchema)
-        this.command.options.forEach((opt) => {
-            if (opt.name !== 'help') {
-                const zodType = this.getZodType(opt.type)
-                const description = getDescription(opt.description)
-                const zodTypeWithDescription = zodType.describe(description)
-
-                schemaShape[opt.name] = opt.required
-                    ? zodTypeWithDescription
-                    : zodTypeWithDescription.optional()
-            }
-        })
+        this.command.options.forEach(addPropertyToSchema)

17-17: 移除对 crypto.randomUUID() 的依赖,改用现有 randomString

统一依赖与运行时兼容性,避免在非 Node 环境或打包场景下额外引入 crypto

- import { randomUUID } from 'crypto'
-            (result ||
-                randomUUID()
-                    .substring(0, 12)
-                    .replace(/[^a-zA-Z0-9]/g, ''))
+            (result || randomString(12))

Also applies to: 540-547


98-116: 避免误杀:includes('chatluna') 过滤过宽,应仅匹配根命令或其子命令。

当前写法会误过滤任意包含子串的命令名,属功能性问题。改为严格等于或前缀匹配。

建议修改:

-                // Filter out chatluna commands
-                if (item.name.includes('chatluna')) {
+                // Filter out chatluna root and its sub-commands
+                if (item.name === 'chatluna' || item.name.startsWith('chatluna.')) {
                     return false
                 }

536-538: 用下划线替代非法字符,降低命名碰撞风险。

直接去除会把 user-listuserlist 归一到同名,可能导致工具注册被覆盖。

-    // Remove all non-alphanumeric characters except dots (for command hierarchy)
-    result = result.replace(/[^a-zA-Z0-9.]/g, '')
+    // Replace invalid chars with underscore to preserve boundaries
+    result = result
+        .replace(/[^a-zA-Z0-9.]+/g, '_')
+        .replace(/^_+|_+$/g, '')
🧹 Nitpick comments (4)
packages/extension-tools/src/plugins/command.ts (4)

133-141: 避免把 JSON 串写入描述:改用 getDescription 生成自然语言。

JSON.stringify(item.description) 会把多语言对象直接序列化进提示词,影响可读性。

-                if (
-                    (rawCommand.description?.length ?? 0) < 1 &&
-                    item.description
-                ) {
-                    description = JSON.stringify(item.description)
-                }
+                if (
+                    (rawCommand.description?.length ?? 0) < 1 &&
+                    item.description
+                ) {
+                    // 统一转为可读字符串描述
+                    description = getDescription(
+                        item.description as unknown as Record<string, string> | string
+                    )
+                }

531-534: 用纯字符串替换替代动态正则,规避 ReDoS 及不必要的开销。

new RegExp(chinese, 'g') 来自变量,虽源自常量表,但可直接用 split/join 或 replaceAll。

-    for (const [chinese, english] of Object.entries(chineseToEnglish)) {
-        result = result.replace(new RegExp(chinese, 'g'), english)
-    }
+    for (const [chinese, english] of Object.entries(chineseToEnglish)) {
+        if (result.includes(chinese)) {
+            // 纯字符串替换,避免动态正则
+            result = result.split(chinese).join(english)
+        }
+    }

(依据静态分析提示)


34-71: 为规范化后的工具名增加去重保护,避免覆盖注册。

即使用下划线替换,仍可能存在重名;建议在注册时做去重处理。

-    for (const command of commandList) {
+    const usedNames = new Set<string>()
+    for (const command of commandList) {
         const prompt = generateSingleCommandPrompt(command)
-        const normalizedName = normalizeCommandName(command.name)
+        let normalizedName = normalizeCommandName(command.name)
+        while (usedNames.has(normalizedName)) {
+            normalizedName = `${normalizedName}_${randomString(4)}`
+        }
+        usedNames.add(normalizedName)

74-76: 提示语可加入命令名,提升可读性(可选)。

-    return `Tool Description: ${command.description || 'No description'}\n\n`
+    return `Tool: ${command.name}\nDescription: ${command.description || 'No description'}\n\n`
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2750bf0 and 2167f4d.

📒 Files selected for processing (1)
  • packages/extension-tools/src/plugins/command.ts (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension-tools/src/plugins/command.ts (1)
packages/extension-tools/src/config.ts (3)
  • Config (4-50)
  • Config (52-258)
  • name (265-265)
🪛 ast-grep (0.39.6)
packages/extension-tools/src/plugins/command.ts

[warning] 532-532: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(chinese, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: lint
🔇 Additional comments (3)
packages/extension-tools/src/plugins/command.ts (3)

28-32: 黑名单参数接入正确,逻辑清晰。

commandBlacklist 透传到 getCommandList 并统一过滤来源,设计合理。


207-211: 无参兜底输入设计合理。

提供 input 可选字符串作为兜底,提升可用性。


83-89: 多语言描述回退顺序合理。

优先 zh-CN,再空键,后 en-US,最后兜底。

…on and blacklist support

- Refactor normalizeCommandName to translate Chinese/non-English characters to English equivalents
- Remove underscore/punctuation from normalized command names, use alphanumeric characters only
- Add commandBlacklist config to block top-level commands and their sub-commands
- Default blacklist includes sensitive commands: command, channel, inspect, plugin, user, usage
- Simplify tool prompt generation to only include description
- Add parameter descriptions to Zod schema for better LLM understanding
- Update i18n files (zh-CN, en-US) with blacklist configuration translations
Update koishi-plugin-chatluna-storage-service peer dependency from
v0.0.10 to v0.0.11 across multiple packages to ensure compatibility
with the latest storage service features and fixes.

Affected packages:
- packages/core
- packages/adapter-gemini
- packages/extension-mcp
- packages/extension-tools
Replace crypto.randomUUID() with named import randomUUID() for
better tree-shaking and explicit dependency declaration.
- Update peerDependencies to koishi-plugin-chatluna ^1.3.0-alpha.68 across all packages
- Bump adapter-dify version from 1.3.0-alpha.11 to 1.3.0-alpha.12
- Bump adapter-gemini version from 1.3.0-alpha.19 to 1.3.0-alpha.20
- Standardize package.json formatting (2-space indentation)

This ensures all packages are compatible with the latest chatluna core version.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
packages/extension-tools/src/plugins/command.ts (4)

185-205: 参数和选项的模式生成逻辑存在重复。

可以将重复的 Zod 类型生成逻辑提取为辅助函数以提高可维护性。

参考重构方案:

const addPropertyToSchema = (prop: { name: string; type: string; description: string | Record<string, string>; required: boolean }) => {
    if (prop.name === 'help') return;

    const zodType = this.getZodType(prop.type)
    const description = getDescription(prop.description)
    const zodTypeWithDescription = zodType.describe(description)

    schemaShape[prop.name] = prop.required
        ? zodTypeWithDescription
        : zodTypeWithDescription.optional()
}

this.command.arguments.forEach(addPropertyToSchema)
this.command.options.forEach(addPropertyToSchema)

539-547: 建议使用现有的 randomString 函数。

使用 crypto.randomUUID() 引入了额外依赖。建议使用文件中已有的 randomString 辅助函数,保持代码一致性。

应用此修改:

     if (result.length === 0 || /^[0-9]/.test(result)) {
         result =
             'cmd' +
-            (result ||
-                randomUUID()
-                    .substring(0, 12)
-                    .replace(/[^a-zA-Z0-9]/g, ''))
+            (result || randomString(12))
     }

98-103: chatluna 过滤条件仍然过宽。

includes('chatluna') 会误匹配任何包含该子串的命令。建议改为精确匹配根命令或前缀匹配子命令。

应用此修复:

-                if (item.name.includes('chatluna')) {
+                if (item.name === 'chatluna' || item.name.startsWith('chatluna.')) {
                     return false
                 }

536-537: 命令名称规范化可能导致冲突。

移除所有非字母数字字符(点号除外)可能导致不同命令规范化为相同名称,例如 user-listuserlist 都会变成 userlist

建议使用下划线替换无效字符以保持唯一性:

-    result = result.replace(/[^a-zA-Z0-9.]/g, '')
+    result = result.replace(/[^a-zA-Z0-9.]+/g, '_')
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2167f4d and 2572b65.

⛔ Files ignored due to path filters (7)
  • package.json is excluded by !**/*.json
  • packages/adapter-gemini/package.json is excluded by !**/*.json
  • packages/core/package.json is excluded by !**/*.json
  • packages/extension-mcp/package.json is excluded by !**/*.json
  • packages/extension-tools/package.json is excluded by !**/*.json
  • packages/extension-tools/src/locales/en-US.schema.yml is excluded by !**/*.yml
  • packages/extension-tools/src/locales/zh-CN.schema.yml is excluded by !**/*.yml
📒 Files selected for processing (2)
  • packages/extension-tools/src/config.ts (2 hunks)
  • packages/extension-tools/src/plugins/command.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/extension-tools/src/config.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/extension-tools/src/plugins/command.ts (1)
packages/extension-tools/src/config.ts (3)
  • Config (4-50)
  • Config (52-258)
  • name (265-265)
🪛 ast-grep (0.39.6)
packages/extension-tools/src/plugins/command.ts

[warning] 532-532: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(chinese, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: lint
🔇 Additional comments (6)
packages/extension-tools/src/plugins/command.ts (6)

28-32: 正确传递黑名单参数。

将配置中的命令黑名单正确传递给 getCommandList 函数,实现了黑名单过滤功能。


74-76: 简化了提示词生成逻辑。

移除了详细的提示词构建,仅返回描述信息,使代码更加简洁。


78-89: 多语言描述处理逻辑完善。

添加了完整的多语言回退机制(zh-CN → '' → en-US → 默认),提升了国际化支持。


104-113: 黑名单过滤逻辑实现正确。

使用精确匹配和前缀匹配来过滤黑名单命令及其子命令,逻辑清晰且正确。


207-211: 为可选输入字段添加了描述。

为空参数命令的默认输入字段添加描述,提升了 AI 模型的理解能力。


552-556: 类型定义与新功能一致。

PickCommandType 正确扩展了 confirm 字段以支持命令确认功能。

Comment thread packages/extension-tools/src/plugins/command.ts
@dingyi222666 dingyi222666 merged commit 7d927c4 into v1-dev Oct 17, 2025
3 checks passed
@dingyi222666 dingyi222666 deleted the feat/command branch October 17, 2025 16:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant