commit-weekly-report
Skill1 starsChanged 4 months agoMITView on GitHub
从 GitHub(可选 GitLab)收集团队 commit 数据,生成周报,通过 lark-cli 创建飞书文档并自动转移文档权限。当用户说"生成周报"、"这周大家做了什么"、"commit summary"、"team weekly report" 等类似请求时触发。
- Reads credentials
In this repository8 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- doc-summarySkill
- lark-doc-deliverSkill
- lark-doc-personalSkill
- meeting-action-syncSkill
- okr-writingSkill
- progress-reportSkill
The file
Files
Commit Weekly Report (CC / Codex)
本 Skill 完全基于
lark-cli+python3+ 标准 shell 工具, 可在任何安装了 Claude Code 或 Codex 的环境中使用。 采用 subagent 并行采集 + 主 agent 汇总 架构,避免上下文溢出。
Prerequisites
| 依赖 | 验证命令 |
| lark-cli | lark-cli auth status |
| python3 | ./scripts/python.sh --version |
| ruamel.yaml | ./scripts/python.sh --check(init/append 索引用) |
| GitHub token | gh auth token 或环境变量 GITHUB_TOKEN |
| GitLab token(可选,自建 GitLab) | 环境变量 GITLAB_TOKEN 或 config.yaml |
One-time Setup: Index Doc
第一次跑这个 skill 之前必须建立汇总入口文档——一篇长期存在的 Lark doc,每周报告链接都会追加到它顶部,形成时间倒序索引。
./scripts/python.sh skills/weekly-report/scripts/init_index.py \
--config skills/weekly-report/config.yaml \
--title "团队工程周报" # 可改脚本会自动:
- 用 bot 身份建一篇含
📌 简介 callout的空 doc - 把 owner 转给 config 里
doc_owner_open_ids[0](自动带--yes,绕过 high-risk-write 网关;用户的预授权来自 config 里登记 owner ID 的动作) - 给 bot 重授
full_access,后续每周由 bot 追加(同样自动--yes) - 抓取顶部 callout 的
block_id作为插入锚点(Lark v2 XML 不支持<divider/>,故用 callout 替代) - 把
token/url/anchor_block_id/title写回config.yaml
幂等:如果 lark.index_doc.token 已有值,会拒绝重跑;要重置传 --force。
⚠️
transfer_owner与permission.members.create都是 lark-cli 的 high-risk-write 操作,不带--yes会 exit 10 +confirmation_required。脚本默认带--yes,因为 owner / bot ID 已由用户在 config 中显式登记;如果你不希望脚本自动转移,请勿登记doc_owner_open_ids。
Execution Flow
Step 1: 读取配置
读取 skills/weekly-report/config.yaml,获取:
team.members— 团队成员列表、用户名、extra_emailsgitlab— GitLab 连接信息github— GitHub 仓库列表(可选)lark.permissions— 飞书文档权限配置lark.doc.folder_token— 旧式 Git/PR 团队技术周报的历史归档文件夹;不要指向“每周需求管理”;为空时停止,禁止回退到云盘根目录report— 报告生成选项
Token 优先级:
- 环境变量
GITHUB_TOKEN/GITLAB_TOKEN - config.yaml 中的
github.token/gitlab.token - GitHub 还可用
gh auth token
计算日期范围(since / until):
- "上周" / 未指定 / 周报 → 上一自然 ISO 周(上周一 00:00 ~ 上周日 23:59)(推荐 + 默认)
- "本周" → 本周一 00:00 ~ 今天(部分周)
- "最近 N 天" → N 天前 ~ 今天
触发节奏(已统一):每周一 09:00 由 launchd 自动跑
/weekly-report 上周,覆盖完整 ISO 上周(Mon~Sun)。周一开周会前看,节奏对齐。 历史上曾用过本周含义(rolling 7d),现已废弃;如果手工跑请用上周。
从各成员的 extra_emails 字段构造 --extra-emails 参数:
格式 user1=email1;email2,user2=email3(多邮箱 ; 分隔,多用户 , 分隔)。
从 team.gitlab_to_github 构造 --github-users 参数:
格式 user1=gh1;gh1_alt,user2=gh2(同一成员多个 GitHub login 用 ; 分隔,多成员用 , 分隔)。GitHub login 匹配必须按大小写不敏感处理。
从各成员的 display_name 字段构造 --display-names 参数:
格式 user1=张三,user2=李四(多用户 , 分隔)。不传则报告标题用 GitHub handle。
GitHub 采集口径:
- 周报反映实际工作量,不是只反映 main/default branch
summarize.py必须遍历 GitHub repo 的所有分支,按 SHA 去重后统计- 报告必须区分状态:
- 已合并 PR/MR:可以写为已合并、进入主线
- 进行中 PR/MR:只能写为进行中
- 未归属 PR/MR 的分支 commit:只能写为“分支工作 / 未确认合并”,不得写成已合并或已上线
- 汇总分析和群消息里的“关键进展”必须避免把分支工作写成主线已完成成果;如需提及,写“分支工作推进了 ...,需确认合并/验证状态”
Step 2: 并行采集每位成员的 Commit 数据
使用 Agent 工具为每位成员 spawn 一个 subagent,所有 subagent 并行执行。
每个 subagent 的任务:
- 运行
summarize.py获取该成员的原始数据:
./scripts/python.sh skills/weekly-report/scripts/summarize.py \
--gitlab-url "<gitlab.base_url>" \
--token "<gitlab_token>" \
--users "<该成员 username>" \
--since "<YYYY-MM-DD>" \
--until "<YYYY-MM-DD>" \
--output /tmp/weekly_<username>.md \
--no-header \
--github-repos "<github.repos,逗号分隔>" \
--github-token "<github_token>" \
--github-users "<该成员的 gitlab_to_github 映射>" \
--extra-emails "<该成员的 extra_emails>" \
--display-names "<该成员的 display_name 映射>"- 读取
/tmp/weekly_<username>.md,撰写该成员的精炼分析摘要(300-500 字),包含:- 提交数、代码变更量(+X / -X)
- 活跃项目列表
- 本周重点工作(按项目/模块分组,2-4 条)
- 已合并 / 进行中的 MR 链接
- 一句话概括
- 将精炼摘要写入
/tmp/weekly_summary_<username>.md - 返回摘要内容给主 Agent
Subagent prompt 模板:
你是周报采集 agent,负责收集 <display_name>(@<username>) 的 commit 数据并生成分析摘要。
1. 执行以下命令获取原始数据:
./scripts/python.sh skills/weekly-report/scripts/summarize.py \
--gitlab-url "<gitlab.base_url>" --token "<token>" \
--users "<username>" --since "<since>" --until "<until>" \
--output /tmp/weekly_<username>.md \
[--github-repos "..." --github-token "..." --github-users "..."] \
[--extra-emails "..."] \
[--display-names "<username>=<display_name>"]
2. 读取 /tmp/weekly_<username>.md
**Zero-activity short-circuit**:如果原始数据里该成员的统计是 0 commit + 0 MR/PR(在文件里通常表现为"_该时间段内无提交记录_"或干脆没有该成员 section),subagent 应立即返回**空摘要**(写入 `/tmp/weekly_summary_<username>.md` 为空文件,或干脆不写)并明确告知主 agent "<username> 本周 0 commit,跳过"。主 agent 据此不把该成员写入分析报告的 per-user section,但 team 总览的 "活跃成员 X/Y" 仍按真实活跃数计算。
3. 写一份精炼分析摘要到 /tmp/weekly_summary_<username>.md,格式如下:
### <display_name> (@<username>) — X commits, +X / -X
**本周重点:一句话概括**
1. **工作条目 1**(项目名,N commits, +X/-X)
- 具体描述
- MR: [!123](url) 已合并/进行中
2. **工作条目 2** ...
**MR/PR 汇总:**
- 已合并: [!123](url) 标题, ...
- 进行中: [!456](url) 标题, ...
摘要要求:
- 所有数据必须来自原始输出,禁止编造
- 保留 MR/PR 链接作为关键证据
- 统计数据(commit 数、+/-行数)必须精确
- 具体 commit 链接不用列,原始数据文档里有完整记录
4. 返回摘要内容。Step 3: 获取 OKR 上下文(可选)
如果 okr.enabled 为 true:
使用 lark-cli docs +fetch 或 MCP 工具读取 OKR 文档内容:
lark-cli docs +fetch --url "<okr.doc_url>" --as bot提取当前 OKR 周期的目标(O)和关键结果(KR),作为 Step 4 分析报告的上下文。
Step 4: 汇总分析报告
等所有数据采集完成后,读取各成员的原始数据(或 subagent 返回的摘要)。
基于数据,组装完整周报,写入 /tmp/weekly_analysis.md:
# 团队周报 (MM.DD — MM.DD)
## 本周总览
| 指标 | 数据 |
|---|---|
| 活跃成员 | X 人 |
| 总提交 | X 次 |
| 合并请求 | X 个 |
| 代码变更 | +X / -X 行 |
## 项目维度概览
| 项目 | 提交数 | 代码变更 | 参与人 |
|---|---|---|---|
| ... | ... | ... | ... |
## 个人工作总结
(按提交数降序排列,包含 MR 链接)
## 本周关键进展
1. 3-5 条核心成果,必须标明已合并 / 进行中 / 分支工作
## OKR 进展映射
(仅在 okr.enabled 时生成此节)
| OKR 目标 | 本周相关工作 | 贡献人 |
|---|---|---|
| O1: ... | 具体工作条目,引用 MR 链接 | @username |
| O2: ... | ... | ... |
> 关联说明:基于 commit 内容和 MR 标题,将本周工作映射到 OKR 目标。
> 未能明确关联到 OKR 的工作列在"其他工作"中。
## 待关注事项
- 需推进的 MR、潜在风险等将各成员的原始数据文件合并(完整 commit 链接、MR/PR 详情都在里面):
# 按 config 中 members 顺序逐个列出,不用 glob 以免混入 summary 文件
cat /tmp/weekly_user1.md /tmp/weekly_user2.md /tmp/weekly_user3.md > /tmp/weekly_raw_all.mdStep 5: 创建飞书文档
注意:
lark-cli docs +create的@file路径必须是相对于当前工作目录的相对路径, 不支持绝对路径。需要先将文件 cp 到工作目录,或 cd 到文件所在目录。
docs +create当前为 v2-only;Markdown 必须使用--content与--doc-format markdown。--title会作为最终标题写入。
4a. 创建原始数据文档(如果 report.create_raw_data_doc 为 true):
cp /tmp/weekly_raw_all.md ./weekly_raw_all.md
lark-cli docs +create \
--title "团队周报-原始数据 (MM.DD — MM.DD)" \
--content @weekly_raw_all.md \
--doc-format markdown \
--parent-token "<lark.doc.folder_token>" \
--as bot4b. 创建汇总分析文档(如果 report.create_analysis_doc 为 true):
cp /tmp/weekly_analysis.md ./weekly_analysis.md
lark-cli docs +create \
--title "团队周报-汇总分析 (MM.DD — MM.DD)" \
--content @weekly_analysis.md \
--doc-format markdown \
--parent-token "<lark.doc.folder_token>" \
--as bot从输出 JSON 中提取 document_id(优先 .data.document.document_id,兼容 .data.doc_id / .data.document_id)。
文档 URL 优先读取 .data.document.url,兼容 .data.doc_url / .data.url。
Step 6: 转移文档权限
对每个创建的文档,读取 lark.permissions 配置,依次执行:
5a. 转移所有权(给第一个 doc_owner_open_ids):
lark-cli drive permission.members transfer_owner \
--params '{"token":"<document_id>","type":"docx","stay_put":"<stay_put>","remove_old_owner":"<remove_old_owner>","old_owner_perm":"<old_owner_perm>","need_notification":"false"}' \
--data '{"member_type":"<member_type>","member_id":"<第一个 doc_owner_open_ids>"}' \
--as bot \
--yes5b. 重新授权 Bot:
lark-cli drive permission.members create \
--params '{"token":"<document_id>","type":"docx","need_notification":"false"}' \
--data '{"member_type":"openid","member_id":"<bot_open_id>","perm":"full_access"}' \
--as bot \
--yes5c. 授权其余成员(如有多个 doc_owner_open_ids):
lark-cli drive permission.members create \
--params '{"token":"<document_id>","type":"docx","need_notification":"false"}' \
--data '{"member_type":"<member_type>","member_id":"<open_id>","perm":"full_access"}' \
--as bot \
--yesowner transfer 失败时不要发送群消息,避免投递不可访问的文档。其余成员授权失败时记录错误并在最终结果中报告。
stay_put必须为true。转移后先用drive metas batch_query --user-id-type open_id --as bot确认两个文档的owner_id等于第一个doc_owner_open_ids,再用drive files list --folder-token <lark.doc.folder_token> --page-all --page-size 200 --as bot确认两个document_id仍在该目录;否则停止消息投递。
Step 7: 消息投递
如果 delivery.enabled 为 true,构造富消息并发送给 delivery.targets 中的每个目标。
消息模板(markdown 格式):
**📋 团队周报 (MM.DD — MM.DD)**
---
**本周总览**
活跃 X 人 · X 次提交 · X 个 MR · +X / -X 行
---
**🔑 关键进展**
1. 第一条核心成果
2. 第二条...
3. ...
---
**📊 OKR 进展映射**(仅 okr.enabled 时包含)
**O1 ...**
· KR?: 相关工作描述
**O2 ...**
· KR?: 相关工作描述
---
**⚠️ 待关注**
· 待推进的 MR 和风险项
---
📝 [汇总分析文档](<analysis_doc_url>) · 📊 [原始数据文档](<raw_doc_url>)发送命令:
先将消息内容写入临时文件 weekly_message.md,然后通过 $(cat) 传递:
对 type=user 的目标:
lark-cli im +messages-send --user-id "<id>" --markdown "$(cat weekly_message.md)" --as bot对 type=chat 的目标:
lark-cli im +messages-send --chat-id "<id>" --markdown "$(cat weekly_message.md)" --as bot注意:
im +messages-send的--markdown不支持@file语法,必须用$(cat file)传递内容。 投递失败时记录错误,不中断流程。
Step 7.5: 追加到汇总入口文档
读取 lark.index_doc.token:
- 为空 → 跳过本步(提示用户跑
init_index.py) - 非空 → 用
append_index.py在 doc 顶部 divider 下方插入本周条目
./scripts/python.sh skills/weekly-report/scripts/append_index.py \
--config skills/weekly-report/config.yaml \
--week-label "<W23 2026 或 2026 第 23 周>" \
--date-range "<YYYY-MM-DD ~ YYYY-MM-DD>" \
--raw-url "<raw_doc_url>" \
--analysis-url "<analysis_doc_url>" \
--stats "<Y commits · +A/-B [· 可选简评,例如 大改造周 / 清理周]>"--stats 来自 Step 4 团队总览的提交数 / 代码变更(不含活跃人数——index 入口要 neat,活跃人数在汇总分析 doc 里看就够)。可附一条简评("大改造周" / "清理周" 等),整行不要超过 60 字。
anchor_block_id 为空或脚本检测到 stale 时会自动重新 fetch(查找顶部 callout)+ 回写 config。
索引 doc 的"锚点"是顶部 callout 而非 divider——
init_index.py已说明原因。
Step 8: 输出结果
📊 原始数据文档: <raw_doc_url>
📝 汇总分析文档: <analysis_doc_url>
📌 索引文档: <index_doc_url>(如已配置)
📨 已投递: <target.name>, ...如有权限操作、投递、或索引追加失败,一并报告。
Key Rules
- 必须使用 subagent 并行采集,禁止在主 Agent 中一次性处理所有成员的原始数据
- 禁止手写 Python 脚本 — 使用已有的
summarize.py/init_index.py/append_index.py - 采集阶段不跳过任何团队成员 — subagent 必须为每位成员跑 summarize.py。但 0-commit 成员不写入 per-user 详细 section(team 总览的 "活跃成员: X/Y 人" 已隐含表达非活跃数);summarize.py 在 generate_report 阶段会自动跳过 0-commit 用户
- 严禁编造:汇总报告和消息中的每一条数据、每一个项目名、每一个 MR 链接都必须在原始数据文件中有明确来源。原始数据中没有的内容绝对不能出现在报告里
- 每个文档创建后必须执行权限转移(包括 init_index.py 已内置)
- 所有
lark-cli命令使用--as bot身份执行 - 大文件内容使用
@file传递给 lark-cli,不要通过命令行参数传递 - Subagent 返回的摘要应在 300-500 字,包含关键数据和 MR 链接
- 索引追加是附加步骤,失败不阻断主流程(raw + analysis doc + 投递三件正常完成即视为成功)
- 禁止落云盘根目录:创建前必须确认
lark.doc.folder_token非空;权限转移使用stay_put=true,完成后回读所有者和目标文件夹验证
Troubleshooting
| 问题 | 解决 |
lark-cli: not configured | echo "<secret>" | lark-cli config init --app-id "<id>" --app-secret-stdin --brand feishu |
| 权限转移失败 | 检查飞书应用权限是否包含 drive:drive 和 docs:permission.member:transfer |
| summarize.py 超时 | 缩小日期范围或增加 --timeout 60 |
@file 报错 | 确认文件路径正确且文件存在 |
| 文档创建成功但无法打开 | 检查 doc_owner_open_ids 是否正确 |
| 文档标题显示 "Untitled" | 确认使用当前 docs +create,并显式传入 --title;不要再使用已移除的 --markdown 参数 |
| subagent 返回空数据 | 该成员本周无提交。不要为该成员写 per-user section,team 总览的"活跃成员 X/Y"已经表达;只在分析报告必要时一句话提及"@xxx 未活跃" |
index_doc.token is empty | 先跑 ./scripts/python.sh skills/weekly-report/scripts/init_index.py 建索引文档 |
could not locate anchor (callout) block_id | 索引文档顶部 callout 被删了;恢复一个 callout 在最顶部,或 init_index.py --force 重建 |
transfer_owner / permission.members.create 报 exit 10 / confirmation_required | lark-cli high-risk-write 网关;init/append 脚本默认已带 --yes。手工调用时记得加 --yes |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

