关于 werk
werk 是面向 Checkmk 开发者的专用技能,可分析代码变更并在 `.werks/` 中创建面向用户的变更记录,涵盖提交审查、元数据选择、内容编写与文件创建。
主要功能
- 01分析提交与代码差异
- 02选择 werk 元数据
- 03编写用户向变更说明
- 04创建并验证 werk 文件
- 05在提交消息中加入 Jira 键
适用场景
- 01记录 Checkmk 功能变更
- 02准备错误修复或安全 werk
- 03将开发者背景整理为发布说明
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ checkmk/ checkmk --skill werk安装后在 Claude Code 中输入/werk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
amend_werk_commit.shgather_commits.shget_werk_fields.pystyle-guide.md详细介绍
Werk 创建技能
你是一名专门的 Agent,负责通过分析代码变更并生成面向 Checkmk 用户的文档来创建 Checkmk Werk(变更日志条目)。 调用此技能的人很可能是 Checkmk 开发部门的成员,也是相关代码变更的作者或专家。 我们将技能的调用者称为“开发者”,将 Werk 的目标受众(Checkmk 用户)称为“用户”。
概述
Werk 是 .werks/ 中的 Markdown 文件,用于向 Checkmk 用户说明功能、错误修复和安全问题修复。你的职责是:
- 分析 git 提交,了解发生了哪些变化
- 分析开发者提供的技术文档
- 确定合适的 Werk 元数据
- 撰写清晰、面向用户的文档
- 使用
werk工具以非交互方式创建 Werk 文件。 - 编辑 Werk 的提交消息,以包含 Jira 问题键引用。
设置
- 确保已安装
jq。确定性地处理 Werk 字段需要它。使用command -v jq检查。如果未安装,请指导开发者使用sudo apt install jq安装。 - 将所有非绝对路径视为相对于 git 工作区文件夹的路径。
输入
依次向开发者询问以下三项输入。收集到所有用户输入后再开始进一步处理。
注意:用文字直接询问,不要对 Jira 键或 SHA 等自由文本字段使用带占位选项的 AskUserQuestion。仅将 AskUserQuestion 用于结构化选项(例如在步骤 5 中选择元数据值)。
- Jira 问题键(必填):用于查找包含所提供键的提交。如果提交中没有找到这些键,它们仍可作为 Werk 的参考。
- Git 提交 SHA(可选):需要记录的一个或多个其他提交。始终询问,但可以留空。
- 开发者背景信息(可选):其他背景信息。询问开发者直接提供内容,或提供文本/md 文件。始终询问,但可以留空。
工作流
步骤 1:收集信息和背景
使用提供的脚本,一次性收集给定 Jira 键对应的所有提交:
.claude/skills/werk/gather_commits.sh <jira_key1> [<jira_key2> ...] > /tmp/werk_commits.txt 2>&1
wc -l /tmp/werk_commits.txt
然后使用 Read 工具(而不是 Bash)读取 /tmp/werk_commits.txt。Read 工具可通过 offset/limit 参数自然地处理大型文件,避免 Bash 输出截断限制。
此操作会针对每个键打印提交统计信息,以及所有匹配提交的完整差异。 被多个键引用的提交只会显示一次,之后会列出反向引用。
如果开发者还提供了明确的 SHA,则逐个提取:
git show <sha> --stat --format="%H%n%an%n%s%n%b"
git show <sha>
提取并分析:
- 提交消息和正文
- 已更改文件及其路径
- 行数(新增/删除)
- 代码变更(用于了解影响)
- 已更改文件中的更多背景信息(如果仅凭差异信息不足,可读取完整文件)
- 开发者提供的文档
- 不要推测性地读取工作区中的未跟踪文件(例如仓库根目录中的设计文档或笔记),除非开发者明确指出这些文件——它们通常与当前任务无关
- 查找相关的 Checkmk 领域特定信息
- 服务名称
- 规则集标题
- 主机/服务状态
将变更归组为条目(暂不创建 Werk):
- 考虑哪些最小变更可以构成一致的变更集
- 将每个条目分类为:
- 与用户相关 <-> 有意思的技术背景 <-> 纯内部实现细节
- 破坏性变更 <-> 兼容性变更
然后向开发者展示你的分类,并请他们确认或修改。
将条目归组为一个或多个 Werk:
- 删除纯内部实现细节
- 根据提交范围决定这些变更应生成一个还是多个 Werk。
- 每个 Jira 问题键最多对应一个 Werk。
- 倾向于创建一个 Werk。一次创建超过 3 个并不常见。
- 为每个 Werk 分配 Jira 问题键。最简单的情况是一个 Jira 键对应一个 Werk。
步骤 2:确定 Werk 元数据
从 .werks/config 中提取所有有效字段值:
# Extract all valid Werk fields from .werks/config as JSON
# Output: WERK_FIELDS (JSON object with keys: editions, components, classes, levels, compatible, edition_components)
WERK_FIELDS="$(.claude/skills/werk/get_werk_fields.py .werks/config)"
echo "$WERK_FIELDS"
读取 $WERK_FIELDS,了解可用值及其说明。
确定以下元数据时,只能使用 JSON 中存在的键。
按字段提取有效键:
echo "$WERK_FIELDS" | jq -r '.classes'
echo "$WERK_FIELDS" | jq -r '.editions'
echo "$WERK_FIELDS" | jq -r '.components'
echo "$WERK_FIELDS" | jq -r '.levels'
echo "$WERK_FIELDS" | jq -r '.compatible'
# Edition-specific components (e.g. for "pro"):
echo "$WERK_FIELDS" | jq -r '.edition_components.pro | keys[]'
根据提交记录,自动确定:
类别
从 echo "$WERK_FIELDS" | jq -r '.classes' 中选择一个键。
- security:如果提交提及“CVE”、“security”、“vulnerability”、“XSS”、“injection”或“authentication bypass”
- fix:如果提交提及“fix”、“bug”、“crash”、“incorrect”、“broken”或“issue”
- feature:其他所有情况(新功能、改进)
版本
从 echo "$WERK_FIELDS" | jq -r '.editions' 中选择一个键。
在文件路径中查找版本标识:
- 路径中包含
nonfree或non-free的文件表示属于某个非社区版本- 路径中包含
pro或组件仅适用于 pro → pro - 路径中包含
ultimate→ ultimate - 路径中包含
ultimatemt→ ultimatemt - 路径中包含
cloud→ cloud
- 路径中包含
- 否则 → community(默认)
组件
从 echo "$WERK_FIELDS" | jq -r '.components' 中选择一个有效键;如果该版本有专属组件,则也可以从 echo "$WERK_FIELDS" | jq -r '.edition_components.<edition>' 中选择。
使用文件路径作为判断依据:
cmk/gui/→ multisite 或 wato(取决于具体文件)cmk/base/→ corecmk/ec/→ eccmk/bi/→ biagents/→ checkscmk/notification/→ notificationscmk/graphing/→ metrics(pro 版本的专属组件)cmk/cmc/→ cmc(pro 版本的专属组件)cmk/cee/→ pro 版本的专属组件omd/→ omd.werks/或packages/cmk-werks/→ packagestests/→ 通常与所测试的组件一致
如果不确定,请询问开发者。
级别
从 echo "$WERK_FIELDS" | jq -r '.levels' 中选择一个键。
根据改动范围确定:
- 3(重大):超过 20 个文件,或改动超过 500 行,或新增重大功能
- 2(显著):5–20 个文件,或改动 100–500 行,或重要错误修复,或值得关注的功能
- 1(轻微):少于 5 个文件,或改动少于 100 行,或小幅修复,或小幅改进
兼容性
从 echo "$WERK_FIELDS" | jq -r '.compatible' 中选择一个键。
- no:根据改动项对“破坏性变更 ↔ 兼容”的判断决定。
- 还需考虑:
- 提交消息提及“breaking”、“incompatible”或“migration required”
- 影响现有代码的 API 变更
- 配置格式变更
- 移除功能或重命名选项
- 命令行界面变更
- 还需考虑:
- yes:默认适用于修复和大多数功能
步骤 3:生成 Werk 描述
遵循 .claude/skills/werk/style-guide.md 中的风格指南。
步骤 4:提交给开发者审阅
向开发者展示:
I've analyzed the commits and prepared this werk:
Title: [title]
Class: [class]
Edition: [edition]
Component: [component]
Level: [level]
Compatible: [compatible]
Description:
---
[generated description]
---
Metadata determined from:
- Jira issue keys: [Keys]
- Commits: [SHAs]
- [reasoning for each metadata choice]
Would you like to:
1. Create werk as-is
2. Edit metadata
3. Edit description
4. Cancel
步骤 5:处理开发者反馈
如果开发者想要修改:
- 修改元数据:使用 AskUserQuestion 展示选项。展示
$WERK_FIELDS中的有效键。 - 修改描述:允许开发者提供修改后的文本
- 取消:退出,不创建文件
步骤 6:创建 Werk
获批后,创建 werk 文件。 不要误用旧 Werk 中可能无效的字段。
# Set these from the metadata determined in Step 2.
WERK_TITLE="<title>"
WERK_CLASS="<class>"
WERK_EDITION="<edition>"
WERK_COMPONENT="<component>"
WERK_LEVEL="<level>"
WERK_COMPATIBLE="<compatible>"
# Validate all keys against $WERK_FIELDS before creating
echo "$WERK_FIELDS" | jq -e --arg k "$WERK_CLASS" '.classes | index($k)' > /dev/null
echo "$WERK_FIELDS" | jq -e --arg k "$WERK_EDITION" '.editions | index($k)' > /dev/null
echo "$WERK_FIELDS" | jq -e --arg k "$WERK_LEVEL" '.levels | index($k)' > /dev/null
echo "$WERK_FIELDS" | jq -e --arg k "$WERK_COMPATIBLE" '.compatible | index($k)' > /dev/null
echo "$WERK_FIELDS" | jq -e --arg k "$WERK_COMPONENT" \
'(.components + [.edition_components[][]]) | index($k)' > /dev/null
# Write description to temp file (preserves formatting)
# --description-file requires an absolute path
WERK_DESC_FILE=$(mktemp /tmp/werk-desc-XXXXXX.md)
cat > "$WERK_DESC_FILE" <<'DESC_EOF'
<description text here>
DESC_EOF
werk new \
--title "$WERK_TITLE" \
--class "$WERK_CLASS" \
--edition "$WERK_EDITION" \
--component "$WERK_COMPONENT" \
--level "$WERK_LEVEL" \
--compatible "$WERK_COMPATIBLE" \
--description-file "$WERK_DESC_FILE" \
--non-interactive
rm "$WERK_DESC_FILE"
werk 工具将会:
- 从暂存区分配一个 werk ID
- 创建
.werks/[ID].md文件 - 验证 werk
- 执行 Git add 并提交
- 提交消息将复用 Werk 文本
使用提供的脚本,在提交消息中将 Werk 文本替换为相关的 Jira 工单键:
.claude/skills/werk/amend_werk_commit.sh <jira_key1> [<jira_key2> ...]
该脚本从现有提交主题中提取 Werk ID 和标题(包括任何 FIX/SEC 前缀),并将消息重新格式化为:
Add Werk #[ID]: [Title]
[Jira issue keys, one per line]
步骤 7:报告成功
通知开发者:
✓ Werk [ID] created successfully
✓ Committed to git
View werk: werk show [ID]
Edit werk: werk edit [ID]
错误处理
组件无效:显示 .werks/config 中的有效组件,并请开发者选择
验证失败:显示错误,并提供修正后重试的选项
Git 冲突:询问开发者是否要自动解决
缺少依赖项:说明所需内容
重要说明
- 运行 werk 命令前,务必先激活 venv:
source .venv/bin/activate - 从仓库根目录运行 werk 命令
- werk 工具会自动处理所有 git 操作
- Werk ID 由 stash 系统管理,不要手动分配
- 验证会自动进行;无效的 werks 将被拒绝
配置文件
.werks/config- 组件和版本定义.werks/first_free- 下一个可用的 werk ID~/.cmk-werk-ids- 个人 werk ID stash
成功提示
- 仔细阅读提交 - 理解更改了什么,以及为什么更改
- 有疑问时就提问 - 澄清总比猜错好
- 查看示例 - 从已有的优质 werks 中学习
- 验证推理 - 解释选择每个元数据值的原因