Back to Better Genshin Impact

Release Note Generator

.agents/skills/release-note-generator.md

0.64.018.4 KB
Original Source

Release Note Generator

基于本地 git 历史和实际代码 diff 生成 BetterGI 发布说明。发布说明的结构、分类和措辞应贴近 GitHub 已发布 Releases 的历史风格;生成具体内容时不依赖网络,所有变更信息从本地仓库获取。

历史 Release 风格

已发布日志的稳定特征:

  • 标题通常为 ## <version> <简短主题>,例如 0.61.0 原神6.60.61.2 优化0.60.1 修复老问题0.59 自动烹饪与BUG修复
  • 大版本或内容较多时,标题下可有一句总览;补丁版本或内容很少时可以直接列 bullet。
  • 分类标题使用产品主功能语义,而不是 Conventional Commits 类型。历史分类可以作为参考,但不是固定枚举;实时任务独立任务新功能等组织性名称不能替代更准确的主功能名称。
  • 版本适配类通常放在最前面,包含新角色识别、新地图、传送点/锚点、七圣召唤元数据等。
  • 其他 分类保留,用于 UI、通知、配置、稳定性、OCR、启动器、仓库、文档等无法归入核心模块的内容。
  • 条目语言偏简洁直白,可以用“新增/修复/优化/支持/更新/回滚/适配”,不需要营销化。
  • PR 号与作者使用纯文本,例如 (#3132) @haokaiyang;多个 PR 可以写在同一括号组里,例如 (#3101 #3108)
  • 不输出 GitHub 自动生成的 ContributorsAssets、reaction 等区块。

版本边界

禁止执行或参考 git taggit describe --tags。版本边界和输出版本号都不能使用 tag 作为依据。

从 HEAD 向后遍历提交历史,匹配明确以版本号发布为主题的提交

  • 提交消息必须匹配以下模式之一(大小写不敏感):
    • Update version to X.Y.Z
    • bump version to X.Y.Z
    • release X.Y.Z
    • vX.Y.Z
  • 版本号正则:\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?
  • 版本号必须是提交消息的核心主题,不能只是顺带提及(如 "fix: update package version to 1.0.19" 这种子包更新不算)
  • 排除包含 alpha 的提交
  • 排除仅更新子包/依赖版本的提交

通用规则

  • 统计区间:(boundary_commit, HEAD],边界提交本身不计入
  • 如果 HEAD 附近已经存在当前目标版本的正式版本提交,不要把它作为边界;继续向父提交方向寻找上一个正式版本提交
  • 若未找到边界版本,明确说明并使用兜底范围

信息采集

提交列表

  • 使用 git -c i18n.logOutputEncoding=utf8 -c core.quotepath=false log 获取提交序列
  • 普通提交使用 --no-merges,合并提交使用 --merges 单独获取;两组提交均限制在完全相同的统计区间内
  • 格式:--pretty=format:"%H%x00%h%x00%P%x00%an%x00%ae%x00%s%x00%b%x1e",字段用 \x00 分隔,commit 用 \x1e 分隔
  • 分别使用 git rev-list --count --no-mergesgit rev-list --count --merges 校验采集数量
  • 读取 commit body,用于提取 Co-authored-by、PR、Issue、其他关联编号和补充说明

Diff 查阅(必须)

  • 对每个普通 commit 必须查阅实际 diff:git diff <sha>^..<sha>
  • 不要把 merge commit 当作普通 commit 再次统计。对 merge commit 使用 git show --cc --stat <sha>git show --cc <sha>,只识别合并时额外产生的冲突解决或手工修改
  • 纯合并且没有额外用户可见改动的 merge commit 不生成日志条目;被合并分支中的普通 commit 仍按各自 diff 检查
  • 不允许仅基于 commit 消息生成说明,必须结合实际代码改动理解变更内容
  • 同一功能的新增 + 后续优化/修复应合并为一条,只记"新增 xxx"

作者信息

  • 所有作者名前统一加 @ 前缀
  • 从 commit 的 author email 解析标识:
  • 从 commit body 的 Co-authored-by: name <email> 提取共同作者,并按同样规则解析
  • 当作者为 huiyadanli(含邮箱 [email protected])时省略 @author(项目维护者,无需标注)
  • 不需要调用 GitHub API,纯本地解析
  • 如果存在下面箭头左侧的作者信息,请替换为右侧的作者名
    • mno -> Bedrockx
    • 秋云 -> physligl
    • darkflamemaster -> 1004452714

内容提炼规则

强制处理顺序

必须先完成全部分析,再开始写 Release Note。禁止一边遍历 commit 一边直接生成条目,否则会把同一功能的后续提交拆成多条。

  1. 查阅统计区间内所有 commit 的实际 diff,不生成最终文案
  2. 将 commit 按用户可感知的功能对象归并为功能簇
  3. 对每个功能簇还原 HEAD 时的最终状态,删除已被后续提交取代、回滚或修复的中间状态
  4. 以整个功能簇为单位确定唯一分类
  5. 最后才生成标题、总览和条目

commit 数量、PR 数量和作者数量都不等于日志条目数量。一个功能簇可以包含多个 commit、多个 PR 和多个作者。

合并策略

  • 后续 commit 若是在补全、修复、优化或重构本周期内刚新增的功能,必须并入该新增功能,只描述 HEAD 时的最终能力
  • 即使 PR 号、作者、提交日期或 commit 前缀不同,只要服务于同一个用户工作流、配置项、API、窗口或任务,就应合并
  • 同一 issue/PR 的多个 commit 必须合并;不同 issue/PR 只要属于同一功能演进,也必须合并
  • 多个 commit 修改相同核心类型、配置、入口或调用链,并且用户无法把它们视为独立功能时,必须合并
  • 后续提交推翻或替代前一提交的实现时,不单列旧行为;条目使用最终行为,并合并保留相关编号与作者
  • 为新功能提供输入、通信、错误提示、配置界面、兼容修复和稳定性修复的配套提交,归入该新功能,不拆成“支持”“错误提示”“协议升级”等独立条目
  • 只有两项改动能够独立使用、独立描述且删除其中一项不影响另一项成立时,才允许拆成两条
  • 可省略纯内部重构、CI、调试日志清理、无用户影响的格式化,但这些 commit 仍必须被检查并纳入内部覆盖记录

合并校准示例:

同一周期内的提交正确处理
新增桌面分身、增加 RawInput、补充 RDP 错误提示、增加组合键切换、升级通信协议合并为一条“新增桌面分身”,描述最终支持的能力
新增战技赶路、修复体力判断、优化下车角度、修复按键残留合并为一条“新增角色战技赶路”,不要再列三条修复或优化
指标栏快捷键先绑定日志快捷键,后改为独立快捷键只描述最终的独立快捷键,并合并相关提交
重构截图与识别区域,后续修复裁剪区域导致的点击偏移合并为一条识别基础设施改进,不跨分类拆成两条
页面布局统一、随后补充导航选中动画和 Footer 菜单兼容合并为一条界面体验优化

分类

分类不是固定枚举,也不由目录表机械决定。先完成 commit 合并,再由 AI 根据实际 diff 判断每个功能簇所属的产品主功能。历史 Release 中出现过的分类只是命名参考,不是白名单。

分类粒度

  • 分类应对应用户能够识别的产品主功能,通常具有独立入口、独立开关、独立配置根节点、独立任务生命周期或完整工作流
  • 子能力、算法、处理器、配置项和实现步骤归入其上级主功能,不单独提升为分类
  • 地图追踪是主功能;战技赶路、路径执行、地图传送、下车判定和传送识别都是其下的条目,不能分别建立分类
  • 自动战斗是主功能;战斗策略、角色识别、技能释放、战后拾取等紧密服务于战斗流程的内容归入其中
  • 遮罩窗口是主功能;准星、指标栏、日志框和窗口行为归入其中
  • 自动拾取自动吃药自动剧情秘境首领讨伐钓鱼等具有独立入口或独立工作流,应直接使用自身功能名,不能统一塞入实时任务独立任务
  • 单个主功能即使只有一条日志,也允许单独建立分类;不要为了减少分类数量而使用大杂烩分类
  • 不要过度细分:若某项改动离开上级功能无法独立使用或无法被用户单独识别,就保留在上级功能分类中

以下名称通常只是组织容器,不应作为默认分类:实时任务独立任务新功能功能优化问题修复。只有用户界面或项目历史确实把它作为独立产品概念时才允许使用。

对所有功能簇统一使用“最近的独立上级主功能”原则:从具体改动向上追溯,选择距离最近、同时具备独立产品入口或完整用户工作流的上级功能作为分类。不要选择更高层的组织容器,也不要停留在更低层的实现或子功能。

具体改动应归入的上级主功能不应使用的分类
战技赶路、传送定位、路径处理器地图追踪战技赶路地图传送独立任务
自动拾取黑名单、拾取触发和拾取识别自动拾取黑名单实时任务
首领路线、首领配置和战前等待首领讨伐路线优化独立任务
遮罩准星、指标栏和日志框遮罩窗口准星指标栏其他
桌面分身的 RawInput、RDP 错误提示和通信协议桌面分身RawInputRDP其他

此表只用于说明层级关系,不是分类白名单。其他功能必须由 AI 按同一原则从代码、界面和调用关系中判断。

AI 判定依据

按以下证据从强到弱确定主功能,允许 AI 创建历史中未出现过但符合项目语义的新分类:

  1. 用户界面中的页面、卡片、设置分组、开关和任务名称
  2. 独立配置对象、任务入口、服务生命周期和用户操作流程
  3. 主要调用方、API 使用者和最终受影响功能
  4. 类型名、命名空间和代码目录
  5. commit 标题和正文
  • 目录只提供线索,不能覆盖功能语义;GameTask/Common、共享 ViewModel、设置页和 .csproj 均不能直接决定分类
  • 直接面向脚本开发者的 genshin.*dispatcher.* 等公共 API 归入JS脚本,即使底层实现位于战斗、地图或通用目录
  • 仅更新资源包或数据包版本时,根据提交说明、包用途和相邻变更判断实际主功能,不按 .csproj 路径归入其他,也不得编造本地无法确认的细节
  • 横跨多个主功能的截图、识别资源、OCR、基础 UI 和捕获接口重构归入其他;明确服务于单一主功能时跟随该主功能
  • 当一个 commit 同时包含两个能够独立使用的主功能改动时,可以拆成两条并分别分类;否则以整个功能簇的主要用户工作流为准

分类完成后反向检查:分类名必须能自然回答“这是哪个主功能的更新?”。若答案只能是一个组织容器或技术层,重新判断。

遮罩相关变更的分类边界

只有变更的核心行为与地图位置或地图标点在遮罩窗口中的展示和交互直接相关时,才归入地图遮罩。通常至少需要一项地图专属证据:

  • 修改 GameTask/MapMaskModel/MaskMapMaskMapPointService 等地图遮罩专属模块
  • diff 中的核心对象是地图坐标、地图数据源、地图标点、标签筛选、点位隐藏、小地图资源点或地图点位交互
  • 修改 MaskWindowMaskWindowViewModel 等共享文件时,同时能从属性、命令、调用链或配套文件确认改动服务于地图标点展示

以下内容即使名称或文件中含有 Mask / “遮罩”,也不能仅因此归入地图遮罩

  • 通用遮罩窗口能力:日志框、指标栏、准星、窗口位置、透明度、DPI、置顶、点击穿透、快捷键、UID 遮盖等,归入遮罩窗口
  • JS 的 HTML 遮罩、HtmlMaskWindowCore/Script/Dependence/HtmlMask*,归入JS脚本
  • OCR、模板匹配、图像识别中的 mask/掩膜,归入其所属业务分类;无明确业务归属时放入其他
  • 自动战斗、独立任务、实时任务内部用于识别或显示的遮罩,归入对应任务分类
  • 只修改 View/MaskWindow*ViewModel/MaskWindow*Core/Config/MaskWindowConfig*、设置页或快捷键配置,不构成地图遮罩的充分证据

冲突时使用以下优先顺序:专属业务模块和调用链 > diff 中的功能对象 > 配置项/命令语义 > 共享文件路径 > 提交标题关键词。证据不足时放入其他,不要猜测为地图遮罩

校准示例:

变更正确分类原因
为遮罩窗口新增准星样式遮罩窗口修改的是通用遮罩窗口显示能力,与地图位置或标点无关
为遮罩指标栏增加独立快捷键遮罩窗口修改的是指标栏和快捷键配置,不能因“遮罩”一词归入地图遮罩
修改 HTML 遮罩资源拦截或 JS 响应JS脚本HTML 遮罩是脚本 API 能力
增加地图遮罩标点的隐藏、筛选或数据源隔离地图遮罩核心对象是地图标点及其数据
为模板匹配增加颜色掩膜所属业务分类或其他这是图像识别掩膜,不是地图遮罩
  • 版本适配类命名:若能从变更或用户要求明确对应原神版本/月之版本,可用 <月之X适配>;否则使用 版本适配
  • 禁止用新功能实时任务独立任务代替能够识别出的上级主功能
  • 历史分类未覆盖时,由 AI 根据独立入口、配置和工作流创建新的主功能分类,分类名必须使用项目中的用户语义,不要使用 feat/fix/refactor
  • 只有无法对应到任何独立主功能的跨模块基础设施和通用改动才放入其他

每条记录格式:

描述内容 (#编号) @author
  • 编号和作者名均使用纯文本,不加超链接
  • 当作者为 huiyadanli 时省略 @author(项目维护者,无需标注)
  • 描述用自然语言,不直接复制 commit 原文
  • 移除 feat:fix: 等 Conventional Commits 前缀
  • 只有 (#3111)Merge pull request #3111 或明确的 /pull/3111 链接可以判定为 PR 号
  • fixes #3111closes #3111resolved #3111 或明确的 /issues/3111 链接按 Issue 关联处理
  • 无法从本地信息判断类型的裸 #3111 只称为“关联编号”,不得擅自标记为 PR
  • 同一个编号在 subject、body 和合并信息中重复出现时只保留一次
  • 多人参与的记录:@id1 @id2
  • 合并多个 PR、Issue 或关联编号时格式为 (#3101 #3108),不要写成多个分散条目

描述质量与长度

  • 每条日志默认只写一句,正文控制在约 25~60 个中文字符;复杂的核心新增功能最多约 90 个中文字符
  • 合并多个 commit 后先概括最终用户效果,不得把每个 commit 的描述用分号拼接成长句
  • 每条只保留最终效果和最多 2 个关键能力;省略实现算法、内部协议、重试次数、完整配置列表和穷举式支持对象
  • 描述必须准确,不缩小也不夸大;只改一个配置项时不能写成整个功能重构
  • 面向用户使用功能、体验和问题现象描述;只有脚本 API 或开发者功能保留必要的技术标识符
  • 纯内部重构、CI、依赖整理和无用户影响的格式化可以省略
  • 总览句控制在约 60 个中文字符内,只概括最重要的 2~4 个变化

输出格式

输出到 .claude/documents/ReleaseNotes-<version>.md(文件名 ASCII)。

输出文件的版本号规则:取边界版本号的次版本号(minor)加 1,补丁版本归零。即 major.(minor+1).0。例如边界为 0.60.1,输出版本号为 0.61.0

若用户明确指定版本号或发布主题,以用户指定为准;否则按上述规则推导。

markdown
## <version> <版本主题>
<一句话版本主题>

### 分类名1
- 变更描述 (#PR号) @author
- 变更描述 @author

### 分类名2
- 变更描述 (#PR号) @author

### 其他
- 变更描述 @author

补丁版本或少量修复可以不分分类,直接输出 bullet;但如果使用分类,仍必须保留 其他 分类。

兜底验证(必须)

初稿不能直接输出。依次执行以下验证;任一项失败都必须退回功能簇合并、分类或文案阶段重写,然后重新验证。

分类验证

  • 出现实时任务独立任务新功能时,逐条检查是否存在更准确的独立上级主功能;存在则判定失败
  • 其他中的条目只要能识别出自动拾取、钓鱼、一条龙、进入游戏等具体主功能,就判定失败并重新分类
  • 其他达到 4 条或超过全部条目的 25% 时,强制逐条重新检查;只有确属跨模块基础设施的内容才能保留
  • 分类名若是子功能、算法、配置项或实现技术,而代码中存在独立上级主功能,判定失败
  • 同一 commit 或功能簇包含两个独立主功能时,必须拆条;不可在一个分类中混写另一个主功能的修复

合并验证

  • 跨分类比较全部条目;相同入口、配置、核心类型或用户工作流出现两次时,判定为未合并
  • 本周期新增功能若同时存在独立的修复、优化、v2、错误提示、输入支持或协议升级条目,判定为未合并
  • 后续提交只是补全新功能时,必须并入新增条目;不得因 PR、作者或提交时间不同而拆分
  • merge commit 的汇总 diff 不得与其中的普通 commit 重复生成条目

精简验证

  • 普通条目超过约 60 个中文字符、核心新增条目超过约 90 个中文字符时,重新压缩
  • 一个条目出现多句、超过 2 个关键能力或明显罗列实现细节时,重新概括
  • 总览句超过约 60 个中文字符或机械罗列所有分类时,重新压缩

最终确认

  • 统计区间内所有 commit 均已检查实际 diff;无用户影响的 commit 可以不输出
  • 每条内容描述 HEAD 时的最终状态,不保留被回滚、替换或修复的中间状态
  • 所有相关编号和作者已合并去重,地图遮罩条目具备地图坐标、标点或数据源等专属证据
  • 其他分类必须存在;全部信息仅从本地 git 获取,不依赖网络