自动扫描本机 Git 仓库,提取本周(周一到今天)的 commit 记录,按项目分类提炼为标准化周报格式,并通过微信频道推送给用户。支持 Mac / Linux / Windows 全平台,支持作者过滤、容错处理、消息分批发送。
mcp__agent-memory__memory (action: search, query: "项目路径" or "project_path") 检查是否已保存项目根目录> "方便告诉我你公司的项目文件夹在本机哪个位置吗?比如 D:/projects 这样的路径。告诉我一次我就记住了,以后每次生成周报都直接用,不用再问你。如果不提供的话,我也会默认帮你全局搜索,只是指定路径会更快更准。"
mcp__agent-memory__memory (action: update) 将路径写入 FACT.md,格式:```
## 项目信息
```
```
```
mcp__agent-memory__memory (action: append, tags: ["setup", "project_path"]) 记录到日志mcp__agent-memory__memory (action: search, query: "周报模板" or "weekly_report_template") 检查是否已保存周报模板> "你之前写过周报吗?如果方便的话发一份给我,我来学习你的格式和风格,以后生成的周报就会跟你以前写的一模一样。只需要配置一次,我就会记住。如果不提供也没关系,我会用一个通用的标准模板来生成。"
mcp__agent-memory__memory (action: update) 将模板规则写入 FACT.md:```
## 周报模板
```
```
## 周报模板
```
AUTHOR_NAME=$(git config user.name)
AUTHOR_EMAIL=$(git config user.email)
保存到 FACT.md 中,后续过滤使用。
必须兼容 Mac / Linux / Windows 三个平台,使用平台检测分支。注意周日边界处理:
# 检测操作系统
OS="$(uname -s)"
DOW=$(date +%u) # 1=Monday, 7=Sunday
case "$OS" in
Darwin*)
# Mac (BSD date)
if [ "$DOW" = "1" ]; then
MONDAY=$(date +%Y-%m-%d)
elif [ "$DOW" = "7" ]; then
MONDAY=$(date -v-6d +%Y-%m-%d) # 周日:本周一是6天前
else
MONDAY=$(date -v-monday +%Y-%m-%d)
fi
TODAY=$(date +%Y-%m-%d)
TOMORROW=$(date -v+1d +%Y-%m-%d)
;;
Linux*)
# Linux (GNU date)
if [ "$DOW" = "1" ]; then
MONDAY=$(date +%Y-%m-%d)
elif [ "$DOW" = "7" ]; then
MONDAY=$(date -d "6 days ago" +%Y-%m-%d) # 周日:本周一是6天前
else
MONDAY=$(date -d "last monday" +%Y-%m-%d)
fi
TODAY=$(date +%Y-%m-%d)
TOMORROW=$(date -d "tomorrow" +%Y-%m-%d)
;;
MINGW*|MSYS*|CYGWIN*)
# Windows Git Bash (GNU date)
if [ "$DOW" = "1" ]; then
MONDAY=$(date +%Y-%m-%d)
elif [ "$DOW" = "7" ]; then
MONDAY=$(date -d "6 days ago" +%Y-%m-%d)
else
MONDAY=$(date -d "last monday" +%Y-%m-%d)
fi
TODAY=$(date +%Y-%m-%d)
TOMORROW=$(date -d "tomorrow" +%Y-%m-%d)
;;
*)
# 兜底
if [ "$DOW" = "1" ]; then
MONDAY=$(date +%Y-%m-%d 2>/dev/null)
elif [ "$DOW" = "7" ]; then
MONDAY=$(date -d "6 days ago" +%Y-%m-%d 2>/dev/null || date -v-6d +%Y-%m-%d 2>/dev/null)
else
MONDAY=$(date -d "last monday" +%Y-%m-%d 2>/dev/null || date -v-monday +%Y-%m-%d 2>/dev/null)
fi
TODAY=$(date +%Y-%m-%d 2>/dev/null)
TOMORROW=$(date -d "tomorrow" +%Y-%m-%d 2>/dev/null || date -v+1d +%Y-%m-%d 2>/dev/null)
;;
esac
echo "周报范围: $MONDAY ~ $TODAY"
> 重要:日期范围使用 --since=$MONDAY --until=$TOMORROW,确保精确覆盖"本周一到今天",而不是模糊的"最近7天"。
使用 find 递归搜索,排除无效目录,限制深度:
# 有指定路径时:在指定路径下搜索
find "<项目根目录>" -name ".git" -type d -maxdepth 3 \
-not -path "*/node_modules/*" \
-not -path "*/.Trash/*" \
-not -path "*/Library/*" \
-not -path "*/AppData/*" \
-not -path "*/.npm/*" \
-not -path "*/.cache/*" \
2>/dev/null | while read gitdir; do
dir=$(dirname "$gitdir")
echo "$dir"
done
# 无指定路径时(兜底):在用户主目录下搜索
find ~ -name ".git" -type d -maxdepth 4 \
-not -path "*/node_modules/*" \
-not -path "*/.Trash/*" \
-not -path "*/Library/*" \
-not -path "*/AppData/*" \
-not -path "*/.npm/*" \
-not -path "*/.cache/*" \
-not -path "*/.vscode/*" \
-not -path "*/.git/*" \
2>/dev/null | while read gitdir; do
dir=$(dirname "$gitdir")
echo "$dir"
done
> 注意:-maxdepth 3(指定路径)或 -maxdepth 4(全局兜底)防止在 node_modules 等深层目录中卡死。
使用 git -C 替代 cd,避免目录切换开销和路径问题:
AUTHOR="$AUTHOR_NAME"
SINCE="$MONDAY"
UNTIL="$TOMORROW"
RESULT=""
ERROR_COUNT=0
ERROR_PROJECTS=""
TOTAL_COMMITS=0
for dir in <上面查找到的所有目录>; do
proj=$(basename "$dir")
# 使用 git -C 直接在目标目录执行,无需 cd
commits=$(git -C "$dir" log --since="$SINCE" --until="$UNTIL" --author="$AUTHOR" --format="%ai | %an | %s" 2>/dev/null)
if [ $? -ne 0 ]; then
ERROR_COUNT=$((ERROR_COUNT + 1))
ERROR_PROJECTS="${ERROR_PROJECTS} - ${proj}: git log 执行失败\n"
continue
fi
if [ -n "$commits" ]; then
# 使用 grep -c 计算行数,避免 wc -l 在无换行符时返回 0 的问题
count=$(echo "$commits" | grep -c '')
TOTAL_COMMITS=$((TOTAL_COMMITS + count))
RESULT="${RESULT}===PROJECT:${proj}===\n${commits}\n"
fi
done
容错规则:
continue 继续下一个git -C 替代 cd,更快且避免路径丢失风险grep -c '' 替代 wc -l,避免空字符串计数陷阱--author 过滤(模糊匹配 Name 和 Email),只统计本人提交.),使用 git -C "$dir" log --author="$AUTHOR_EMAIL" 用邮箱精确匹配将获取的 commit 按以下规则处理:
feat: / 新增 / 新功能 → 功能开发fix: / 修复 / bug → Bug 修复refactor: / 重构 / 优化 → 优化改进docs: / 文档 → 文档style: / 样式 / css → 样式调整chore: / 配置 / 构建 → 工程配置init / 初始化 → 项目初始化注意:项目名称直接使用 Git 仓库目录名,不加业务描述括号。例如直接写 shiotp-web-jintan,不写 shiotp-web-jintan(后勤管理系统)。
当前对话版(支持 Markdown 表格):
XX周工作周报(YYYY年MM月DD日 - MM月DD日)
一、本周工作总结
共涉及 N 个项目,M 次提交。
| 项目 | 提交数 | 主要工作 |
|------|--------|---------|
| 项目A | X次 | 采购模块API开发 |
| 项目B | X次 | 图片上传功能优化 |
| 项目C | X次 | 新项目初始化 |
项目A:shiotp-web-jintan
- 新增采购申请管理模块API接口
- 重构数量和金额的计算逻辑,新增格式化方法
- 新增出库单管理模块API,支持申请单列表查询
项目B:HOMEdecor
- 新增收藏功能,优化商品展示逻辑
- 重构上传文件功能,添加图片上传压缩
- 优化涂抹功能,支持原图信息和高清导出
二、其他需反馈的事项(选填)
- (如有需协调/反馈的事项)
微信推送版(纯文本,不使用 Markdown 表格,因为微信聊天框不支持渲染):
XX周工作周报(YYYY年MM月DD日 - MM月DD日)
一、本周工作总结
共涉及 N 个项目,M 次提交:
1. 项目A (X次):采购模块API开发
2. 项目B (X次):图片上传功能优化
3. 项目C (X次):新项目初始化
项目A:shiotp-web-jintan
- 新增采购申请管理模块API接口
- 重构数量和金额的计算逻辑
- 新增出库单管理模块API
项目B:HOMEdecor
- 新增收藏功能
- 重构上传文件功能
- 优化涂抹功能
二、其他需反馈的事项
- (选填)
从 Step 2 保存的记忆中提取模板结构,严格按照用户的历史格式生成。优先遵循:
周报生成后,先询问用户确认,不要直接发送:
> "周报已生成,请查看上方内容。是否需要修改或补充?或者直接回复'发送'推送到微信。"
原因:AI 的归类可能不完全符合员工想向老板表达的意图,增加一次确认能大幅提高准确度。
用户确认后执行发送:
mcp__claw__config (action: status) 检查微信频道是否已连接(connected: true)mcp__claw__notify (message: 微信推送版内容, channel_id: 微信频道ID) 推送微信单条消息建议不超过 2000 字符。如果周报内容超过此限制,按以下策略分批发送:
[第X条/共N条]发送时使用循环逐条调用 mcp__claw__notify,每条之间不设间隔。
只记忆静态配置,不记忆运行时数据:
| 内容 | 是否存入记忆 | 说明 |
|---|---|---|
| ------ | ------------- | ------ |
| 项目根目录路径 | 是 | 静态配置 |
| Git 用户名/邮箱 | 是 | 静态配置 |
| 周报模板规则 | 是 | 静态配置 |
| commit 记录 | 否 | 运行时数据,仅存在于当前会话 |
| 生成的周报内容 | 否 | 运行时数据,仅存在于当前会话 |
| 错误统计 | 否 | 运行时数据 |
> 原因:LLM 的上下文和记忆库有限,几周的 commit 积累会冲垮 Token 限制,且让后续检索变慢。
git -C 替代 cd,性能更好且避免路径丢失find 递归搜索 .git,排除 node_modules 等无效目录grep -c '' 替代 wc -l,避免无换行符时计数为 0共 2 个版本