mcpField
A
add-command

add-command

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

关于 add-command

为 Coralogix 的 `cx` CLI 添加命令的开发技能,指导贡献者选择命令模式,并完成实现、测试与验证。

主要功能

  1. 01选择 DataPrime 或 REST 模式
  2. 02添加 API 和命令模块
  3. 03将命令接入 CLI
  4. 04覆盖单元、集成及端到端测试
  5. 05运行构建、Lint 和格式检查

适用场景

  1. 01添加日志或 Span 查询命令
  2. 02封装 Coralogix REST API
  3. 03扩展 CLI 命令组

安装

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

$npx skills add https://github.com/coralogix/cx-cli --skill add-command

安装后在 Claude Code 中输入/add-command确认已加载。

详细介绍

添加 CLI 命令

在 cx 中添加新命令的端到端工作流。每个命令都属于两种类型之一——先确定类型,再按照相应步骤操作。

docs/adding-a-command.md 为以下每个步骤都提供了可直接复制粘贴的代码模板。请在阅读此工作流的同时参阅该文档。

步骤 0:了解要构建的内容

编写任何代码之前,先明确领域:

  1. 你要封装哪个 Coralogix API? 查找 API 文档或示例响应。了解数据模型——有哪些实体、实体包含哪些字段、支持哪些操作。
  2. 用户应该能够执行哪些操作? 列出子命令(例如 list、get、create)以及合适的标志。
  3. 这是否应该归入某个封装组? CLI 会将相关命令组织到封装组中。创建顶层命令之前,先检查命令是否适合归入现有组:
    • cx alerts - 告警定义和 schedulers
    • cx notifications - connectors、routers、presets、test
    • cx webhooks - 外发 Webhook 和 actions
    • cx enrichments - 丰富规则和 custom 丰富表
    • cx integrations - 集成和 extensions、contextual-data
    • cx iam - api-keys、roles、scopes、users、groups、ip-access 运行 cx schema,以 JSON 格式查看完整命令树。
  4. 适合哪种类型?
类型适用场景参考实现
A:基于 DataPrime查询日志、跨度或任何 DataPrime 数据源src/commands/logs/mod.rs
B:基于 REST封装 Coralogix REST API(大多数新命令)src/commands/alerts/api.rs + src/commands/alerts/mod.rs

DataPrime 命令会委托给共享管道,只需少量代码(约 130 行)。REST 命令则需要构建完整管道(API 客户端、扇出、合并、渲染)——代码更多,但控制力也更强。

重要: 所有 API 集成都必须使用 REST(HTTP)。CLI 从设计上仅支持 HTTP——请勿使用 gRPC。

步骤 1:阅读参考实现

编写任何代码之前,请阅读以下文件,熟悉现有模式。这一步至关重要——先阅读现有代码的 Agent,编写出的实现会与代码库保持一致,而不是另创模式。

务必阅读:

  • src/main.rs - 研究 Commands 枚举,了解变体的组织方式;查看 match cli.command 分发代码块,了解新变体应放在哪里。注意哪些命令会提前退出(无需凭据),哪些命令会经过完整的配置解析流程。留意封装组(例如 Notifications、Iam、Webhooks、Integrations)——它们是包含嵌套子命令枚举的顶层命令,用于组织相关领域的命令。如果你的命令属于现有组,应向该组的子命令枚举添加新变体,而不是创建顶层命令。
  • src/commands/mod.rs - 查看现有模块注册方式,确保将新模块添加到正确位置
  • docs/adding-a-command.md - 两种类型的完整指南和代码模板

基于 DataPrime 的类型——还需阅读:

  • src/commands/logs/mod.rs - 一个完整的 DataPrime 命令;注意所需代码很少,因为繁重的工作由共享管道完成
  • src/commands/dataprime/mod.rs - 命令将委托给的共享管道;了解 run_query() 的签名及其处理的内容(扇出、合并、溢写、Agent 输出)

基于 REST 的类型——还需阅读:

  • src/commands/alerts/api.rs - 查看响应类型的组织方式、API 结构体如何借用 &CxClient,以及反序列化测试的编写方式
  • src/commands/alerts/mod.rs - 查看处理器如何声明 pub mod api; 并通过 use api::{...}; 导入类型
  • src/commands/dashboards/mod.rs - 查看使用 render::* 辅助函数实现的扇出/合并/渲染模式,以及三种输出格式的处理方式

步骤 2:创建 API 层(仅 REST)

DataPrime 命令可跳过此步骤——它们使用共享的 DataPrime 流程。

创建 src/commands/<domain>/api.rs。完整模板请参阅 docs/adding-a-command.md §「Archetype B, Step 1」。

关键约定及其重要性:

  • 在响应类型上使用 #[serde(rename_all = "camelCase")]——Coralogix API 使用 camelCase JSON 键
  • 在 Vec 字段上使用 #[serde(default)]——API 有时会完全省略空数组,而不是发送 [],因此这可以避免反序列化失败
  • 对可能缺失的字段使用 Option<T>——应采取防御性做法;API 会不断演进,字段也会因层级而异
  • API 结构体借用 &CxClient(不要持有它)——客户端在整个扇出过程中共享,并且必须比单次 API 调用存活更久
  • 使用 const BASE_PATH 定义端点前缀——避免 URL 重复
  • 反序列化测试是必需的——测试正常情况和边缘情况(空列表、缺少可选字段),因为这些情况会导致生产环境故障

步骤 3:创建命令模块

创建 src/commands/<domain>/mod.rs。对于 REST 命令,在顶部声明 pub mod api;,这样处理器就能通过 use api::{...}; 使用同级 api.rs 中的类型。两种架构的完整模板请参阅 docs/adding-a-command.md。

DataPrime 架构

提供两项内容:

  1. 文本渲染器:pub fn render_<domain>_text(merged: &MergedResults) -> Result<()>——仅在 OutputFormat::Text 时调用;JSON 和 Agents 输出由共享流程处理
  2. 一个精简的 run() 包装函数,调用 super::dataprime::run_query() 并传入你的 DataPrime 源名称
REST 架构

构建完整的扇出/合并/渲染流程。需要理解的关键模式:

  • 文本输出使用 render::render_table——传入列标题(不含「Profile」)和行,行的首个元素为配置文件名称。该辅助函数会根据 include_profile 有条件地包含 Profile 列。无需重复定义结构体。
  • JSON 输出使用 render::render_json——以美化格式打印 &[Value] 数组
  • let include_profile = targets.len() > 1;——这个布尔值统一控制所有多配置文件行为(文本中的 Profile 列、JSON 中的 "profile" 键)
  • 扇出错误不是致命错误——将错误打印到标准错误并继续,因为一个配置错误的配置文件不应阻止其他配置文件返回结果
  • 状态消息输出到标准错误(eprintln!)——标准输出保留给数据,避免管道输出受到污染
  • Agents 输出由命令负责——每个命令在任何后处理之后直接调用 toon_encode,因为不同命令在编码前可能以不同方式转换数据

在 src/commands/mod.rs 中注册该模块。

步骤 4:接入 CLI

在 src/main.rs 中添加三项内容。模板请参阅 docs/adding-a-command.md §「CLI Wiring」。

  1. Commands 枚举变体——DataPrime 命令使用内联参数;REST 命令引用子命令枚举
  2. 子命令枚举(仅 REST)——定义 List、Get 等
  3. 分发匹配分支——放在 match cli.command 代码块中。大多数命令会经过完整的配置解析流程;只有不需要凭据的命令(如 profiles、cleanup)才会提前退出

第 5 步:添加测试

每个新命令都必须在三个层级添加测试。代码模板和各层示例请参阅 docs/adding-a-command.md § "Testing"。

层级位置验证内容
单元测试src/**/<file>.rs #[cfg(test)]纯逻辑——反序列化(REST 必须测试)、辅助函数、转换
集成测试tests/<command>/main.rs (wiremock)使用模拟 HTTP 端到端运行命令
端到端测试tests/e2e/<command>/mod.rs (assert_cmd, #[ignore]d)使用真实 cx 二进制对 Coralogix 测试团队进行测试

文档中没有特别强调的、与此工作流有关的事项:

  • 不要为会修改状态的命令添加端到端测试(创建/删除/启用/禁用),除非有配套的撤销计划——这些命令会影响共享的测试团队状态。应添加注释说明有意不覆盖此类测试,例如 tests/e2e/alerts/mod.rs。
  • 如果子命令需要测试团队中的 ID(例如 get <id>),请在端到端测试模块中添加本地 discover_* 函数,参照 tests/e2e/alerts/mod.rs 中的 discover_alert_id。使用 OnceLock 缓存;如果测试团队没有数据,则优雅地跳过——不要 panic。
  • 别忘了通过 #[path = "e2e/your_domain/mod.rs"] mod your_domain; 在 tests/e2e.rs 中声明新的端到端测试模块。

第 6 步:创建面向用户的技能

每个命令都需要在 skills/ 中有一个对应的技能,让 AI Agent 知道如何使用该命令。使用 add-skill 工作流创建技能——该工作流会引导你完成整个流程,包括阅读参考实现、编写有效的触发描述以及验证。

第 7 步:验证

运行 cargo build、cargo test(单元测试和集成测试)、cargo clippy 以及 cargo fmt --check。提交前修复所有问题。

如果已配置测试团队凭据,也请运行端到端测试套件:

cargo test --test e2e -- --ignored --test-threads=1

对所有三种输出格式(text、json、agents)以及多配置文件(-p profile1 -p profile2)进行冒烟测试。

完整的 PR 描述检查清单请参阅 docs/adding-a-command.md § "PR Checklist"。

评论

支持 Markdown