Back to skills
SKILL.md
Daily Report
ASecurity產生 Claude Code 工作日報並經核可後寄 Gmail 給設定檔指定的收件人。掃描本機所有專案的當日 session 記錄,按專案分組摘要「做了什麼+待辦/未完成」,使用者過目核可後透過 Gmail SMTP 寄出。當使用者說「日報」、「產今天的日報」、「工作日報」、「今天做了什麼整理一下寄出去」、「昨天的日報補寄」、「daily report」時觸發。
- 2 stars
- 0 votes
- 0 copies
- 1 view
- Added September 3, 2026
Works with
Security analysis
100/100Pro scans all 11 files and shows the line behind each finding
npx -y skills add abs1294/fulin-claude-plugins --skill daily-report --agent claude-codeAre you the author of Daily Report?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/abs1294-daily-report)---
name: daily-report
description: 產生 Claude Code 工作日報並經核可後寄 Gmail 給設定檔指定的收件人。掃描本機所有專案的當日 session 記錄,按專案分組摘要「做了什麼+待辦/未完成」,使用者過目核可後透過 Gmail SMTP 寄出。當使用者說「日報」、「產今天的日報」、「工作日報」、「今天做了什麼整理一下寄出去」、「昨天的日報補寄」、「daily report」時觸發。
---
# daily-report — 工作日報產生與 Gmail 寄送
把一整天散在各專案的 Claude Code 對話,濃縮成一封收件人(主管/客戶)看得懂的工作日報。
資料來源是本機 `~/.claude/projects/` 的 session jsonl;寄送走 Gmail SMTP(應用程式密碼)。
## 核心原則
1. **寄信是對外動作,預設要人工核可**:報告在寄出前必須完整呈現給使用者。能不能「沒回應就自動寄」只看設定檔的一個開關 `require_approval`:
- `true`(預設;沒寫、寫錯、讀不到設定檔都算這個)→ 每封都要使用者親口說「寄」才寄,沒有默許窗口。剛開始用請維持這樣。
- `false`(使用者覺得運作順利後自己改)→ 才有「確認窗口到期沒人喊停就自動寄」。
這個開關由寄送腳本強制:`require_approval` 不是 `false` 時,帶 `--auto` 的寄送一律被拒,不靠記得。
2. **收件人視角**:日報是給別人看的。寫「完成了什麼、產出是什麼」,不寫內部術語、不寫 prompt 原文、不寫統計數據(統計只在對話裡給使用者自己看)。
3. **機密不落 git**:SMTP 憑證只存 `~/.claude/daily-report/config.json`(家目錄)。
## 執行步驟
### 1. 定日期
預設今天;「昨天的日報」= 昨天;也可指定 `YYYY-MM-DD`。時區預設台北(+08:00)。
### 2. 萃取當日 session
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/extract_sessions.py" --date <YYYY-MM-DD>
```
**預設只掃目前專案**(當前工作目錄及其子目錄的 session),不是全機器。這是刻意的:plugin 多裝在 project scope,「這個專案的日報」才是預期行為,掃全機器會把別的客戶/專案混進同一封信。要跨專案總覽時才加 `--all-projects`;要指定他處用 `--project <路徑>`。
- stdout 唯一輸出=中間檔路徑(`~/.claude/daily-report/out/<date>-<專案>.json`),直接 Read 它。
- exit 3 = 該日無記錄 → 告知使用者,不硬產空報告。
- 腳本已自動濾掉:subagent 對話、SDK/程式驅動 session、系統注入訊息、指令回顯。留下的都是「人打的 prompt」與 session 標題(ai-title)。
- 要連自動化 session 一起看時加 `--include-auto`(罕用)。
### 3. 生成日報
讀中間檔,寫日報 markdown 到 `~/.claude/daily-report/reports/<date>.md`。固定結構:
```markdown
# YYYY-MM-DD 工作日報
## <專案名(口語化,非路徑)>
- 完成/推進了什麼(1~4 條,說結果不說過程)
## 待辦與未完成
- 從對話中萃取的未收尾事項(沒有就寫「無」)
```
寫作要點:
- **專案名口語化**:`C:\...\winbond-vendor-platform` → 「Winbond 供應商平台」。相鄰子目錄的 session(如 `customer-hub` 與 `customer-hub\web`)併成同一個專案講。
- **從 title + prompts 歸納敘事**,不逐條翻譯 prompt。session 標題(Claude 自動生成)通常就是最好的主題句起點。
- **待辦線索**:對話尾段的「之後再」、「明天」、被中斷的工作、使用者說要做但當天沒做完的事。
- **私人 session 要過濾**:掃出來的 session 可能含私人事務(非工作專案)。判斷明顯私人的(如個人研究、家庭事務)**預設不寫進報告**,並在對話中告知使用者「已略過 N 個疑似私人 session(列標題)」,讓使用者可要求加回。
**表格**:內容本來就是表格的(工時、明細、逐項數據)直接寫 markdown 表格,`md_to_html()` 會轉成帶框線的 HTML `<table>`(1px 灰框、`#f4f4f4` 表頭底、Arial 13px;樣式硬寫不可調)。
```markdown
| Week | Start Date | End Date | Hours | Description |
|:-:|:-:|:-:|:-:|:-:|
| 2 | 07/09/2026 | 13/09/2026 | 9.0 | 供應商平台簽核流程 |
| | | Total hours | 9.0 | |
```
- **對齊列(`|:-:|:-:|`)會被自動丟棄**,不會渲染成資料列。
- **合計列就寫成普通一列**(前幾格留空、寫 `Total hours` 與數字),轉換器不做特殊處理。
- 表格是「敘述放不下才用」的工具——一般日報的專案進度仍用條列,不要為了表格而表格。
### 4. 內容硬閘與易讀性閘(寄送腳本自動跑)
**日報是對外文件,不得出現任何 AI / 工具鏈痕跡**(AI、Claude、plugin、prompt、agent、token、紅藍對抗、自動彙整…),也要讀得懂(編號連續、沒有未定義代號、沒有「本次查核」這類異動紀錄用語)。兩道閘都寫在寄送腳本的共用前置流程裡(`send_common.prepare_send`):
- `content_guard.py`:AI/工具鏈字眼、憑證、個資。**不可豁免(公文式敬稱組除外,見下)**。
- `check-before/scripts/check_doc.js`:易讀性,與 Stop hook 同一套判準。硬缺陷擋寄送,提醒照印。
**Gmail API(A)與 SMTP(B)兩條路徑不用手動跑**——第 5 步呈現前跑的 `--dry-run` 就會經過這兩道閘,沒過就拿不到預覽;實寄時會再跑一次。
**MCP 建草稿(C)也不用手動跑**:這條路徑直接呼叫 Gmail 工具、不經寄送腳本,所以由 PreToolUse hook `hooks/daily-draft-gate.js` 在建立/更新草稿**之前**把關——主旨含「工作日報」的草稿,內文會先跑同樣兩支(`content_guard.py`、`check_doc.js`),任一不過就拒絕建立草稿並附上命中清單。想在建草稿前先看結果,可手動跑:
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/content_guard.py" <報告.md> [--project <目錄>]
node "${CLAUDE_PLUGIN_ROOT}/skills/check-before/scripts/check_doc.js" <報告.md>
```
> **例外:公文式敬稱(易讀性鐵則 14)只提醒、不擋寄送**。「貴司/貴中心/本中心」這類敬稱命中時會印 `⚠ 提醒(不擋寄送)`,exit code 仍為 0——因為中文沒有詞邊界,「貴司機」「成本中心」「本司法」都會誤命中,擋下去會訓練使用者忽略警告。看到提醒請自己判斷:是敬稱就改「您們」,是正常詞就忽略。
命中時照它印的改寫原則重寫——**站在收件人角度寫「做了什麼、產出是什麼」,不寫用什麼工具做的**:
- ✗ 調整 AI 工作流程,讓 AI 遇到問題即時詢問 → ✓ 調整開發流程:遇到需求疑義即時確認,減少返工
- ✗ 新增 daily-report plugin,經紅藍對抗審查 → ✓ 新增工作記錄彙整工具,完成設計審查
若輸出含 **`⚠ 需要對外別名`**(專案名本身含禁用詞,改寫解決不了),問使用者「這個專案對外要怎麼稱呼?」,然後登記:
```
python content_guard.py --set-alias "<原名>" "<對外別名>" [--project <目錄>]
```
登記後永久生效,**同一個專案只會問一次**——別讓使用者每天重答。
### 5. 呈現與核可(先問開關:要人工說「寄」,還是允許默許窗口)
**先查開關,不要自己讀設定檔判斷**(跟第 6 步用 `setup_gate.py` 同一個道理——腳本每次都查同樣的條件):
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/confirm_gate.py" policy [--project <目錄>]
```
- **exit 14(印 `[approval-required]`)** → 走 **5A 需人工核可**。開關是 `true`、沒寫、寫錯、讀不到設定檔,全都落在這裡。
- **exit 0(印 `[auto-allowed]`)** → 走 **5B 允許自動寄**(使用者已把 `require_approval` 改成 `false`)。
開關的位置與意思:`require_approval` 寫在專案 `<專案>/.claude/daily-report.json` 或家目錄 `~/.claude/daily-report/config.json` 的最外層(專案那份優先,兩邊都沒寫=`true`)。手動叫日報、定時觸發都看同一個開關,沒有第二個。
**呈現內容**(5A、5B 都一樣)——四塊,缺一不可:
1. **寄送資訊**:收件人、副本、寄件者、主旨;5B 另加「預計自動寄發時間」。使用者要在知道「這封會寄給誰」的前提下決定,不能只看內文。(這些**不放進郵件內文**——收件人從 header 就看得到,內文重複是冗餘。)
⚠ **每一項都顯示「真正會寄出的值」,不是佔位符或示意**。主旨尤其要注意:直接跑 `send_gmail.py --dry-run`(或 `gmail_oauth.py send --dry-run`)拿它印出的實際主旨,那已經是 `<前綴> <日期> 工作日報` 代換好的完整字串——**不要自己打「(日報前綴)」這種佔位文字給使用者看**。使用者看到的預覽必須等於實際會寄的內容,否則「呈現核可」形同虛設。dry-run 的輸出本身就是最可靠的預覽來源,直接用它。
2. **日報全文**(將寄出的內容,一字不差)。
3. **本機統計**(只顯示不寄出):專案數、session 數、活躍時段、工具呼叫 top 5。
4. **下一步怎麼走**:5A 寫「你說『寄』我才寄出,要改內容或不寄也直接說」;5B 寫「N 分鐘內沒有回覆或修改,我就用這個版本自動寄出」。
#### 5A. 需人工核可(`require_approval` 為 `true`,預設)
呈現完就**停下來等使用者回覆**。這條路**不 arm 自動寄、不排喚醒、不帶 `--auto`**——就算排了,寄送腳本也會以 `approval-required` 拒寄。
| 回應 | 動作 |
|---|---|
| 說「寄」 | 照第 6 步寄出,**不帶 `--auto`** |
| 改內容 | 更新報告 → 重跑 `--dry-run`(兩道閘隨之重跑)→ 重新呈現,繼續等 |
| 不寄 | 不寄,結束 |
想之後改成自動寄,告訴使用者:在專案的 `.claude/daily-report.json`(或家目錄 `config.json`)最外層把 `"require_approval"` 改成 `false`。**這個值只由使用者自己改**,不要主動改、也不要每次都問要不要改。
#### 5B. 允許自動寄(`require_approval` 為 `false`)
呈現後**立刻 arm(同一輪,不可延後)**:
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/confirm_gate.py" arm <date> \
--report <報告.md> --recipients <收件人> [--cc <副本>] [--project <目錄>]
```
窗口分鐘數讀 config 的 `confirm_wait_minutes`(預設 30)。arm 會記下報告內容指紋與到期時間——**之後的自動寄送必須通過 `check` 才放行**,這是機械閘,不是靠記得。
**接著同一輪排喚醒源**(arm 的輸出也會提醒):
- `ScheduleWakeup({ delaySeconds: <分鐘數×60>, reason: "日報確認窗口", prompt: "<重述:回到 daily-report 寄送步驟>" })`
- 無 ScheduleWakeup 時用 `CronCreate({ recurring:false, cron:<現在+N分> })`,記下 job id。(**不要傳 `durable`**——工具契約明寫該參數無效、所有 job 都只活在本 session。)
> ⚠ **不排喚醒 = 空頭承諾**:這一輪結束後控制權交還使用者,沒有計時器就沒有任何東西會觸發寄送。`confirm_gate check` 在逾期超過 1 小時時會回報 warning,那就是「當初漏排」的證據。
**使用者在窗口內回應時**:
| 回應 | 動作 |
|---|---|
| 改內容 | 更新報告 → 重跑 `--dry-run`(兩道閘隨之重跑;MCP 草稿路徑在重建草稿時由 hook 自動重跑)→ **`confirm_gate clear <date>`** → 重新呈現並 arm(窗口重新計時) |
| 喊停 | **`confirm_gate veto <date> --reason "..."`** → `CronDelete <id>` → 不寄 |
| 說「寄」 | 直接寄,**不帶 `--auto`**(這是他的意思表示,不必等窗口) |
**喚醒觸發時**:寄送指令**必須帶 `--auto`**,腳本會強制查 `confirm_gate check`——開關不是 `false`(approval-required)/ not-armed / still-waiting / vetoed / 內容被改過,任一情況都拒寄。
### 6. 交付(先跑閘,由腳本告訴你走哪條)
**不要自己讀 config 判斷,也不要問使用者「你想用哪種」**——跑這行,退出碼就是答案:
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/setup_gate.py" status
```
- **exit 0(印 `SETUP_OK`)** → 輸出會寫明管道,照下面 A/B/C 對應執行。
- **exit 10(印 `SETUP_REQUIRED`)** → 設定未完成,**跳到「首次設定引導」**。此時不得自行猜測管道、不得直接寄送。
之所以用腳本判斷而非讀檔自行推論:判斷條件有四種未完成情境(檔案不存在、JSON 壞、有管道但無收件人、有檔但無管道),逐條記在腦中容易漏,腳本每次都查同樣的四條。
**A. Gmail API(OAuth)**
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/gmail_oauth.py" send --report ~/.claude/daily-report/reports/<date>.md --date <date> --dry-run
```
先 `--dry-run` 給使用者看實際收件人與主旨,明確確認後拿掉 `--dry-run` 實寄。exit 2 含 `invalid_grant` → 授權失效(撤銷/改密碼/測試模式 7 天過期),重跑 `setup` 即可。
**B. SMTP 直寄**
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/send_gmail.py" --report ~/.claude/daily-report/reports/<date>.md --date <date> --dry-run
```
同樣先 dry-run 再實寄。臨時改收件人用 `--to a@x,b@y`(會連 config 的 cc 一併清空,避免自我測試誤寄主管)。
**C. MCP 建草稿**(session 有 `mcp__claude_ai_Gmail__create_draft`;工具未載入先 ToolSearch)
`create_draft`:`to`/`cc` 讀 config、`subject`=`<subject_prefix> <date> 工作日報`、`body`=markdown 原文、`htmlBody`=`send_gmail.py` 的 `md_to_html()` 轉換結果。完成後告知「草稿已在你的 Gmail 草稿匣,過目後自己按送出」——**按送出即人工核可**,本 skill 不代按。
## 定時觸發(`schedule` 區塊,自續鏈)
設定檔的 `schedule` 區塊讓日報定時自動產生,用 **Claude Code 內建的 `CronCreate`**。
**架構是自續鏈,不是循環排程**:寄成功 → 立刻排下一次(一次性 job)→ 到點觸發 → 產稿 → 核可 → 寄出 → 再排下一次。**任何時刻只有一個 job 活著。**
為什麼不用 `recurring: true`:
| | `recurring:true` | 自續鏈 |
|---|---|---|
| 重複排導致爆量 | 靠 Claude 記得先 `CronList` 查重——**自律,會被繞過** | 結構上不可能:只在「寄成功」這單一時點排,一次一個 |
| 7 天自動過期 | 過期就斷,要有人記得重排 | 不受限——該限制只適用 `recurring:true` |
| 斷鏈 | 這次沒觸發,下次還會來 | **一次失敗就終止**(所以需要下面的候補檢查) |
> ⚠ **這是 session 級排程,不是系統排程**。工具契約原文:`Jobs live only in this Claude session — nothing is written to disk, and the job is gone when Claude exits`。**關掉 Claude Code 排程就消失**。要無人值守請另外用系統排程器(Windows 工作排程器 / crontab),那不在本 skill 範圍。
### 一、寄出成功之後,排下一次(鏈就是這樣接起來的)
`schedule.enabled` 為 `true` 時,**寄成功的同一輪**就要接上鏈:
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/schedule_gate.py" next --project <目錄>
```
輸出會給下一次的時間與可直接用的 cron 欄位,照它排:
```
CronCreate({
cron: "<next 輸出的 cron 欄位>",
recurring: false,
prompt: "產生今天的工作日報:依 daily-report skill 的執行步驟,萃取 session、生成日報、跑內容硬閘,然後呈現給我並進確認窗口。"
})
```
三件要注意的:
1. **`recurring: false`**——自續鏈每次只排一個一次性 job。排成 `true` 會同時有循環與自續兩套,重複觸發。
2. **prompt 寫自然語言,不要寫 slash command**——排程送出的 prompt 裡 slash 是純文字、不會被解析(Claude Code 2.1.196 起的行為)。
3. **不要傳 `durable`**——工具契約明寫該參數無效。
`enabled: false` 或無 `schedule` 區塊 → 不排,也**不要主動問要不要排**(沒設就是不要)。
### 二、忘了接鏈或鏈斷過,Stop hook 會講(他律,不靠你記得)
上面那句「寄成功的同一輪就要接上鏈」寫在這裡是**自律**——會被漏掉,而鏈一旦斷了就是靜默地永遠斷著。所以真正的保證在 `hooks/daily-report-chain-gate.js`(Stop hook,講完話就觸發):
| 情況 | hook 的反應 |
|---|---|
| 本回合寄出成功,但沒呼叫 `CronCreate` | **硬擋**(`decision:block`)並告訴你怎麼補——鏈斷在這裡最可惜,當下補排只要一步 |
| 過去有該寄而沒寄的日期 | **只警告**,列出缺口日期;補不補是使用者的選擇,不卡住結束對話 |
| 這輪沒碰 daily-report/`enabled:false`/任何判斷不確定 | 靜默放行 |
兩種提醒的節奏不同(使用者明定),這是刻意分開的:
| | 忘了接鏈 | 過去的缺口 |
|---|---|---|
| 頻率 | **每個日報週期一次**——有新的寄送就會再提醒 | **永久只問一次** |
| 為什麼 | 「這次寄完有沒有接鏈」每次都該問 | 你說過不補的日子,不該在下次寄信後又被翻出來 |
| 怎麼記 | 內部狀態記下上次提醒時的寄送快照 | 寫進設定檔的 `schedule.acknowledged_gaps` |
缺口的結案時機是**提醒的下一輪**——那一輪就代表使用者已經回應過了(不管回補、不補、還是沒理),整批日期寫進設定檔永不再問。「問完的下一則就是記錄點」是機械可偵測的時機,不必靠 Claude 記得去登記(那會被漏掉)。
`acknowledged_gaps` 刻意放**設定檔**而不是內部狀態:使用者看得到,想恢復提醒就自己把日期刪掉。實際補寄的日子不會留在清單裡(補了就有寄送紀錄,本來就不算缺口);超出 `lookback_days` 的舊項目自動裁掉。
還有一條不變的原則:**FAIL-OPEN**——讀檔失敗、解析例外、判斷不確定一律放行。這 hook 影響 session 能不能結束,寧可漏擋絕不卡死。
缺口判定由 `scripts/schedule_gate.py` 提供(`check` 列缺口、`next` 算下次時間)。它**不依賴 cron 有沒有觸發**,只比對 `sent/` 目錄裡事實上哪幾天沒有寄出紀錄,所以四種斷鏈成因都抓得到:使用者 veto、內容閘擋下、cron 到點時 REPL 不是 idle、Claude Code 被關掉。回溯天數讀 `schedule.lookback_days`(預設 30)。
### 三、觸發之後做什麼——跟手動叫日報完全一樣
定時觸發只是「誰按下開始」不同,之後照執行步驟 1~6 走,**寄不寄由第 5 步的同一個開關 `require_approval` 決定**(`confirm_gate.py policy` 查),這裡沒有另一套規則:
- 開關需人工核可(預設)→ 走 5A:呈現完停下來等使用者說「寄」。使用者當天沒回,這天就不寄,之後由下面的缺口檢查提醒。
- 開關允許自動寄 → 走 5B:呈現、arm、排喚醒,窗口到期沒人喊停就帶 `--auto` 寄出。
`schedule` 區塊裡舊版的 `require_approval` 仍會被讀到(最外層沒寫時),但它跟最外層是**同一個開關**,不是只管排程的第二個開關;新設定請寫在最外層。
> **鏈斷在哪都不會靜默**:`confirm_gate` 管「arm 之後沒寄」,`schedule_gate check` 管「根本沒觸發所以沒 arm」。兩者合起來,才補上 `confirm_gate.py` docstring 裡明文承認的缺口——「模型有沒有真的去排喚醒無法由腳本強制」。
## 首次設定引導(`status` 回 exit 10 時走這裡)
這一節的選項說明與步驟**全部由腳本產生**,你的工作是搬運與陪跑,不是自己組織內容。這麼設計的原因:使用者是在「這個選擇給出多少權限」的資訊下做決定的,而那正是長對話中最容易被壓縮掉的部分——交給腳本輸出,內容就不隨當下狀態浮動。
**步驟 1|取得選項並原文呈現**
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/setup_gate.py" options
```
輸出是 JSON,含 `question` / `header` / 三個 `options`(各有 `label` 與 `description`)。用 **AskUserQuestion** 呈現:`label` 照抄、`description` 照抄。
`description` 內含權限、有效期、設定成本、代價四欄——**這四欄不可摘要、不可省略**。使用者選「應用程式密碼」前必須看見「等同整個信箱完整存取權、永不過期」,否則他不是在做選擇,是在賭。輸出的 `instruction` 欄位也寫著同一件事,照做即可。
**步驟 2|取得該管道的逐步引導**
```
python "${CLAUDE_PLUGIN_ROOT}/skills/daily-report/scripts/setup_gate.py" guide <oauth|app_password|mcp_draft>
```
輸出是編號步驟,每步含 `do`(做什麼)與 `確認`(怎麼知道成功了)。**一次講一步,等使用者回報再講下一步**;他卡住就根據他描述的畫面對照該步的「確認」給提示。指令裡的 `<PLUGIN>` 替換成實際路徑再給他。
過程中的兩條紅線:
- **OAuth 的 client_id / client_secret 可以直接請使用者貼給你**,當參數餵給 `gmail_oauth.py setup`(腳本自己寫進他家目錄)。桌面應用程式(Desktop app)類型的 client_secret **按 Google 設計就不是機密**——它必須隨程式散佈到每台使用者電腦,本來就藏不住,Google 文件明說桌面 app 的 secret 不當機密看待。所以不必遮遮掩掩、不必叫使用者改用別的方式輸入,那只會讓人以為卡關而浪費時間。(**app password 不同**:那是真憑證=整個信箱權限,請使用者自己編輯設定檔那一格,不要貼進對話。)
- **`config.example.json` 是隨 plugin 發布的空範本,永遠不要把真值寫進去**。真設定檔的位置是 `~/.claude/daily-report/config.json`。(真寫進去也會被 git-commit 的憑證閘擋下,但別依賴那道補救。)
⚠ **不要把「使用者說做完了」當成做完了**。實戰教訓:本 skill 的作者自己照這份引導跑,仍漏掉「啟用 Gmail API」那步,直到寄信被 403 才發現——每步的「確認」都靠人眼判斷加口頭回報,中間兩層都會失真。**每個宣稱完成的步驟後跑一次 `gmail_oauth.py doctor`**(見步驟 3),它實際打 API 驗,不接受自我回報。
⚠ **Console 的畫面與網址以 Google 當下回傳的訊息為準,不以引導文字為準。** 引導裡的路徑會隨 Google 改版過時,而 doctor 輸出的錯誤與連結是 Google 即時給的。兩者衝突時信 doctor。
### 依專案分設收件人
同一台機器上不同專案要寄給不同人時(Winbond 的日報不該寄給 AI Platform 的窗口),在**該專案**建 `.claude/daily-report.json`:
```json
{ "recipients": ["主管@example.com"], "cc": ["pm@example.com"], "subject_prefix": "[Winbond 日報]" }
```
解析規則:**專案層只能覆寫「寄給誰」**(`recipients` / `cc` / `subject_prefix` / `from_name`),憑證一律只從家目錄那份讀。這樣一組授權可以服務多個專案,而憑證不會因為放在專案目錄裡被 git 帶走。所有腳本都吃 `--project <路徑>`,省略即用目前工作目錄。
**步驟 3|驗收(用 doctor,不用問使用者)**
OAuth 管道跑 `gmail_oauth.py doctor`——五項全綠才算完成。常見的未通過與處置:
| doctor 輸出 | 意思 | 處置 |
|---|---|---|
| `尚未啟用 Gmail API`(附連結) | 專案沒開 API | 開它給的**那個連結**按啟用(別用文件裡的路徑,Google 給的才是對的) |
| `invalid_grant` | 授權已失效 | 重跑 `setup` |
| `授權範圍不含 gmail.send` | scope 不對 | 重跑 `setup` 重新授權 |
| `收件人未設定` | 缺 recipients | 問使用者收件人並寫進 config |
其他管道(app password / MCP 草稿)跑 `setup_gate.py status`,看到 `SETUP_OK` 才算完成。
驗收通過後回到第 5 步交付。**寄送若仍失敗,先跑 doctor 再猜原因**——它會直接指出是哪一環。
## 界線(誠實告知)
- 日報品質取決於 session 記錄的可讀性;純瀏覽器操作、外部會議等 Claude Code 之外的工作不會出現,提醒使用者可口頭補充後由 Claude 補進報告。
- **排程只到 session 級**:`schedule` 區塊用 Claude Code 內建 CronCreate 走自續鏈(寄成功排下一次,見「定時觸發」章),**關掉 Claude Code 就失效**。斷鏈由 `schedule_gate.py check` 事後偵測(比對實際寄出紀錄),不是即時的。要真正無人值守的每日寄送,仍須另行搭配 Windows 工作排程器或 delaylocal(屆時仍建議人工核可後寄)。
- 寄送對象由設定檔管理;本 skill 不維護聯絡人清單。
Files in this skill
- SKILL.md
- config.example.json
- daily-report.project.example.json
- scripts/check_no_secrets.py
- scripts/confirm_gate.py
- scripts/content_guard.py
- scripts/extract_sessions.py
- scripts/gmail_oauth.py
- scripts/send_common.py
- scripts/send_gmail.py
- scripts/setup_gate.py
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.