scan-new-specs

scan-new-specs

熱門

掃描 warpdotdev/warp 和 warp-server 中最近合併但尚未在 warpdotdev/docs 中有對應文件 PR 的 PRODUCT.md 規格。當找到完整的規格時,自動產生完整的文件草稿 PR 並標記工程師。當規格過於簡略無法起草時,直接通知工程師。設計為排程執行的 Oz 背景代理(例如每 2-3 天)。用於設定自動文件觸發或執行手動文件覆蓋掃描。

146星標
1分支
更新於 2026/7/14
SKILL.md
唯讀
名稱
scan-new-specs
描述

掃描 warpdotdev/warp 和 warp-server 中最近合併但尚未在 warpdotdev/docs 中有對應文件 PR 的 PRODUCT.md 規格。當找到完整的規格時,自動產生完整的文件草稿 PR 並標記工程師。當規格過於簡略無法起草時,直接通知工程師。設計為排程執行的 Oz 背景代理(例如每 2-3 天)。用於設定自動文件觸發或執行手動文件覆蓋掃描。

scan-new-specs

掃描 warpdotdev/warpwarp-server 中最近合併但缺少對應文件草稿的產品或技術規格。針對每個缺口:

  • 如果規格完整 — 自動以背景模式執行 write-feature-docs,在 warpdotdev/docs 中產生完整的草稿 PR,然後通知工程師審查
  • 如果規格簡略 — 直接通知工程師,請他們補充規格或手動啟動文件流程

兩種情況都會在 #growth-docs 頻道發布摘要。

設定

執行前,請確認以下數值(或接受預設值):

設定 預設值 說明
LOOKBACK_DAYS 3 向後掃描多少天以尋找合併的規格 PR
SLACK_CHANNEL #growth-docs 用於通知工程師和發布摘要的 Slack 頻道
SLACK_BOT_TOKEN 來自 buzz 環境 用於透過 API 發送訊息的 Slack Bot Token(已在 buzz Oz 環境中可用)

此技能使用 Slack API(chat.postMessage)而非 incoming webhook,以實現真實的使用者標記。buzz Oz 環境已包含所需的 SLACK_BOT_TOKEN,無需額外設定密鑰。

如果未設定 SLACK_BOT_TOKEN,則將所有訊息輸出到標準輸出。

步驟 1:尋找最近合併的規格

從兩個儲存庫中列出自回顧日期以來合併的 PR,然後根據變更的檔案進行過濾。請勿使用 --search "in:files"(GitHub 不支援在 PR 搜尋中依檔案路徑過濾),並使用在 Linux 和 macOS 上皆可移植的日期指令:

# 可移植的日期計算(相容 GNU/Linux 和 BSD/macOS)
SINCE=$(date -d "-${LOOKBACK_DAYS} days" +%Y-%m-%d 2>/dev/null \
        || date -v-${LOOKBACK_DAYS}d +%Y-%m-%d)

# 列出所有最近合併的 PR(不依檔案路徑過濾 — 我們下一步檢查檔案)
gh pr list \
  --repo warpdotdev/warp \
  --state merged \
  --search "merged:>${SINCE}" \
  --json number,title,author,mergedAt,url \
  --limit 100

# 對 warp-server 重複
gh pr list \
  --repo warpdotdev/warp-server \
  --state merged \
  --search "merged:>${SINCE}" \
  --json number,title,author,mergedAt,url \
  --limit 100

對於每個回傳的 PR,檢查它是否確實包含新的 specs/*/PRODUCT.md,方法是檢查變更的檔案(這是正確的過濾步驟):

gh pr view <number> --repo warpdotdev/<repo> --json files -q '.files[].path' \
  | grep -E '^specs/.+/PRODUCT\.md$'

收集以下清單:規格 ID(specs/ 下的目錄名稱)、規格 PR 編號和 URL、PR 作者的 GitHub 使用者名稱、儲存庫(warpwarp-server)以及合併日期。

對於每個 PR 作者的 GitHub 使用者名稱,解析他們的 Slack 身份:

# 從 GitHub 取得工程師的姓名和電子郵件
ENG_NAME=$(gh api users/<github-username> -q '.name // .login')
ENG_EMAIL=$(gh api users/<github-username> -q '.email // empty')

# 透過電子郵件查詢他們的 Slack 使用者 ID(真實標記,不僅是名稱提及)
if [ -n "$ENG_EMAIL" ]; then
  SLACK_USER_ID=$(curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
    "https://slack.com/api/users.lookupByEmail?email=${ENG_EMAIL}" \
    | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['user']['id'] if d.get('ok') else '')")
fi

# 如果查詢成功,使用 <@USER_ID> 進行真實標記;否則回退到 @名稱
if [ -n "$SLACK_USER_ID" ]; then
  ENG_MENTION="<@${SLACK_USER_ID}>"
else
  ENG_MENTION="@${ENG_NAME} _(找不到 Slack ID — 請確認這是正確的人)_"
fi

儲存 ENG_MENTIONENG_NAMEENG_GITHUB 以在 Slack 訊息中使用。

步驟 2:檢查現有的文件覆蓋

對於每個找到的規格,檢查 warpdotdev/docs 中是否有開啟/草稿或合併的 PR 提及該規格 ID。執行兩個獨立的查詢,以避免將已關閉但未合併的 PR 計為覆蓋:

# 檢查開啟或草稿的 PR
gh pr list \
  --repo warpdotdev/docs \
  --state open \
  --search "<spec-id>" \
  --json number,title,state,url \
  --limit 5

# 檢查合併的 PR
gh pr list \
  --repo warpdotdev/docs \
  --state merged \
  --search "<spec-id>" \
  --json number,title,state,url \
  --limit 5

如果任一查詢回傳結果(存在開啟、草稿或合併的 PR),則該規格視為已覆蓋。跳過已覆蓋的規格。

如果兩個查詢都沒有回傳結果,則該規格未覆蓋。已關閉但未合併的 PR 計為覆蓋 — 關閉的 PR 表示工作已放棄,需要重新觸發。

步驟 3:評估規格完整性

對於每個未覆蓋的規格,讀取 specs/<id>/PRODUCT.md 並評估其內容是否足以自動起草:

完整(繼續自動起草)如果滿足所有以下條件:

  • 檔案至少 40 行
  • 包含 ## Behavior 章節(或同等內容),其中有編號的不變量或使用者面向的步驟
  • 描述至少一個具體的使用者操作(不僅是摘要段落)

簡略(改為通知工程師)如果規格是存根 — 僅有摘要章節、少於 40 行、或沒有行為細節。

步驟 4:根據規格完整性採取行動

路徑 A:完整規格 → 自動起草

  1. 背景模式執行 write-feature-docs(詳見 write-feature-docs 技能)— 這會跳過互動式大綱確認,而是將大綱作為檢查清單嵌入 PR 描述中
  2. PR 在 warpdotdev/docs 中開啟,包含草稿和一個需要工程師驗證的檢查清單
  3. 請求工程師(@<github-username>)以及 @rachaelrenk@hongyi-chen 審查
  4. SLACK_CHANNEL 發布以下 Slack 訊息:
📄 *文件草稿已自動產生*

功能:*<spec-id>*(來自 `<repo>`)
規格 PR:<spec-pr-url>
<@USER_ID>(GitHub:<github-username>)

我已開啟一份草稿文件 PR 供審查:<docs-pr-url>
請檢查 PR 中標記為 *[UNVERIFIED]* 和 *[TODO]* 的項目 — 這些是唯一需要您輸入的內容。

路徑 B:簡略規格 → 通知工程師

SLACK_CHANNEL 發布以下 Slack 訊息:

📋 *新規格需要文件 — 細節不足,無法自動起草*

功能:*<spec-id>*(來自 `<repo>`)
規格 PR:<spec-pr-url>
<@USER_ID>(GitHub:<github-username>)

規格中沒有足夠的行為細節讓我自動產生文件。請您:
• 在 `specs/<spec-id>/PRODUCT.md` 中新增更多細節(包含使用者面向步驟的 Behavior 章節),或者
• 在此頻道通知文件團隊,我們將手動起草

如果沒有未覆蓋的規格,則發布:

✅ *文件覆蓋掃描完成* — 所有最近合併的規格都有文件覆蓋。

步驟 5:發布到 Slack

使用 Slack API 發布每則訊息。使用 jq 建構 JSON 負載,以安全處理 $MESSAGE 中的換行、引號和反斜線:

jq -n \
  --arg channel "$SLACK_CHANNEL" \
  --arg text "$MESSAGE" \
  '{channel: $channel, text: $text}' \
| curl -s -X POST https://slack.com/api/chat.postMessage \
    -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
    -H 'Content-type: application/json' \
    -d @-

如果未設定 SLACK_BOT_TOKEN,則將訊息輸出到標準輸出。

步驟 6:列印摘要

始終將執行摘要輸出到標準輸出:

scan-new-specs 執行摘要
  掃描的儲存庫:         warpdotdev/warp, warp-server
  回顧視窗:             <N> 天(自 <date> 起)
  找到的規格:           <N>
  已覆蓋:               <N>
  自動起草:             <N>   (完整規格 → 已開啟草稿 PR)
  已通知(簡略規格):   <N>   (不完整規格 → 已通知工程師)
  Slack 頻道:           <channel>

排程

此技能設計為每 2-3 天執行一次的排程 Oz 背景代理。建議的 Oz 代理設定提示:

"執行 scan-new-specs 以檢查 warpdotdev/warp 和 warp-server 中是否有新合併但尚未在 warpdotdev/docs 中有對應文件 PR 的 PRODUCT.md 規格。對於完整規格,自動產生草稿文件 PR 並標記工程師。對於簡略規格,在 Slack 中通知工程師。將摘要發布到 #growth-docs。使用最近 3 天作為回顧視窗。"

建議排程:每週一、三、五上午 9 點太平洋時間 — 頻率足以快速捕捉規格,但不會造成干擾。

去重注意事項

此技能在執行之間不維護持久狀態。去重完全依賴於 warpdotdev/docs 中是否存在文件 PR — 如果某個規格有開啟或合併的 PR,則不會再次標記。這意味著規格會持續產生提醒,直到有人為其開啟文件 PR(即使是草稿)。

邊緣情況: 如果文件草稿 PR 已開啟但隨後關閉(未合併),則該規格將在下一次執行時被重新標記,因為關閉的 PR 不計為覆蓋。這是故意的 — 關閉的 PR 表示文件工作已放棄,需要重新觸發。

Slack 提及注意事項

此技能使用來自 buzz Oz 環境的 SLACK_BOT_TOKEN 透過 Slack API(chat.postMessage)發送訊息。這支援真實的 <@USER_ID> 提及 — 工程師在檢測到其規格時會收到直接通知。

使用者 ID 是透過查詢工程師的 GitHub 電子郵件與 Slack 的 users.lookupByEmail API 來解析的。如果工程師有私密的 GitHub 電子郵件,查詢將失敗,訊息將回退為純文字名稱,並附帶手動驗證的說明。

相關技能

  • write-feature-docs — 工程師在被提醒後執行以產生文件草稿的技能