[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M77YYB6CPH6ZAFPY97S7JRJC":3,"skill-same:01M77YYB6CPH6ZAFPY97S7JRJC":49},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":26,"commitSha":27,"skillDirectory":28,"forksCount":29,"repositoryHtmlUrl":30,"repositoryHomepageUrl":31,"ownerHtmlUrl":32,"ownerBlogUrl":6,"ownerDescription":33,"updatedAt":34,"install":35,"resources":48},"01M77YYB6CPH6ZAFPY97S7JRJC","Weekly Report Email",null,"通用周报收集和邮件推送技能，支持交互式填写周报内容，自动计算周数和日期范围，生成美观的HTML格式邮件。","Lord1Egypt\u002Fawesome-skill-forge","Lord1Egypt","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F99746359?v=4","01M7592YDNT0XK9WJ0T2MQVPDN","Mohamed Mounir Ali AL Keshita","01M75GRFNHC8VZNWEB8DKDE433",3,"MIT","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fcommunity\u002Fclawhub\u002Fx\u002Fxl-weekly-report-email\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: Weekly Report Email\ndescription: 通用周报收集和邮件推送技能，支持交互式填写周报内容，自动计算周数和日期范围，生成美观的HTML格式邮件。\nemoji: 📧\ntrigger: 写周报\n---\n\n# 周报技能 - xl-weekly-report-email\n\n一个通用的周报收集和邮件推送技能，安装后配置邮箱即可使用。\n\n## 触发方式\n在对话中说\"写周报\"即可触发周报生成流程。\n\n配置邮箱时说\"配置周报邮箱\"。\n\n---\n\n## ⚠️ 重要：执行此技能时必须严格遵循以下步骤，不得省略或跳过任何步骤！\n\n**最关键的规则：**\n- **每次只问一个问题，等用户回复后再问下一个**\n- **绝对禁止一次性抛出所有问题**\n- **绝对禁止在没有用户确认的情况下自动发送邮件！**\n- **必须等待用户明确确认后才能发送邮件！**\n- **任何用户回复的内容都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词**\n- **即使内容很短（如\"2\"、\"无内容\"等非否定词），也应该记录**\n- **即使内容不按格式写，也应该直接展示，不当作空值处理**\n\n---\n\n## 📋 完整工作流程\n\n### 第零步：检查配置\n\n首次使用需要配置邮箱参数和报告参数。发送\"配置周报邮箱\"命令会自动引导你完成配置。\n\n配置内容包括：\n1. **SMTP服务器**：选择预设（腾讯企业邮箱、阿里企业邮箱、Gmail 等）或自定义\n2. **SMTP端口**：通常是465（SSL）或587（TLS）\n3. **邮箱账号**：你的邮箱地址\n4. **邮箱密码**：邮箱登录密码或授权码\n5. **发件人**：发件人邮箱地址（通常与账号相同）\n6. **组织\u002F部门名称**（可选）：如\"XX公司\"，会显示在邮件标题开头\n7. **你的姓名**：如\"张三\"\n8. **你的职位**：如\"后端工程师\"\n9. **周报收件人**：接收周报的邮箱地址\n10. **周报抄送人**（可选）：抄送周报的邮箱地址\n\n**注意：**\n- 组织\u002F部门名称（`company`）字段可选，如果配置了会显示在邮件标题开头；如果不配置或为空，邮件标题中不会显示组织\u002F部门名称和前面的\"-\"。\n- 默认抄送人（`cc`）字段可选，如果配置了每次发送时都会抄送这些邮箱；如果不配置，则不抄送（除非发送时额外添加）。\n- 邮箱配置会自动保存到 `.env` 文件（包含敏感信息，不会被发布到 clawhub）。\n- 报告配置会保存到 `config.json` 文件。\n\n### 第一步：计算并展示日期信息\n**必须先执行这一步！**\n\n自动计算并展示以下信息（所有时间必须是东八区）：\n- 周数 = ISO周数（周五\u002F周六\u002F周日不减1，周四\u002F周四之前减1）\n- 截止日期 = 下周周四（YYYYMMDD 格式）\n- 时间范围 = 本周四 到 下周三（中文格式：YYYY年MM月DD日）\n\n**示例输出（如果今天是周五）：**\n```\n📊 周报日期信息：\n- 周数：13\n- 截止日期：20260402\n- 时间范围：2026年3月26日 至 2026年4月1日\n```\n\n**⚠️ 警告：在计算并展示日期信息之前，不要询问任何周报内容！**\n\n---\n\n### 第二步：逐项收集周报内容\n\n**⚠️ 关键规则：必须一个一个询问！禁止一次性抛出所有问题！**\n\n每次只问一个问题，等用户回复后再问下一个。绝对不能把所有问题一次性列出来！\n\n#### 第一部分：遗留问题\u002F阻碍因素跟进\n\n**执行顺序：**\n1. 先给描述\n2. 再给格式提示\n3. 最后给示例\n4. 等用户回复\n\n**描述：**\n列出上周遗留问题或当前最大的阻碍因素的跟进情况。\n\n**格式：**\n[问题描述][当前状态]：进展详情\n**重要：** 必须使用方括号 `[]` 包裹问题描述和当前状态，否则没有样式！\n\n**示例：**\n```\n1. [测试环境资源不足][已解决]：已申请新服务器，问题解决，进度已恢复。\n2. [数据接口延迟问题][跟进中]：已联系数据负责人，承诺本周五前修复，目前正在联调。\n```\n\n**状态样式说明：**\n- `已解决` 或 `Done` → 绿色样式 ✓\n- 其他所有状态 → 蓝色样式 →\n\n**⚠️ 格式提示与用户坚持的规则（重要！）：**\n\n**用户输入内容不按格式时的处理流程：**\n\n**情况1：用户第一次输入不按格式（如\"111\"、\"完成开发任务\"等）**\n- AI **只提示一次**：\"建议格式是 [问题描述][当前状态]：进展详情，您确定要这样写吗？\"\n- 如果用户回复\"确定\"、\"是的\"、\"就这么写\"等确认词 → **直接记录用户之前输入的内容**（\"111\"）\n- 如果用户回复\"好的\"、\"明白了\"等 → 重新询问用户第一部分内容\n- 如果用户继续输入新的内容（不是确认词） → **直接记录用户新输入的内容**\n\n**情况2：用户坚持使用不按格式的内容**\n- 任何用户输入的内容，都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词\n- 即使内容很短（如\"111\"、\"222\"），也应该记录\n- 即使内容不按格式写，也应该直接展示，用普通样式展示\n\n**记住：**\n- 格式提示只提示一次，不要重复提示\n- 用户输入任何内容（除了明确的否定词），都要记录\n- 不要问\"您确定要这样写吗？\"多次\n\n**⚠️ 关键规则：**\n- **任何用户回复的内容都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词**\n- **即使内容很短（如\"2\"、\"123\"），也应该记录**\n- **即使内容不按格式写，也应该直接展示，不当作空值处理**\n\n**⚠️ 禁止：** 不要问\"第一部分是什么\"，直接按照\"描述→格式→示例\"的顺序给用户！也不要继续问第二部分，等用户回复第一部分后再问！\n\n---\n\n#### 第二部分：本周具体产出\n\n**执行顺序：**\n1. 先给描述\n2. 再给格式提示\n3. 最后给示例\n4. 等用户回复\n\n**描述：**\n列出本周具体的产出，建议按项目或模块分类。\n\n**格式：**\n[项目 xxx] 子项目名 + 项目状态 (Done\u002FDoing 进度 X%\u002F Delay\u002F Suspend) + 进度详情\u002F阶段成果\u002F阻塞原因\n**重要：** 必须使用方括号 `[]` 包裹项目名，状态必须用圆括号 `()` 包裹，否则没有样式！\n\n**示例：**\n```\n1. [项目 A] 画像标签开发 (Doing 80%)\n   完成了用户活跃度标签的逻辑重构，性能提升 30%。\n   正在与业务方进行数据验收。\n2. [数据治理] 人员数据质量优化 (Done)\n   完成了历史脏数据的清洗工作，并补充了缺失的日志数据。\n3. [项目 B] 人员表开发（Doing 80%\u002FDelay）\n   完成了 xxxx 的开发\n   需求变动导致 delay\n```\n\n**状态样式说明：**\n- `Done` → 绿色样式\n- `Delay` → 橙色样式\n- `Suspend` → 灰色样式\n- `Doing 进度X%` 或其他状态 → 蓝色样式\n- 组合状态（如 `Doing 80%\u002FDelay`）会拆分成多个状态标签，分别显示对应样式\n\n**⚠️ 格式提示与用户坚持的规则（重要！）：**\n\n**用户输入内容不按格式时的处理流程：**\n\n**情况1：用户第一次输入不按格式（如\"222\"、\"完成开发任务\"等）**\n- AI **只提示一次**：\"建议格式是 [项目名] 任务名 (状态)，您确定要这样写吗？\"\n- 如果用户回复\"确定\"、\"是的\"、\"就这么写\"等确认词 → **直接记录用户之前输入的内容**（\"222\"）\n- 如果用户回复\"好的\"、\"明白了\"等 → 重新询问用户第二部分内容\n- 如果用户继续输入新的内容（不是确认词） → **直接记录用户新输入的内容**\n\n**情况2：用户坚持使用不按格式的内容**\n- 任何用户输入的内容，都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词\n- 即使内容很短（如\"222\"、\"123\"），也应该记录\n- 即使内容不按格式写，也应该直接展示，用普通样式展示\n\n**记住：**\n- 格式提示只提示一次，不要重复提示\n- 用户输入任何内容（除了明确的否定词），都要记录\n- 不要问\"您确定要这样写吗？\"多次\n\n**⚠️ 关键规则：**\n- **任何用户回复的内容都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词**\n- **即使内容很短（如\"2\"、\"123\"），也应该记录**\n- **即使内容不按格式写，也应该直接展示，不当作空值处理**\n\n**⚠️ 禁止：** 同上，等用户回复第一部分后再问第二部分！不要问\"第二部分是什么\"，直接按顺序给！\n\n---\n\n#### 第三部分：技术难点\u002F业务卡点\n\n**执行顺序：**\n1. 先给描述\n2. 最后给示例\n3. 等用户回复\n\n**描述：**\n这里重点写本周遇到的技术难点或业务卡点，以及你打算怎么解决。\n\n**示例：**\n```\n1. 问题描述：需求频繁变更，导致开发返工。\n   解决方案：已与产品经理约定，后续需求变更需通过 TAPD 更新 PRD 并邮件周知，重大变更需重新评估工时。\n2. 问题描述：ClickHouse 查询超时。\n   解决方案：通过分析慢查询日志，发现索引未命中，已优化 SQL 语句并增加二级索引。\n```\n\n**⚠️ 禁止：** 同上，等用户回复后再继续！\n\n---\n\n#### 第四部分：下周核心计划\n\n**执行顺序：**\n1. 先给描述\n2. 最后给示例\n3. 等用户回复\n\n**描述：**\n按优先级列出下周的核心产出承诺。\n\n**示例：**\n```\n1. [计划 1]\n2. [计划 2]\n3. [计划 3]\n```\n\n**⚠️ 禁止：** 同上！\n\n---\n\n#### 第五部分：团队协作\u002F流程\u002F架构思考（非必选）\n\n**执行顺序：**\n1. 先给描述\n2. 最后给示例\n3. 等用户回复\n\n**描述：**\n不仅限于自己的代码，着眼于团队协作、流程、架构等宏观问题。这是周报中体现思考深度的部分。\n\n**示例：**\n```\n1. 协作问题：[例如：数据上游经常口头变更字段，导致下游任务失败]。建议建立字段变更通知机制，必须经过审批群周知。\n2. 架构\u002F稳定性问题：[例如：当前实时任务单点故障风险较高]。建议将核心任务迁移至 Flink 集群，并配置拉起机制。\n3. 业务痛点：[例如：业务方普遍反映离线数据产出时间太晚]。建议优化 DAG 调度依赖，将核心任务优先级提高。\n```\n\n**⚠️ 禁止：** 同上！\n\n---\n\n#### 第六部分：自由发挥区（非必选）\n\n**执行顺序：**\n1. 先给描述\n2. 等用户回复\n\n**描述：**\n自由发挥区（心得体会、GET 技能、共鸣句子、个人思考等）\n\n**⚠️ 禁止：** 同上！\n\n---\n\n### 第三步：保存周报内容（临时文件）\n将所有内容写入 `memory\u002Fweekly-report-YYYYMMDD.md` 文件\n\n**注意：** 这是临时文件，发送完邮件后会自动删除，不会保留。\n\n**保存临时文件的方式：**\n```javascript\nconst fs = require('fs');\nconst path = require('path');\n\n\u002F\u002F 生成文件名（用当前日期）\nconst dateStr = new Date().toISOString().slice(0, 10).replace(\u002F-\u002Fg, ''); \u002F\u002F YYYYMMDD\nconst tempFile = path.join(__dirname, 'memory', `weekly-report-${dateStr}.md`);\n\n\u002F\u002F 确保目录存在\nconst memoryDir = path.join(__dirname, 'memory');\nif (!fs.existsSync(memoryDir)) {\n  fs.mkdirSync(memoryDir, { recursive: true });\n}\n\n\u002F\u002F 写入文件\nfs.writeFileSync(tempFile, content);\n```\n\n---\n\n### 第四步：生成 HTML 预览\n\n**⚠️ 必须使用 main.js！禁止自己手写 HTML！**\n\n**正确方式：**\n```bash\ncd \u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fxl-weekly-report-email\nnodejs main.js\n```\n\n**调用方式：**\n- 先导入：`const { generateWeeklyReport } = require('.\u002Fmain.js');`\n- 再生成：`const report = generateWeeklyReport(content);`\n- 预览：把 `report.body` 给用户看\n\n**禁止：**\n- ❌ 自己写 HTML\n- ❌ 直接输出文本\n- ❌ 省略样式\n\n**⚠️ 重要：生成预览后，给用户看HTML内容，然后问用户是否确认发送！绝对不要自动发送！**\n\n---\n\n### 第五步：询问额外抄送人（可跳过）\n\n**⚠️ 在发送邮件前询问！**\n\n**执行顺序：**\n1. 询问用户是否有其他抄送人\n2. 让用户填写抄送邮箱地址（多个用逗号分隔，全角逗号\"，\"或半角逗号\",\"都可以）\n3. 如果用户不填或填写\"无\"，则只使用配置的抄送人（如果配置了）\n\n**示例：**\n```\n这次发送周报，是否需要添加其他抄送人？（可留空，多个邮箱用逗号分隔）\n例如：boss@example.com,leader@example.com\n```\n\n---\n\n### 第六步：发送邮件\n\n**⚠️ 关键规则：必须等待用户明确确认后才能发送邮件！绝对禁止自动发送！**\n\n**执行顺序：**\n1. 生成 HTML 格式预览给用户确认\n2. **明确询问用户：是否确认发送？**\n3. **等待用户明确回复\"确认\"、\"发送\"、\"是\"等确认词**\n4. **只有收到用户明确确认后，才能调用 `main.js` 中的 `generateAndSendReport(content, additionalCc, tempFilePath)` 函数发送邮件**\n5. **如果用户回复\"不\"、\"取消\"、\"修改\"等否定词，则不发送，询问用户需要修改什么**\n6. 邮件信息（收件人、抄送、发件人）处理逻辑：\n   - 配置的抄送人 + 额外填写的抄送人 = 所有抄送人（自动去重）\n   - 如果两者都没有，则不抄送任何人\n7. 邮件发送成功后，自动删除临时文件 `memory\u002Fweekly-report-YYYYMMDD.md`\n\n**⚠️ 严重警告：**\n- **绝对禁止在生成预览后自动发送邮件！**\n- **绝对禁止在没有用户确认的情况下调用发送函数！**\n- **必须明确等待用户的确认回复！**\n- `tempFilePath` 参数是第三步保存的临时文件路径\n- 邮件发送成功后会自动清理，无需手动删除\n- 如果需要手动清理，可以调用 `cleanupTempFile(filePath)` 函数\n\n---\n\n## 📧 邮件规则\n\n- **标题格式**: 从 config.json 读取配置生成（姓名、职位会自动填入）\n- **收件人**: 从 config.json 读取\n- **抄送**: 从 config.json 读取（可选）\n- **时间计算规则**:\n  - 周数 = 当前周数 - 1（使用 ISO 标准周数，通过 Python 的 `isocalendar()` 方法计算）\n  - 截止日期 = 本周周四（如果今天 \u003C= 周四则取本周，如果今天 > 周四则取下周）\n  - 时间范围 = 上周四 到 本周三\n\n---\n\n## 🔧 技术实现\n\n### 核心文件\n- `main.js`: 周报生成和发送主逻辑（日期计算、HTML生成、内容解析）\n- `mailer.js`: 邮件发送模块（基于 nodemailer）\n- `setup.js`: 首次配置引导\n- `config.json`: 用户配置文件\n\n### 依赖\n- nodemailer: 邮件发送\n\n### 发送邮件的正确方式\n\n**方式1：使用 nodemailer（main.js 中已集成）**\n```javascript\nconst { sendWeeklyReport } = require('.\u002Fmailer');\nawait sendWeeklyReport(subject, htmlBody, recipient, cc);\n```\n\n**方式2：使用 imap-smtp-email\u002Fsmtp.js 命令行（标准）**\n```bash\ncd \u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fimap-smtp-email\u002Fscripts\nnodejs smtp.js send --to target@example.com --subject \"标题\" --html-file email.html\n```\n\n### ⚠️ 系统环境限制\n- Node.js 命令是 `nodejs` 不是 `node`\n- nodemailer 依赖在 `\u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fxl-weekly-report-email\u002Fnode_modules`\n\n---\n\n## 📁 配置文件格式\n\n### config.json（报告配置）\n\n报告配置保存在 `config.json` 中：\n\n```json\n{\n  \"report\": {\n    \"company\": \"XX公司\",\n    \"name\": \"张三\",\n    \"position\": \"后端工程师\",\n    \"recipient\": \"manager@example.com\",\n    \"cc\": \"cc@example.com\"\n  }\n}\n```\n\n### .env（邮箱配置）\n\n邮箱配置保存在 `.env` 文件中（首次使用请复制 `.env.example` 为 `.env`）：\n\n```env\n# SMTP 配置（发邮件）\nSMTP_HOST=smtp.qiye.aliyun.com\nSMTP_PORT=465\nSMTP_SECURE=true\nSMTP_USER=your-email@example.com\nSMTP_PASS=your-password\nSMTP_FROM=your-email@example.com\n```\n\n**说明：**\n- `company` 字段可选，如果不配置或为空，邮件标题中不会显示组织\u002F部门名称和前面的\"-\"\n- 如果配置了 `company`，邮件标题格式为：`组织\u002F部门名称 - 职位姓名 - X周周报 - 日期`\n- 如果没配置 `company`，邮件标题格式为：`职位姓名 - X周周报 - 日期`\n- `.env` 文件包含敏感信息，不会被发布到 clawhub（在 .clawignore 中已排除）\n\n---\n\n## 🐛 常见问题\n\n### 忘记配置了怎么办？\n重新发送\"配置周报邮箱\"命令，会重新进入配置流程。\n\n### 邮件发送失败怎么办？\n1. 检查 `.env` 文件是否存在且配置正确\n2. 检查邮箱密码是否正确（某些邮箱需要使用授权码）\n3. 检查SMTP服务器地址和端口是否正确\n4. 检查是否开启了SMTP服务\n5. 查看 detailed 错误信息\n\n### 如何配置邮箱？\n1. 复制 `.env.example` 为 `.env`\n2. 填写你的 SMTP 配置信息\n\n### 支持哪些邮箱？\n支持所有标准SMTP协议的邮箱，包括：\n- 腾讯企业邮箱\n- 阿里企业邮箱\n- 网易企业邮箱\n- Gmail（需要应用专用密码）\n- Outlook\n- 其他支持SMTP的邮箱\n\n---\n\n## 🧪 测试\n\n运行测试脚本：\n```bash\ncd \u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fxl-weekly-report-email\nnodejs test.js\n```\n\n---\n\n**版本历史和变更日志请查看 [CHANGELOG.md](CHANGELOG.md)**","# 周报技能 - xl-weekly-report-email\n\n一个通用的周报收集和邮件推送技能，安装后配置邮箱即可使用。\n\n## 触发方式\n在对话中说\"写周报\"即可触发周报生成流程。\n\n配置邮箱时说\"配置周报邮箱\"。\n\n---\n\n## ⚠️ 重要：执行此技能时必须严格遵循以下步骤，不得省略或跳过任何步骤！\n\n**最关键的规则：**\n- **每次只问一个问题，等用户回复后再问下一个**\n- **绝对禁止一次性抛出所有问题**\n- **绝对禁止在没有用户确认的情况下自动发送邮件！**\n- **必须等待用户明确确认后才能发送邮件！**\n- **任何用户回复的内容都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词**\n- **即使内容很短（如\"2\"、\"无内容\"等非否定词），也应该记录**\n- **即使内容不按格式写，也应该直接展示，不当作空值处理**\n\n---\n\n## 📋 完整工作流程\n\n### 第零步：检查配置\n\n首次使用需要配置邮箱参数和报告参数。发送\"配置周报邮箱\"命令会自动引导你完成配置。\n\n配置内容包括：\n1. **SMTP服务器**：选择预设（腾讯企业邮箱、阿里企业邮箱、Gmail 等）或自定义\n2. **SMTP端口**：通常是465（SSL）或587（TLS）\n3. **邮箱账号**：你的邮箱地址\n4. **邮箱密码**：邮箱登录密码或授权码\n5. **发件人**：发件人邮箱地址（通常与账号相同）\n6. **组织\u002F部门名称**（可选）：如\"XX公司\"，会显示在邮件标题开头\n7. **你的姓名**：如\"张三\"\n8. **你的职位**：如\"后端工程师\"\n9. **周报收件人**：接收周报的邮箱地址\n10. **周报抄送人**（可选）：抄送周报的邮箱地址\n\n**注意：**\n- 组织\u002F部门名称（`company`）字段可选，如果配置了会显示在邮件标题开头；如果不配置或为空，邮件标题中不会显示组织\u002F部门名称和前面的\"-\"。\n- 默认抄送人（`cc`）字段可选，如果配置了每次发送时都会抄送这些邮箱；如果不配置，则不抄送（除非发送时额外添加）。\n- 邮箱配置会自动保存到 `.env` 文件（包含敏感信息，不会被发布到 clawhub）。\n- 报告配置会保存到 `config.json` 文件。\n\n### 第一步：计算并展示日期信息\n**必须先执行这一步！**\n\n自动计算并展示以下信息（所有时间必须是东八区）：\n- 周数 = ISO周数（周五\u002F周六\u002F周日不减1，周四\u002F周四之前减1）\n- 截止日期 = 下周周四（YYYYMMDD 格式）\n- 时间范围 = 本周四 到 下周三（中文格式：YYYY年MM月DD日）\n\n**示例输出（如果今天是周五）：**\n```\n📊 周报日期信息：\n- 周数：13\n- 截止日期：20260402\n- 时间范围：2026年3月26日 至 2026年4月1日\n```\n\n**⚠️ 警告：在计算并展示日期信息之前，不要询问任何周报内容！**\n\n---\n\n### 第二步：逐项收集周报内容\n\n**⚠️ 关键规则：必须一个一个询问！禁止一次性抛出所有问题！**\n\n每次只问一个问题，等用户回复后再问下一个。绝对不能把所有问题一次性列出来！\n\n#### 第一部分：遗留问题\u002F阻碍因素跟进\n\n**执行顺序：**\n1. 先给描述\n2. 再给格式提示\n3. 最后给示例\n4. 等用户回复\n\n**描述：**\n列出上周遗留问题或当前最大的阻碍因素的跟进情况。\n\n**格式：**\n[问题描述][当前状态]：进展详情\n**重要：** 必须使用方括号 `[]` 包裹问题描述和当前状态，否则没有样式！\n\n**示例：**\n```\n1. [测试环境资源不足][已解决]：已申请新服务器，问题解决，进度已恢复。\n2. [数据接口延迟问题][跟进中]：已联系数据负责人，承诺本周五前修复，目前正在联调。\n```\n\n**状态样式说明：**\n- `已解决` 或 `Done` → 绿色样式 ✓\n- 其他所有状态 → 蓝色样式 →\n\n**⚠️ 格式提示与用户坚持的规则（重要！）：**\n\n**用户输入内容不按格式时的处理流程：**\n\n**情况1：用户第一次输入不按格式（如\"111\"、\"完成开发任务\"等）**\n- AI **只提示一次**：\"建议格式是 [问题描述][当前状态]：进展详情，您确定要这样写吗？\"\n- 如果用户回复\"确定\"、\"是的\"、\"就这么写\"等确认词 → **直接记录用户之前输入的内容**（\"111\"）\n- 如果用户回复\"好的\"、\"明白了\"等 → 重新询问用户第一部分内容\n- 如果用户继续输入新的内容（不是确认词） → **直接记录用户新输入的内容**\n\n**情况2：用户坚持使用不按格式的内容**\n- 任何用户输入的内容，都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词\n- 即使内容很短（如\"111\"、\"222\"），也应该记录\n- 即使内容不按格式写，也应该直接展示，用普通样式展示\n\n**记住：**\n- 格式提示只提示一次，不要重复提示\n- 用户输入任何内容（除了明确的否定词），都要记录\n- 不要问\"您确定要这样写吗？\"多次\n\n**⚠️ 关键规则：**\n- **任何用户回复的内容都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词**\n- **即使内容很短（如\"2\"、\"123\"），也应该记录**\n- **即使内容不按格式写，也应该直接展示，不当作空值处理**\n\n**⚠️ 禁止：** 不要问\"第一部分是什么\"，直接按照\"描述→格式→示例\"的顺序给用户！也不要继续问第二部分，等用户回复第一部分后再问！\n\n---\n\n#### 第二部分：本周具体产出\n\n**执行顺序：**\n1. 先给描述\n2. 再给格式提示\n3. 最后给示例\n4. 等用户回复\n\n**描述：**\n列出本周具体的产出，建议按项目或模块分类。\n\n**格式：**\n[项目 xxx] 子项目名 + 项目状态 (Done\u002FDoing 进度 X%\u002F Delay\u002F Suspend) + 进度详情\u002F阶段成果\u002F阻塞原因\n**重要：** 必须使用方括号 `[]` 包裹项目名，状态必须用圆括号 `()` 包裹，否则没有样式！\n\n**示例：**\n```\n1. [项目 A] 画像标签开发 (Doing 80%)\n   完成了用户活跃度标签的逻辑重构，性能提升 30%。\n   正在与业务方进行数据验收。\n2. [数据治理] 人员数据质量优化 (Done)\n   完成了历史脏数据的清洗工作，并补充了缺失的日志数据。\n3. [项目 B] 人员表开发（Doing 80%\u002FDelay）\n   完成了 xxxx 的开发\n   需求变动导致 delay\n```\n\n**状态样式说明：**\n- `Done` → 绿色样式\n- `Delay` → 橙色样式\n- `Suspend` → 灰色样式\n- `Doing 进度X%` 或其他状态 → 蓝色样式\n- 组合状态（如 `Doing 80%\u002FDelay`）会拆分成多个状态标签，分别显示对应样式\n\n**⚠️ 格式提示与用户坚持的规则（重要！）：**\n\n**用户输入内容不按格式时的处理流程：**\n\n**情况1：用户第一次输入不按格式（如\"222\"、\"完成开发任务\"等）**\n- AI **只提示一次**：\"建议格式是 [项目名] 任务名 (状态)，您确定要这样写吗？\"\n- 如果用户回复\"确定\"、\"是的\"、\"就这么写\"等确认词 → **直接记录用户之前输入的内容**（\"222\"）\n- 如果用户回复\"好的\"、\"明白了\"等 → 重新询问用户第二部分内容\n- 如果用户继续输入新的内容（不是确认词） → **直接记录用户新输入的内容**\n\n**情况2：用户坚持使用不按格式的内容**\n- 任何用户输入的内容，都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词\n- 即使内容很短（如\"222\"、\"123\"），也应该记录\n- 即使内容不按格式写，也应该直接展示，用普通样式展示\n\n**记住：**\n- 格式提示只提示一次，不要重复提示\n- 用户输入任何内容（除了明确的否定词），都要记录\n- 不要问\"您确定要这样写吗？\"多次\n\n**⚠️ 关键规则：**\n- **任何用户回复的内容都应该被记录，除非用户明确回复\"无\"、\"空\"、\"不需要\"、\"跳过\"等否定词**\n- **即使内容很短（如\"2\"、\"123\"），也应该记录**\n- **即使内容不按格式写，也应该直接展示，不当作空值处理**\n\n**⚠️ 禁止：** 同上，等用户回复第一部分后再问第二部分！不要问\"第二部分是什么\"，直接按顺序给！\n\n---\n\n#### 第三部分：技术难点\u002F业务卡点\n\n**执行顺序：**\n1. 先给描述\n2. 最后给示例\n3. 等用户回复\n\n**描述：**\n这里重点写本周遇到的技术难点或业务卡点，以及你打算怎么解决。\n\n**示例：**\n```\n1. 问题描述：需求频繁变更，导致开发返工。\n   解决方案：已与产品经理约定，后续需求变更需通过 TAPD 更新 PRD 并邮件周知，重大变更需重新评估工时。\n2. 问题描述：ClickHouse 查询超时。\n   解决方案：通过分析慢查询日志，发现索引未命中，已优化 SQL 语句并增加二级索引。\n```\n\n**⚠️ 禁止：** 同上，等用户回复后再继续！\n\n---\n\n#### 第四部分：下周核心计划\n\n**执行顺序：**\n1. 先给描述\n2. 最后给示例\n3. 等用户回复\n\n**描述：**\n按优先级列出下周的核心产出承诺。\n\n**示例：**\n```\n1. [计划 1]\n2. [计划 2]\n3. [计划 3]\n```\n\n**⚠️ 禁止：** 同上！\n\n---\n\n#### 第五部分：团队协作\u002F流程\u002F架构思考（非必选）\n\n**执行顺序：**\n1. 先给描述\n2. 最后给示例\n3. 等用户回复\n\n**描述：**\n不仅限于自己的代码，着眼于团队协作、流程、架构等宏观问题。这是周报中体现思考深度的部分。\n\n**示例：**\n```\n1. 协作问题：[例如：数据上游经常口头变更字段，导致下游任务失败]。建议建立字段变更通知机制，必须经过审批群周知。\n2. 架构\u002F稳定性问题：[例如：当前实时任务单点故障风险较高]。建议将核心任务迁移至 Flink 集群，并配置拉起机制。\n3. 业务痛点：[例如：业务方普遍反映离线数据产出时间太晚]。建议优化 DAG 调度依赖，将核心任务优先级提高。\n```\n\n**⚠️ 禁止：** 同上！\n\n---\n\n#### 第六部分：自由发挥区（非必选）\n\n**执行顺序：**\n1. 先给描述\n2. 等用户回复\n\n**描述：**\n自由发挥区（心得体会、GET 技能、共鸣句子、个人思考等）\n\n**⚠️ 禁止：** 同上！\n\n---\n\n### 第三步：保存周报内容（临时文件）\n将所有内容写入 `memory\u002Fweekly-report-YYYYMMDD.md` 文件\n\n**注意：** 这是临时文件，发送完邮件后会自动删除，不会保留。\n\n**保存临时文件的方式：**\n```javascript\nconst fs = require('fs');\nconst path = require('path');\n\n\u002F\u002F 生成文件名（用当前日期）\nconst dateStr = new Date().toISOString().slice(0, 10).replace(\u002F-\u002Fg, ''); \u002F\u002F YYYYMMDD\nconst tempFile = path.join(__dirname, 'memory', `weekly-report-${dateStr}.md`);\n\n\u002F\u002F 确保目录存在\nconst memoryDir = path.join(__dirname, 'memory');\nif (!fs.existsSync(memoryDir)) {\n  fs.mkdirSync(memoryDir, { recursive: true });\n}\n\n\u002F\u002F 写入文件\nfs.writeFileSync(tempFile, content);\n```\n\n---\n\n### 第四步：生成 HTML 预览\n\n**⚠️ 必须使用 main.js！禁止自己手写 HTML！**\n\n**正确方式：**\n```bash\ncd \u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fxl-weekly-report-email\nnodejs main.js\n```\n\n**调用方式：**\n- 先导入：`const { generateWeeklyReport } = require('.\u002Fmain.js');`\n- 再生成：`const report = generateWeeklyReport(content);`\n- 预览：把 `report.body` 给用户看\n\n**禁止：**\n- ❌ 自己写 HTML\n- ❌ 直接输出文本\n- ❌ 省略样式\n\n**⚠️ 重要：生成预览后，给用户看HTML内容，然后问用户是否确认发送！绝对不要自动发送！**\n\n---\n\n### 第五步：询问额外抄送人（可跳过）\n\n**⚠️ 在发送邮件前询问！**\n\n**执行顺序：**\n1. 询问用户是否有其他抄送人\n2. 让用户填写抄送邮箱地址（多个用逗号分隔，全角逗号\"，\"或半角逗号\",\"都可以）\n3. 如果用户不填或填写\"无\"，则只使用配置的抄送人（如果配置了）\n\n**示例：**\n```\n这次发送周报，是否需要添加其他抄送人？（可留空，多个邮箱用逗号分隔）\n例如：boss@example.com,leader@example.com\n```\n\n---\n\n### 第六步：发送邮件\n\n**⚠️ 关键规则：必须等待用户明确确认后才能发送邮件！绝对禁止自动发送！**\n\n**执行顺序：**\n1. 生成 HTML 格式预览给用户确认\n2. **明确询问用户：是否确认发送？**\n3. **等待用户明确回复\"确认\"、\"发送\"、\"是\"等确认词**\n4. **只有收到用户明确确认后，才能调用 `main.js` 中的 `generateAndSendReport(content, additionalCc, tempFilePath)` 函数发送邮件**\n5. **如果用户回复\"不\"、\"取消\"、\"修改\"等否定词，则不发送，询问用户需要修改什么**\n6. 邮件信息（收件人、抄送、发件人）处理逻辑：\n   - 配置的抄送人 + 额外填写的抄送人 = 所有抄送人（自动去重）\n   - 如果两者都没有，则不抄送任何人\n7. 邮件发送成功后，自动删除临时文件 `memory\u002Fweekly-report-YYYYMMDD.md`\n\n**⚠️ 严重警告：**\n- **绝对禁止在生成预览后自动发送邮件！**\n- **绝对禁止在没有用户确认的情况下调用发送函数！**\n- **必须明确等待用户的确认回复！**\n- `tempFilePath` 参数是第三步保存的临时文件路径\n- 邮件发送成功后会自动清理，无需手动删除\n- 如果需要手动清理，可以调用 `cleanupTempFile(filePath)` 函数\n\n---\n\n## 📧 邮件规则\n\n- **标题格式**: 从 config.json 读取配置生成（姓名、职位会自动填入）\n- **收件人**: 从 config.json 读取\n- **抄送**: 从 config.json 读取（可选）\n- **时间计算规则**:\n  - 周数 = 当前周数 - 1（使用 ISO 标准周数，通过 Python 的 `isocalendar()` 方法计算）\n  - 截止日期 = 本周周四（如果今天 \u003C= 周四则取本周，如果今天 > 周四则取下周）\n  - 时间范围 = 上周四 到 本周三\n\n---\n\n## 🔧 技术实现\n\n### 核心文件\n- `main.js`: 周报生成和发送主逻辑（日期计算、HTML生成、内容解析）\n- `mailer.js`: 邮件发送模块（基于 nodemailer）\n- `setup.js`: 首次配置引导\n- `config.json`: 用户配置文件\n\n### 依赖\n- nodemailer: 邮件发送\n\n### 发送邮件的正确方式\n\n**方式1：使用 nodemailer（main.js 中已集成）**\n```javascript\nconst { sendWeeklyReport } = require('.\u002Fmailer');\nawait sendWeeklyReport(subject, htmlBody, recipient, cc);\n```\n\n**方式2：使用 imap-smtp-email\u002Fsmtp.js 命令行（标准）**\n```bash\ncd \u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fimap-smtp-email\u002Fscripts\nnodejs smtp.js send --to target@example.com --subject \"标题\" --html-file email.html\n```\n\n### ⚠️ 系统环境限制\n- Node.js 命令是 `nodejs` 不是 `node`\n- nodemailer 依赖在 `\u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fxl-weekly-report-email\u002Fnode_modules`\n\n---\n\n## 📁 配置文件格式\n\n### config.json（报告配置）\n\n报告配置保存在 `config.json` 中：\n\n```json\n{\n  \"report\": {\n    \"company\": \"XX公司\",\n    \"name\": \"张三\",\n    \"position\": \"后端工程师\",\n    \"recipient\": \"manager@example.com\",\n    \"cc\": \"cc@example.com\"\n  }\n}\n```\n\n### .env（邮箱配置）\n\n邮箱配置保存在 `.env` 文件中（首次使用请复制 `.env.example` 为 `.env`）：\n\n```env\n# SMTP 配置（发邮件）\nSMTP_HOST=smtp.qiye.aliyun.com\nSMTP_PORT=465\nSMTP_SECURE=true\nSMTP_USER=your-email@example.com\nSMTP_PASS=your-password\nSMTP_FROM=your-email@example.com\n```\n\n**说明：**\n- `company` 字段可选，如果不配置或为空，邮件标题中不会显示组织\u002F部门名称和前面的\"-\"\n- 如果配置了 `company`，邮件标题格式为：`组织\u002F部门名称 - 职位姓名 - X周周报 - 日期`\n- 如果没配置 `company`，邮件标题格式为：`职位姓名 - X周周报 - 日期`\n- `.env` 文件包含敏感信息，不会被发布到 clawhub（在 .clawignore 中已排除）\n\n---\n\n## 🐛 常见问题\n\n### 忘记配置了怎么办？\n重新发送\"配置周报邮箱\"命令，会重新进入配置流程。\n\n### 邮件发送失败怎么办？\n1. 检查 `.env` 文件是否存在且配置正确\n2. 检查邮箱密码是否正确（某些邮箱需要使用授权码）\n3. 检查SMTP服务器地址和端口是否正确\n4. 检查是否开启了SMTP服务\n5. 查看 detailed 错误信息\n\n### 如何配置邮箱？\n1. 复制 `.env.example` 为 `.env`\n2. 填写你的 SMTP 配置信息\n\n### 支持哪些邮箱？\n支持所有标准SMTP协议的邮箱，包括：\n- 腾讯企业邮箱\n- 阿里企业邮箱\n- 网易企业邮箱\n- Gmail（需要应用专用密码）\n- Outlook\n- 其他支持SMTP的邮箱\n\n---\n\n## 🧪 测试\n\n运行测试脚本：\n```bash\ncd \u002Fhome\u002Fnode\u002F.openclaw\u002Fworkspace\u002Fskills\u002Fxl-weekly-report-email\nnodejs test.js\n```\n\n---\n\n**版本历史和变更日志请查看 [CHANGELOG.md](CHANGELOG.md)**",{"name":5,"emoji":24,"trigger":25,"description":7},"📧","写周报","master","4aa004da461d820f4ea5499e58eb8d196cf99016","community\u002Fclawhub\u002Fx\u002Fxl-weekly-report-email",0,"https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge","https:\u002F\u002Fskill-explorer-rho.vercel.app","https:\u002F\u002Fgithub.com\u002FLord1Egypt","Unbreakable. Unstoppable. Unmatched⚡.\r\n Speaker of machine tongues 🤖  | World-builder of decentralized dreams 🌐 | Defender of the digital realm🛡️.","2026-06-10 08:21:01",{"source":8,"skillName":5,"commands":36,"prompt":46,"zipAvailable":47},[37,40,43],{"tool":38,"command":39},"npx","npx skills add Lord1Egypt\u002Fawesome-skill-forge --skill \"Weekly Report Email\"",{"tool":41,"command":42},"bunx","bunx skills add Lord1Egypt\u002Fawesome-skill-forge --skill \"Weekly Report Email\"",{"tool":44,"command":45},"pnpm","pnpm dlx skills add Lord1Egypt\u002Fawesome-skill-forge --skill \"Weekly Report Email\"","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fcommunity\u002Fclawhub\u002Fx\u002Fxl-weekly-report-email\u002FSKILL.md",true,[],[50,57,64,71,78,85],{"skillNo":51,"name":52,"nameZh":6,"description":53,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":56,"publishedAt":19},"01M785WKJB99G3STR1NF9NRTJW","youtube-content","YouTube transcripts to summaries, threads, blogs.","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fskills\u002Fyoutube-content\u002FSKILL.md",[],[],{"skillNo":58,"name":59,"nameZh":6,"description":60,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":19},"01M785WEFHB0G2S9YA6EPR3H0E","xurl","X\u002FTwitter via xurl CLI: post, search, DM, media, v2 API.","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fskills\u002Fxurl\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M785W98EDN4EFJXJPMQEHCRC","touchdesigner-mcp","Control a running TouchDesigner instance via twozero MCP — create operators, set parameters, wire connections, execute Python, build real-time visuals. 36 native tools.","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fskills\u002Ftouchdesigner-mcp\u002FSKILL.md",[],[],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M785W5S9FP3QBH2V191E025P","test-driven-development","TDD: enforce RED-GREEN-REFACTOR, tests before code.","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fskills\u002Ftest-driven-development\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M785W2AS08NSSH9YATCV6FJB","teams-meeting-pipeline","Operate the Teams meeting summary pipeline via Hermes CLI — summarize meetings, inspect pipeline status, replay jobs, manage Microsoft Graph subscriptions.","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fskills\u002Fteams-meeting-pipeline\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M785VXKW4T34BTP1SCHW1R7F","systematic-debugging","4-phase root cause debugging: understand bugs before fixing.","https:\u002F\u002Fgithub.com\u002FLord1Egypt\u002Fawesome-skill-forge\u002Fblob\u002Fmaster\u002Fskills\u002Fsystematic-debugging\u002FSKILL.md",[],[]]