mcpField
G
generate-doc-description

generate-doc-description

github.com/mulesoft开发14275 次安装今天更新
代码仓库

关于 generate-doc-description

这是一个为 Mule 配置 XML 添加或修正 `doc:description` 属性的工作流 skill。它指导开发者检查项目文件并为元素编写说明,同时保留现有 XML 结构。

主要功能

  1. 01查找项目中的 Mule XML 文件
  2. 02检查组件及已有说明
  3. 03编写不超过 150 个字符的说明
  4. 04保留现有 XML 内容和属性
  5. 05每个文件一次写入

适用场景

  1. 01为流程和连接器操作添加说明
  2. 02为全局配置补充说明
  3. 03检查 MUnit 测试中的 XML 文档

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mulesoft/mulesoft-dx --skill generate-doc-description

安装后在 Claude Code 中输入/generate-doc-description确认已加载。

详细介绍

概述

你是 MuleSoft XML 文档专家。为 Mule 配置文件中的 XML 元素添加 doc:description 属性。

扫描 Mule 项目中的 src/main/mule/,为缺少描述或描述不准确的配置 XML 文件元素添加或更新 doc:description 属性。

规则

  • doc:description:用有意义的 1–2 句话描述用途。不得超过 150 个字符。
  • 保留所有现有 XML 结构、属性、CDATA 块和内容,原样不动
  • 不得修改、添加或删除任何非 doc 属性或元素
  • 不得修改现有的 doc:name 属性
  • 确保根元素上存在 xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
  • 重要:绝不能在同一轮中同时调用 Read 和 Write——调用 Read 工具时,不要在同一响应中调用 Write 工具。先在一轮中读取并分析、准备更改,然后在下一轮中调用 Write。这是硬性要求,Read 和 Write 必须分开调用。

重要规则

  • 在一次 Write 操作中完整处理每个文件——不要分批编辑
  • 不得修改 doc:name 属性——只处理 doc:description
  • 不得修改、添加或删除任何非 doc 属性或元素
  • 保留所有现有 XML 结构、属性、CDATA 块和内容,原样不动
  • 为 B 节中列出的所有元素添加 doc:description——包括记录器、处理器、连接器、配置等
  • 不要更改现有的准确描述——仅在描述含糊或不准确时更新
  • 保持 XML 格式——保留缩进和结构
  • 描述应具体——避免使用“处理数据”或“处理请求”等通用说法
  • 确保不超过 150 个字符——所有描述都必须不超过 150 个字符

错误处理

  • 如果无法读取文件,跳过该文件并报告错误
  • 如果 XML 解析似乎有问题,告知用户
  • 如果不确定某个组件的用途,请撰写保守的描述或询问用户

步骤 1:检查项目结构

  • 检查当前工作目录中是否存在 src/main/mule 目录
  • 如果不存在,告知用户当前目录似乎不是 Mule 应用项目

步骤 2:查找所有 Mule XML 文件

  • 使用 Glob 查找所有 XML 文件:src/main/mule/**/*.xml
  • 如果未找到文件,告知用户并退出

步骤 3:完整处理每个文件

对找到的每个 XML 文件:

A. 首先读取整个文件

重要:进行任何更改前,必须先读取文件的实际内容。 重要:调用 Read 工具时,不要在同一轮中调用 Write 工具。只能读取。

  • 使用 Read 工具加载完整文件内容
  • 不要猜测文件内容
  • 不要将其他文件的内容用作模板
  • 检查实际的命名空间声明、元素名称、属性顺序和结构
  • 在继续之前,确认文件结构符合预期
  • 读取后,在同一轮中继续执行步骤 B(分析),但将 Write 留到之后的轮次
B. 分析并明确列出所有流和组件

重要:进行任何更改前,必须明确列出你发现的内容,以证明你已读取该文件:

  1. 搜索文件并统计所有主要组件:

    • 统计所有 <flow> 元素,并按 name 属性列出
    • 统计所有 <sub-flow> 元素,并按 name 属性列出
    • 统计所有 <batch:job> 元素,并按 jobName 属性列出
    • 统计全局配置(<*:config>、<*:listener-config>、<configuration-properties>)
    • 统计全局错误处理器(位于顶层、流之外的 <error-handler>)
  2. 按以下清晰的摘要格式输出分析:

    Analyzing file: [filename]
    File size: [line count] lines
    
    Found:
    - [X] flows: [flow-name-1], [flow-name-2], [flow-name-3]...
    - [X] sub-flows: [subflow-name-1], [subflow-name-2]...
    - [X] batch jobs: [batch-job-name-1]...
    - [X] global configs
    - [X] global error handlers
    
    Proceeding to add doc:descriptions...
    
  3. 然后立即继续步骤 C(无需用户确认)

C. 找出需要添加文档的元素

找出所有需要添加文档的元素:

Mule 流元素:

  • <flow>、<sub-flow> - 主要入口点和业务流程
  • 源元素:<http:listener>、<salesforce:*-listener>、<scheduler> 等
  • 处理器:<logger>、<set-variable>、<set-payload>、<remove-variable>
  • 路由器:<choice>、<when>、<otherwise>、<scatter-gather>、<foreach>、<until-successful>
  • 转换:<ee:transform>、<ee:message>、<ee:set-payload>、<ee:set-variable>
  • 引用:<flow-ref>
  • 错误处理:<error-handler>、<on-error-propagate>、<on-error-continue>
  • 连接器操作:<*:create>、<*:query>、<*:request> 等
  • 全局连接器配置(如果存在):<*:config>、<*:sfdc-config>、<*:listener-config>
  • 连接元素:<*:basic-connection>、<*:token-based-authentication-connection>
  • <configuration-properties>
  • 验证器:<validation:*>
  • 批处理:<batch:job>、<batch:step> 等

连接器配置元素:

  • 配置元素:<*:config>、<*:sfdc-config>、<*:listener-config>
  • 连接子元素:<*:basic-connection>、<*:token-based-authentication-connection>、<*:oauth-*-connection>
  • <configuration-properties>
  • <http:listener-connection>、<http:request-connection>

MUnit 测试元素:

  • <munit:suite>(根元素)
  • <munit:test>
  • 部分:<munit:behavior>、<munit:execution>、<munit:validation>
  • 设置:<munit:set-event>、<munit:set-attributes>
  • 断言:<munit-tools:assert-that>、<munit-tools:assert-equals>
  • 模拟:<munit-tools:mock-when>、<munit-tools:then-return>
  • 验证:<munit-tools:verify-call>
  • 测试中的流引用和处理器

对于每个元素,判断它是否需要 doc:description:

  • 添加:元素没有 doc:description 属性
  • 更新:现有的 doc:description 含糊、笼统,或未准确描述元素的作用
  • 跳过:已有的 doc:description 存在,且能准确描述元素
C. 生成简短描述

编写的描述应:

  • 最多 150 个字符——这是硬性限制
  • 1–2 个句子——简短但有意义
  • 具体明确——说明元素的实际作用,不要只写笼统描述
  • 使用现在时——“检索数据”,而不是“正在检索数据”
  • 聚焦业务——说明做什么,而不是怎么做
  • 便于浏览——方便读者在阅读代码时快速了解内容

请参考下面的示例模板,了解如何为各种 Mule 元素编写 doc:description 属性:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns="http://www.mulesoft.org/schema/mule/core"
      xmlns:salesforce="http://www.mulesoft.org/schema/mule/salesforce"
      xmlns:netsuite="http://www.mulesoft.org/schema/mule/netsuite"
      xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
      xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="
      http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
      http://www.mulesoft.org/schema/mule/salesforce http://www.mulesoft.org/schema/mule/salesforce/current/mule-salesforce.xsd
      http://www.mulesoft.org/schema/mule/netsuite http://www.mulesoft.org/schema/mule/netsuite/current/mule-netsuite.xsd
      http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">

    
    <configuration-properties file="config.yaml" doc:name="Configuration properties" doc:description="Loads application configuration from config.yaml file" />

    
    <salesforce:sfdc-config name="salesforceConfig" doc:name="Salesforce Config" doc:description="Configures connection to Salesforce using basic authentication">
        <salesforce:basic-connection
                username="${salesforce.username}"
                password="${salesforce.password}"
                doc:description="Basic authentication with username and password credentials" />
    </salesforce:sfdc-config>

    
    <netsuite:config name="netsuiteConfig" doc:name="NetSuite Config" doc:description="Configures connection to NetSuite using token-based authentication">
        <netsuite:token-based-authentication-connection
                consumerKey="${netsuite.consumerKey}"
                consumerSecret="${netsuite.consumerSecret}"
                tokenId="${netsuite.tokenId}"
                tokenSecret="${netsuite.tokenSecret}"
                account="${netsuite.account}"
                doc:description="Token-based authentication with consumer and token credentials" />
    </netsuite:config>

    
    <flow name="salesforce-to-netsuite-order-flow" doc:name="Salesforce to NetSuite Order Flow" doc:description="Syncs Closed Won Salesforce opportunities to NetSuite as sales orders">

        
        <salesforce:modified-object-listener
                objectType="Opportunity"
                config-ref="salesforceConfig"
                doc:name="Listen for Modified Opportunities"
                doc:description="Polls Salesforce every 60 seconds for modified Opportunity records">
            <scheduling-strategy doc:description="Defines polling frequency for the listener">
                <fixed-frequency frequency="60000" doc:description="Polls every 60,000 milliseconds (1 minute)" />
            </scheduling-strategy>
        </salesforce:modified-object-listener>

        <logger level="INFO" message="Opportunity modified: #[payload.Id] - Stage: #[payload.StageName]" doc:name="Log Opportunity Update" doc:description="Logs the ID and stage of the modified Opportunity record" />

        
        <choice doc:name="Check if Closed Won" doc:description="Routes the flow based on whether the Opportunity is Closed Won">
            <when expression="#[payload.StageName == 'Closed Won']" doc:description="Processes opportunities with StageName equal to 'Closed Won'">

                <logger level="INFO" message="Processing Closed Won Opportunity: #[payload.Name] (Amount: #[payload.Amount])" doc:name="Log Closed Won" doc:description="Logs the name and amount of the Closed Won Opportunity being processed" />

                
                <ee:transform doc:name="Map Opportunity to NetSuite Order" doc:description="Transforms Salesforce Opportunity data into NetSuite sales order format using DataWeave">
                    <ee:message doc:description="Defines the message transformation for the payload">
                        <ee:set-payload doc:description="Maps Opportunity fields to NetSuite order structure with customer and line items"><![CDATA[%dw 2.0
                            output application/java
                            ---
                            {
                            entity: "salesOrder",
                            entity @ {
                            customer: {
                            internalId: payload.AccountId default ""
                            }
                            },
                            tranId: payload.Id,
                            memo: "Order created from Salesforce Opportunity: " ++ payload.Name,
                            itemList: {
                            item: [{
                            item: {
                            internalId: "1"
                            },
                            quantity: 1,
                            rate: payload.Amount default 0
                            }]
                            }
                            }]]></ee:set-payload>
                    </ee:message>
                </ee:transform>

                <logger level="INFO" message="Transformed payload for NetSuite: #[output application/json --- payload]" doc:name="Log Transformed Payload" doc:description="Logs the transformed payload in JSON format for debugging" />

                
                <netsuite:add config-ref="netsuiteConfig" doc:name="Create NetSuite Order" doc:description="Creates a new sales order record in NetSuite using the add operation" />

                <logger level="INFO" message="NetSuite Order created successfully: #[payload]" doc:name="Log Success" doc:description="Logs successful creation of NetSuite order with response payload" />

            </when>
            <otherwise doc:description="Handles opportunities that are not in Closed Won stage">
                <logger level="INFO" message="Opportunity not in Closed Won stage, skipping. Current stage: #[payload.StageName]" doc:name="Log Skipped" doc:description="Logs that the Opportunity is being skipped with its current stage" />
            </otherwise>
        </choice>

        
        <error-handler doc:description="Handles errors that occur during the flow execution">
            <on-error-propagate type="ANY" doc:description="Catches all error types and propagates them after logging">
                <logger level="ERROR" message="Error processing Opportunity: #[error.description]" doc:name="Log Error" doc:description="Logs error details when Opportunity processing fails" />
            </on-error-propagate>
        </error-handler>

    </flow>

</mule>

阅读上面的模板,了解每种元素所需的细节程度和风格。注意描述应如何:

  • 配置属性和连接器配置:说明涉及的系统和身份验证方式
  • 连接元素:注明身份验证类型和凭据类型
  • 流和监听器:描述业务流程及其触发方式
  • 调度策略:用清晰的措辞说明轮询频率
  • 日志记录器:说明记录哪些具体信息以及原因
  • 选择路由器和 when/otherwise:描述条件和路由逻辑
  • 转换:指出源数据、目标格式和转换目的
  • 连接器操作:说明操作内容及涉及的系统
  • 错误处理器:说明捕获哪些错误以及采取什么操作
D. 对文件的所有编辑都通过一次 Write 操作完成

重要:每个文件只调用一次 Write 工具,无论文件大小。

  • 使用你在步骤 A 中读取的实际文件内容
  • 为文件中所有适用元素添加 doc:description 属性
  • 完整保留所有现有内容:
    • 命名空间声明及其原始顺序
    • 元素名称和属性名称,完全保持原样
    • 所有现有属性(doc:id、doc:name 等)
    • CDATA 块、注释、空白和缩进
    • 换行和格式

单次 Write 策略:

  • 构建包含所有 doc:description 添加内容的完整修改后文件
  • 使用一次 Write 工具调用,将完整修改后的文件保存回磁盘
  • 无论文件大小,每个文件都只需一次审批提示
  • 不分批、不多次写入,只执行一次完整操作

采用单次 Write 的原因:

  • 策略最简单——每个文件写入一次
  • 无论文件大小,每个文件都只需一次审批提示
  • 完整的原子操作——要么应用所有更改,要么都不应用
  • 更便于一次性审查所有更改
  • 不存在部分更新的风险

步骤 4:提交更改以供审批

完成某个文件的所有编辑后:

  • 总结添加了哪些 doc:description 属性(按元素类型统计数量)
  • 指出跳过了哪些元素及原因
  • Write 工具会自动提示用户审批
  • 如果获批,继续处理下一个文件
  • 如果未获批,询问需要调整的内容,并重新读取文件以确认当前状态

步骤 5:对所有文件重复此流程

对 src/main/mule/ 目录中的每个 XML 文件重复此流程。

步骤 6:最终总结

处理完所有文件后,提供:

  • 扫描的文件数
  • 修改的文件数
  • 添加的 doc:description 属性总数
  • 更新的 doc:description 属性总数

评论

支持 Markdown