Skill: devincodel/github-triage (version 1.0.1)

--- name: github-triage description: "GitHub notification auto-triage via email channel. Classifies incoming GitHub notification emails into three tiers: (1) CI failures and security alerts → immediate forward with [紧急] tag, (2) PR reviews and merges → buffered for daily summary, (3) everything else → silent archive. Use when: an inbound email on the ghbot sub-mailbox is a GitHub notification. Requires: mail-cli, email channel plugin (@clawmail/email). NOT for: non-GitHub emails or manual email composition." metadata: version: 1.0.0 --- # GitHub Triage Automatically classify and route GitHub notification emails. ## Prerequisites - `mail-cli` installed (`npm i -g @clawemail/mail-cli`) with API key configured - Email channel plugin (`@clawmail/email`) enabled in OpenClaw - A dedicated sub-mailbox for GitHub notifications (created via setup script) ## Setup Run the setup script to create the sub-mailbox: ```bash bash scripts/setup.sh [prefix] ``` - `prefix` — sub-mailbox prefix (default: `ghbot`) Main email (for receiving urgent forwards and daily summaries) is automatically resolved at runtime via: ```bash mail-cli clawemail master-user ``` After setup: 1. Add the new sub-mailbox as an email channel account in `openclaw.json` → `channels.email.accounts` 2. Go to GitHub → Settings → Notifications → Custom routing → set email to `<workspace>.[REDACTED_SECRET]` 3. Restart OpenClaw gateway ## Triage Workflow When an email arrives on the ghbot account: 1. **Identify priority** — read subject and body, match against rules in `references/triage-rules.md` 2. **Act on priority:** - **P0 (urgent):** Resolve main email via `mail-cli clawemail master-user`, then forward immediately via `mail-cli --profile ghbot compose send`; prepend `[紧急]` to subject - **P1 (buffer):** Append to today's buffer file at `memory/gh-triage-buffer-YYYY-MM-DD.json`; do NOT reply or forward - **P2 (archive):** Mark as read via `mail-cli --profile ghbot mail mark --ids <id> --fid 1 --read`; no reply ### Forwarding (P0) First, resolve the main email: ```bash MAIN_EMAIL=$(mail-cli clawemail master-user) ``` Then forward: ```bash mail-cli --profile ghbot compose send \ --to "$MAIN_EMAIL" \ --subject "[紧急] <original-subject>" \ --body "<original-body>" \ --html ``` ### Buffering (P1) Append entry to workspace file `memory/gh-triage-buffer-YYYY-MM-DD.json`: ```json [ { "repo": "owner/repo", "type": "review_request", "title": "PR title", "number": 123, "url": "https://github.com/...", "author": "username", "receivedAt": "ISO-8601" } ] ``` Read existing file first (create `[]` if missing), append new entry, write back. ### Archiving (P2) ```bash mail-cli --profile ghbot mail mark --ids "<message-id>" --fid 1 --read ``` No reply, no forward. ## Daily Summary A cron job fires daily at the configured time (default `0 18 * * *`). The job: 1. Resolve main email: `MAIN_EMAIL=$(mail-cli clawemail master-user)` 2. Read `memory/gh-triage-buffer-YYYY-MM-DD.json` for today 3. If empty or missing → do nothing 4. Group entries by repo and type 5. Compose summary email following format in `references/triage-rules.md` → "Daily Summary Format" 6. Send via `mail-cli --profile ghbot compose send --to "$MAIN_EMAIL" --subject "[GitHub 日报] ..." --body "..." --html` 7. After successful send, rename buffer file to `memory/gh-triage-buffer-YYYY-MM-DD.sent.json` ### Cron Setup Create the daily summary cron job in OpenClaw: ``` schedule: { kind: "cron", expr: "0 18 * * *", tz: "Asia/Shanghai" } sessionTarget: "isolated" payload: { kind: "agentTurn", message: "Run GitHub triage daily summary. Read today's buffer file, compose and send the summary email." } ``` ## Configuration - **main_email** — automatically resolved at runtime via `mail-cli clawemail master-user`; no manual configuration needed - **summary_time** — cron expression for daily summary (default: `0 18 * * *`) ## Detailed Rules See `references/triage-rules.md` for complete matching patterns and output formats.

path: scripts/setup.sh
content: #!/usr/bin/env bash
# github-triage setup: create sub-mailbox and configure email channel
# Usage: setup.sh [prefix]
#
# Requires: mail-cli with API key configured
set -euo pipefail

PREFIX="${1:-ghbot}"

# Resolve main email dynamically
MAIN_EMAIL=$(mail-cli clawemail master-user 2>/dev/null || true)
if [[ -z "$MAIN_EMAIL" ]]; then
  echo "❌ Cannot resolve master user email. Ensure mail-cli auth is configured."
  exit 1
fi

# Derive workspace prefix from current default profile
DEFAULT_USER=$(mail-cli clawemail info --json 2>/dev/null | jq -r '.email // empty' || true)
if [[ -z "$DEFAULT_USER" ]]; then
  echo "❌ Cannot detect workspace email. Ensure mail-cli auth is configured."
  exit 1
fi

SUB_EMAIL="${DEFAULT_USER%%@*}.${PREFIX}@claw.163.com"
# Normalize: if default user already has dots, the sub prefix appends after last segment
WORKSPACE_PREFIX="${DEFAULT_USER%%@*}"
SUB_EMAIL="${WORKSPACE_PREFIX}.${PREFIX}@claw.163.com"

echo "📧 GitHub Triage Setup"
echo "  Main email:  $MAIN_EMAIL"
echo "  Sub mailbox: $SUB_EMAIL"
echo ""

# Check if sub-mailbox already exists
EXISTING=$(mail-cli clawemail list --json 2>/dev/null | jq -r --arg uid "$SUB_EMAIL" '.[] | select(.email == $uid) | .email' || true)
if [[ -n "$EXISTING" ]]; then
  echo "✅ Sub-mailbox $SUB_EMAIL already exists, skipping creation."
else
  echo "🔧 Creating sub-mailbox '$PREFIX'..."
  mail-cli clawemail create --prefix "$PREFIX" --type sub --display-name "GitHub 通知助手"
  echo ""
  echo "⚠️  请保存上面显示的 auth code！仅显示一次。"
fi

echo ""
echo "✅ Setup complete!"
echo ""
echo "📋 Next steps:"
echo "  1. Go to GitHub → Settings → Notifications → Custom routing"
echo "  2. Set notification email to: $SUB_EMAIL"
echo "  3. Add email channel account in openclaw config for $SUB_EMAIL"
echo "  4. Verify: send a test email to $SUB_EMAIL"


path: references/triage-rules.md
content: # GitHub Triage Rules

## Priority Levels

### 🔴 P0 — Immediate Forward

Forward to main email immediately. Prepend `[紧急]` to subject. Main email is resolved via `mail-cli clawemail master-user`.

**Matching patterns** (case-insensitive, check subject + body):
- CI/CD failures: `failed`, `broken`, `build error`, `workflow run failed`, `check suite failed`
- Security: `dependabot`, `security alert`, `vulnerability`, `CVE-`
- Direct mentions requiring action: body contains `@<your-username>` AND words like `please`, `need`, `urgent`, `ASAP`, `decision`, `approve`, `block`
- Deploy failures: `deploy failed`, `rollback`

**Forward format:**
```
Subject: [紧急] <original-subject>
Body: <original-body>
```

### 🟡 P1 — Buffer for Daily Summary

Do NOT forward immediately. Store metadata for daily summary.

**Matching patterns:**
- PR review requests: `requested your review`, `review requested`
- PR merged: `merged`, `pull request merged`
- PR approved: `approved your pull request`
- Issue assigned: `assigned to you`, `you were assigned`

**Store format (one line per item):**
```
<repo>|<type>|<title>|<url>|<timestamp>
```

### 🟢 P2 — Silent Archive

No forward. No reply. Mark as read.

**Everything else**, including:
- Star/watch notifications
- Comment threads you're CC'd on
- Subscription digests
- Bot auto-comments (codecov, dependabot auto-merge, etc.)

## Daily Summary Format

Send at configured time (default 18:00) to main email (resolved via `mail-cli clawemail master-user`).

```
Subject: [GitHub 日报] <date> — <n> 条待处理通知

# GitHub 通知日报 — <date>

## 🔍 待你 Review 的 PR（<count>）

### <repo-name>
- [ ] #<number> <title>  — <author>, <time-ago>

### <repo-name>
- [ ] #<number> <title>  — <author>, <time-ago>

## ✅ 今日 Merged PR（<count>）
- <repo>#<number> <title>

## 🔒 今日 Closed Issue（<count>）
- <repo>#<number> <title>

---
此邮件由 GitHub Triage Skill 自动生成
```

If no buffered items exist, skip sending the summary (don't send empty reports).


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)