Back to list
DBS-Dev2000

daily-briefing

by DBS-Dev2000

Version-controlled repository for Claude Code and Claude Desktop agents and skills

0🍴 0📅 Jan 25, 2026

SKILL.md

Daily Briefing Generator Skill

Overview

Generate a comprehensive daily briefing by orchestrating data from calendar, email, Teams, Wrike, and weather into a Notion database entry.

Trigger Phrases

  • "Generate my daily briefing"
  • "Create today's briefing"
  • "What's on my schedule today?" (comprehensive view)
  • "Give me my daily briefing for [date]"
  • /daily-briefing or /daily-briefing 2026-01-24

⚠️ MANDATORY REQUIREMENTS - Session Consistency

Every briefing MUST include ALL of the following sections. Do NOT skip any section.

Required Sections - MANDATORY ORDER

Sections MUST appear in this exact order. Do not reorder.

OrderSectionRequired Content
1Page Name"{DayName}, {Month} {Day}, {Year}" format
2WeatherCurrent conditions + forecast + any alerts
3Quick SummaryDay overview with key counts (meetings, emails, tasks)
4CalendarTimeline table + deep work blocks
5Teams@mentions and action keywords
6EmailCounts by account + specific emails listed
7WrikeTasks by category with clickable links
8Action ItemsPrioritized list with checkboxes (to_do blocks)

Consistency Rules

  1. Always set page name first - Before adding any content
  2. Follow section order exactly - Weather → Summary → Calendar → Teams → Email → Wrike → Actions
  3. Weather is mandatory - Fetch Charlotte, NC weather via WebSearch
  4. Email details required - Not just counts, list actual email subjects
  5. All Wrike links must be clickable - Use permalink format
  6. Action items use checkboxes - Use Notion to_do blocks so user can check them off
  7. Complete all 8 sections - Never mark "Ready" with missing sections

Execution Workflow

PHASE 1: Initialize (Required First)

Execute these sequentially:

1. Get Wrike Contact ID (if not cached):
   Tool: mcp__wrike__wrike_get_my_contact_id
   Purpose: Get user's Wrike ID for task filtering
   Store as: WRIKE_CONTACT_ID

2. Get Wrike Workflows (CRITICAL - blocks all task processing):
   Tool: mcp__wrike__wrike_get_workflows
   Purpose: Map customStatusId to human-readable status names
   Store as: WORKFLOW_MAPPING = {status_id: status_name}

PHASE 2: Parallel Data Collection

Execute ALL of these in parallel (no dependencies between them):

CALENDARS (5 sources):
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. Work Calendar                                                        │
│    Tool: mcp__m365__list_events                                         │
│    Params: account_id="prisma", start_date=TODAY_START, end_date=TODAY_END │
├─────────────────────────────────────────────────────────────────────────┤
│ 2. DataBusiness Calendar                                                │
│    Tool: mcp__m365__list_events                                         │
│    Params: account_id="databusiness", start_date=TODAY_START, end_date=TODAY_END │
├─────────────────────────────────────────────────────────────────────────┤
│ 3. Personal Calendar                                                    │
│    Tool: mcp__m365__list_events                                         │
│    Params: account_id="personal", start_date=TODAY_START, end_date=TODAY_END │
├─────────────────────────────────────────────────────────────────────────┤
│ 4. Family Calendar                                                      │
│    Tool: mcp__m365__list_events                                         │
│    Params: account_id="personal", calendar_id="family", start_date=TODAY_START, end_date=TODAY_END │
├─────────────────────────────────────────────────────────────────────────┤
│ 5. Google Calendar                                                      │
│    Tool: mcp__google__google_calendar_list_events                       │
│    Params: calendar_id="primary", time_min=TODAY_START, time_max=TODAY_END │
└─────────────────────────────────────────────────────────────────────────┘

EMAILS (5 queries):
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. Prisma Unread                                                        │
│    Tool: mcp__m365__search_emails                                       │
│    Params: account_id="prisma", query="isRead:false", max_results=25    │
├─────────────────────────────────────────────────────────────────────────┤
│ 2. Prisma Flagged                                                       │
│    Tool: mcp__m365__search_emails                                       │
│    Params: account_id="prisma", query="flag:flagged", max_results=10    │
├─────────────────────────────────────────────────────────────────────────┤
│ 3. DataBusiness Unread                                                  │
│    Tool: mcp__m365__search_emails                                       │
│    Params: account_id="databusiness", query="isRead:false", max_results=15 │
├─────────────────────────────────────────────────────────────────────────┤
│ 4. Personal Unread                                                      │
│    Tool: mcp__m365__search_emails                                       │
│    Params: account_id="personal", query="isRead:false", max_results=20  │
├─────────────────────────────────────────────────────────────────────────┤
│ 5. Gmail Unread                                                         │
│    Tool: mcp__google__gmail_search_emails                               │
│    Params: query="is:unread", max_results=10                            │
└─────────────────────────────────────────────────────────────────────────┘

WRIKE TASKS (1 query):
┌─────────────────────────────────────────────────────────────────────────┐
│ Active Tasks                                                            │
│    Tool: mcp__wrike__wrike_search_tasks                                 │
│    Params: responsibles=[WRIKE_CONTACT_ID], status=["Active"]           │
│    Fields: customFields, superParentIds, responsibleIds, customStatusId │
│    CRITICAL: Capture task.permalink for each task (clickable links)    │
│    Permalink format: https://www.wrike.com/open.htm?id={task_id}        │
└─────────────────────────────────────────────────────────────────────────┘

TEAMS ACTION ITEMS (2 queries):
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. Recent @Mentions                                                     │
│    Tool: mcp__m365__teams_search_messages                               │
│    Params: account_id="prisma", query="@Daren", limit=20                │
├─────────────────────────────────────────────────────────────────────────┤
│ 2. Action Keywords                                                      │
│    Tool: mcp__m365__teams_search_messages                               │
│    Params: account_id="prisma", query="please OR todo OR deadline OR need", limit=20 │
└─────────────────────────────────────────────────────────────────────────┘

WEATHER (MANDATORY - 1 query):
┌─────────────────────────────────────────────────────────────────────────┐
│ Charlotte NC Weather                                                    │
│    Tool: WebSearch                                                      │
│    Query: "Charlotte NC weather today forecast"                         │
│    Extract: Current temp, conditions, high/low, any alerts/warnings     │
│    Location: Charlotte, North Carolina (user's location)                │
│    Note: Include any severe weather alerts prominently                  │
└─────────────────────────────────────────────────────────────────────────┘

PHASE 3: Inline Data Aggregation

Process ALL collected data WITHOUT external files:

Calendar Aggregation

# Merge all calendar sources into single sorted timeline
all_events = []
for source, events in calendar_results.items():
    for event in events:
        all_events.append({
            "source": source,
            "subject": event.subject[:60],
            "start": event.start.dateTime,
            "end": event.end.dateTime,
            "location": event.location or "",
            "is_online": "teams.microsoft.com" in (event.onlineMeetingUrl or "")
        })

# Sort by start time
all_events.sort(key=lambda x: x["start"])

# Calculate deep work blocks (gaps >= 2 hours)
deep_work_blocks = []
for i in range(len(all_events) - 1):
    gap_hours = (all_events[i+1].start - all_events[i].end).hours
    if gap_hours >= 2:
        deep_work_blocks.append({
            "start": all_events[i].end.strftime("%H:%M"),
            "end": all_events[i+1].start.strftime("%H:%M"),
            "hours": gap_hours
        })

Email Categorization

categories = {
    "critical_alerts": [],      # urgent, critical, asap, immediate
    "system_errors": [],        # error, failed, exception, timeout, crash
    "financial_notices": [],    # balance, payment, deposit, overdraft
    "deliveries": [],           # usps, fedex, ups, delivery, package
    "cybersource_issues": [],   # cybersource, payment gateway
    "action_required": [],      # high importance or flagged
}

for account, emails in email_results.items():
    for email in emails:
        subject = email.subject.lower()
        # Categorize by keywords...
        # Truncate subject to 80 chars for token efficiency

Wrike Task Categorization

# Use WORKFLOW_MAPPING from Phase 1
task_categories = {
    "in_progress": [],
    "final_review_prod": [],
    "on_hold": [],
    "awaiting_feedback": [],
    "overdue": [],
    "kraken_mailing": [],
    "promostandards": [],
    "high_priority": []
}

for task in wrike_tasks:
    status_name = WORKFLOW_MAPPING.get(task.customStatusId, "Unknown")
    task_info = {
        "title": task.title[:60],
        "status": status_name,
        "due": task.dates.due if task.dates else None,
        "importance": task.importance,
        "id": task.id,
        "permalink": task.permalink  # CRITICAL: Include for clickable links
    }
    # Categorize by status keywords...
    # Check if overdue (due_date < today)
    # Group by project keywords

Teams Action Item Extraction

action_items_from_teams = []
for message in teams_results:
    # Check for @mentions
    if "@Daren" in message.content:
        action_items_from_teams.append({
            "type": "mention",
            "from": message.from.user.displayName,
            "content": message.content[:100],
            "date": message.createdDateTime,
            "chat": message.channelIdentity.channelId or message.chatId
        })
    # Check for action keywords
    if any(kw in message.content.lower() for kw in ["please", "can you", "need", "todo", "deadline"]):
        action_items_from_teams.append({
            "type": "action_keyword",
            "from": message.from.user.displayName,
            "content": message.content[:100],
            "date": message.createdDateTime
        })

Generate Top 7 Action Items

action_items = []
priority = 1

# 1. Critical alerts
if critical_count > 0:
    action_items.append({
        "priority": priority,
        "icon": "🚨",
        "action": f"Address {critical_count} critical system alerts"
    })
    priority += 1

# 2. Overdue tasks
if overdue_count > 0:
    action_items.append({
        "priority": priority,
        "icon": "⏰",
        "action": f"Triage {overdue_count} overdue Wrike tasks"
    })
    priority += 1

# 3. Deep work opportunity (if >= 2 hours available)
if total_deep_work_hours >= 2:
    action_items.append({
        "priority": priority,
        "icon": "🚀",
        "action": f"Deep work on KRAKEN ({total_deep_work_hours}hrs available)"
    })
    priority += 1

# 4. Day-specific priorities
day_name = datetime.now().strftime("%A")
if day_name in ["Tuesday", "Sunday"]:
    action_items.append({
        "priority": priority,
        "icon": "🌏",
        "action": "Review offshore team commits"
    })
    priority += 1

# 5. Teams action items
if teams_action_count > 0:
    action_items.append({
        "priority": priority,
        "icon": "💬",
        "action": f"Respond to {teams_action_count} Teams messages requiring action"
    })
    priority += 1

# 6. Financial notices
if financial_count > 0:
    action_items.append({
        "priority": priority,
        "icon": "💰",
        "action": f"Review {financial_count} financial notices"
    })
    priority += 1

# 7. High priority Wrike tasks
if high_priority_count > 0:
    action_items.append({
        "priority": priority,
        "icon": "⭐",
        "action": f"Work on {high_priority_count} high-priority tasks"
    })

# Return top 7
return action_items[:7]

PHASE 4: Create Notion Entry

Option A: Use notion_block_builder.py (Recommended)

Pipe the aggregated data through the block builder to generate proper Notion blocks:

# Generate blocks from aggregated data
echo '{aggregated_data_json}' | python notion_block_builder.py > blocks.json

# Or use inline_aggregator output directly
echo '{raw_data}' | python inline_aggregator.py | python notion_block_builder.py

The block builder automatically:

  • Creates clickable Wrike task links using task.permalink
  • Applies color coding by status (red for In Progress, yellow for Awaiting, etc.)
  • Groups tasks by category (KRAKEN, PromoStandards, etc.)
  • Formats the complete briefing structure

Option B: Manual Block Creation

Create database entry with aggregated data:

Tool: mcp__notion__notion_create_database_item
Params:
  database_id: "b063f8ee870e4caa956b1e1e24da31cf"
  properties:
    - Name: "{DayName}, {Month} {Day}, {Year}"
    - Date: {briefing_date}
    - Status: "Ready"
    - Meeting Count: {total_meetings}
    - Unread Email Count: {total_unread}
    - Active Task Count: {active_tasks}
    - Deep Work Hours: {total_deep_work_hours}

Then populate content with blocks:

Tool: mcp__notion__notion_append_block_children
Params:
  block_id: {new_page_id}
  children: [
    # Generated content blocks with clickable Wrike links...
  ]

Each Wrike task MUST be rendered as a Notion block with a clickable link to the task. Use this exact JSON structure for bulleted_list_item blocks:

{
  "object": "block",
  "type": "bulleted_list_item",
  "bulleted_list_item": {
    "rich_text": [
      {
        "type": "text",
        "text": {
          "content": "Task Title Here",
          "link": { "url": "https://www.wrike.com/open.htm?id=TASK_ID" }
        },
        "annotations": { "bold": true }
      },
      {
        "type": "text",
        "text": { "content": " - Status description (Due: Jan 30) " }
      },
      {
        "type": "text",
        "text": { "content": "HIGH" },
        "annotations": { "bold": true, "color": "red" }
      }
    ],
    "color": "default"
  }
}

Key Points:

  • The task title text MUST have a link.url property with the Wrike permalink
  • Use annotations.bold: true for task titles
  • Use annotations.color: "red" for HIGH priority indicators
  • Color the entire block for status: "color": "red" for In Progress, "color": "orange" for overdue
  • Truncate task titles to 60 characters max

Day-of-Week Intelligence

DayFocusSpecial ActionsHighlight
MondayDeep WorkInbox triage, week ahead🚀 Start strong
TuesdayDeep WorkCheck offshore commits💻 Minimize meetings
WednesdayMeetingsMidweek checkpoint🤝 Collaboration focus
ThursdayCode ReviewsWeekly touchbase prep🔍 Offshore deliverables
FridayWrap UpEarly dismissal (2:30 PM)🏁 Wrap up week
SaturdayFamilyMinimal work check👨‍👩‍👧 Family first
SundayPlanningOffshore review, Monday prep📋 Plan ahead

Output Format

CRITICAL: Every briefing MUST follow this exact structure and order. Do not skip or reorder sections.

SECTION ORDER (MANDATORY):
1. Weather
2. Quick Summary
3. Calendar
4. Teams
5. Email
6. Wrike
7. Action Items (with checkboxes)

Present the briefing in this format:

# Daily Briefing - {DayName}, {Month} {Day}, {Year}
**Generated:** {timestamp} | **Status:** Ready

---

## 🌤️ Weather - Charlotte, NC
**Current:** {current_temp}°F - {conditions}
**Today:** High {high}°F / Low {low}°F
**Forecast:** {brief_forecast}
{IF ALERTS: ⚠️ **WEATHER ALERT:** {alert_type} - {alert_details}}

---

## 📊 Quick Summary

| Metric | Value |
|--------|-------|
| Meetings Today | {total_meetings} |
| Deep Work Hours | {deep_work_hours} |
| Unread Emails | {total_unread} |
| Active Wrike Tasks | {active_count} |
| Overdue Tasks | {overdue_count} |
| Critical Alerts | {critical_count} |
| Teams Actions | {teams_action_count} |

**Day Focus:** {day_highlight based on day-of-week}

---

## 📅 Calendar ({total_meetings} meetings, {deep_work_hours}hrs deep work)

### Timeline
| Time | Event | Source | Location |
|------|-------|--------|----------|
{sorted_events}

### Deep Work Blocks
{deep_work_blocks as bullet list}

---

## 💬 Teams ({teams_action_count} action items)

### @Mentions
{mention_items as bullet list}

### Action Required
{action_keyword_items as bullet list}

---

## 📧 Email ({total_unread} unread)

### By Account
- **Prisma:** {count} unread
- **DataBusiness:** {count} unread
- **Personal:** {count} unread
- **Gmail:** {count} unread

### 🚨 Critical Items ({critical_count})
{critical_alerts and system_errors - list specific subjects}

### 💰 Financial Notices ({financial_count})
{financial_notices - list specific subjects}

### 📦 Deliveries ({delivery_count})
{delivery_notices - list specific subjects}

### Top Emails by Account (MANDATORY)

**Prisma (Work)**
| Subject | From | Received |
|---------|------|----------|
| {subject_1} | {sender_1} | {time_1} |
| {subject_2} | {sender_2} | {time_2} |
| {subject_3} | {sender_3} | {time_3} |

**DataBusiness**
| Subject | From | Received |
|---------|------|----------|
| {subject_1} | {sender_1} | {time_1} |
| {subject_2} | {sender_2} | {time_2} |

**Personal**
| Subject | From | Received |
|---------|------|----------|
| {subject_1} | {sender_1} | {time_1} |
| {subject_2} | {sender_2} | {time_2} |

---

## ✅ Wrike Tasks ({active_count} active, {overdue_count} overdue)

### 🔴 In Progress ({count})
{in_progress_tasks as bullet list with CLICKABLE LINKS to Wrike}

### ⚠️ Overdue ({count})
{overdue_tasks as bullet list with CLICKABLE LINKS to Wrike}

### 🟡 Final Review ({count})
{final_review_tasks as bullet list with CLICKABLE LINKS to Wrike}

### 🔵 Awaiting Feedback ({count})
{awaiting_feedback_tasks as bullet list with CLICKABLE LINKS to Wrike}

**IMPORTANT:** Each task title MUST be a clickable link using the task's permalink.
Format: [Task Title](https://www.wrike.com/open.htm?id=TASK_ID) - Status (Due: Date)

---

## ☑️ Action Items (CHECKBOXES)
**Use Notion to_do blocks so items can be checked off**

{action_items as to_do blocks with icons - MUST have 5-7 items}

Example Notion to_do block format:
```json
{
  "type": "to_do",
  "to_do": {
    "rich_text": [{"type": "text", "text": {"content": "🚨 Address 2 critical system alerts"}}],
    "checked": false,
    "color": "default"
  }
}

Action items should be prioritized:

  1. 🚨 Critical alerts (immediate attention)
  2. ⏰ Overdue tasks (clear debt)
  3. 🚀 Deep work opportunities
  4. 💬 Teams responses needed
  5. 💰 Financial reviews
  6. ⭐ High priority tasks
  7. 🌏 Day-specific actions (offshore review, etc.)

Generated by Claude Daily Briefing System v3.2


---

## PHASE 5: Validation Checklist (MANDATORY)

**Before marking Status="Ready", verify ALL items are complete IN ORDER:**

VALIDATION CHECKLIST - Must pass ALL before marking Ready ═══════════════════════════════════════════════════════════

SECTION ORDER CHECK (must be in this exact order): □ 1. Page Name set to "{DayName}, {Month} {Day}, {Year}" □ 2. Weather section present with current conditions + alerts □ 3. Quick Summary table with all 7 metrics + day focus □ 4. Calendar section with timeline table + deep work blocks □ 5. Teams section with @mentions + action keywords □ 6. Email section with counts + specific emails by account □ 7. Wrike section with categories + clickable links □ 8. Action Items section with CHECKBOXES (to_do blocks)

CONTENT REQUIREMENTS: □ Weather includes any alerts/warnings prominently □ Quick Summary has all 7 metrics filled in □ Calendar timeline is sorted by time □ Deep work blocks calculated (gaps >= 2 hours) □ Teams shows actual messages or "No action items" □ Email lists 3-5 specific emails per account □ All Wrike task titles are clickable links □ Action items use to_do blocks (checkboxes), not bullets □ 5-7 action items prioritized with icons

NOTION PROPERTIES: □ Status = "Ready" □ Phase = "6-Complete" □ Meeting Count = {actual count} □ Unread Email Count = {actual count} □ Active Task Count = {actual count} □ Deep Work Hours = {actual hours}

If ANY item is missing → Do NOT mark Ready, complete it first


### Common Mistakes to Avoid
1. ❌ Wrong section order (must be: Weather → Summary → Calendar → Teams → Email → Wrike → Actions)
2. ❌ Action items as bullets instead of checkboxes (to_do blocks)
3. ❌ Skipping weather because "it's not a data source"
4. ❌ Only showing email counts without specific email subjects
5. ❌ Wrike tasks without clickable links
6. ❌ Missing page name (showing ID instead of formatted date)
7. ❌ Quick Summary at the end instead of near the top
8. ❌ Empty sections without "None" or "No items" message

---

## Error Handling

### Partial Briefing Generation
If any data source fails, continue with available data:
- Missing calendar: Note "Calendar unavailable" in timeline
- Missing emails: Show "Email check failed" with retry suggestion
- Missing Wrike: Show "Wrike unavailable" with direct link
- Missing Teams: Skip section with note

### Recovery Actions
- Retry failed calls once with exponential backoff
- Cache successful results for 5 minutes
- Always create Notion entry (even if partial)
- Mark Status as "Partial" if any source failed

---

## Configuration

```yaml
Notion:
  database_id: "b063f8ee870e4caa956b1e1e24da31cf"
  parent_page_id: "2e1c2c7a-5990-8168-a2e3-c3a00a606abf"

Wrike:
  contact_id: "KUAFJKXO"  # Daren's ID

M365 Accounts:
  prisma: "Work (dbruncak@poweredbyprisma.com)"
  databusiness: "Business (dbruncak@databusiness.ai)"
  personal: "Personal (dbruncak@outlook.com) + Family calendar"

Google:
  calendar: "primary"
  gmail: "primary"

Timezone: "America/New_York"

Performance Targets

MetricTargetMethod
Token Usage< 6,000Inline aggregation, truncation
Execution Time< 40sParallel data collection
Tool Calls14 maxOptimized query batching
Success Rate> 95%Error handling, partial generation

Version

  • Version: 3.2
  • Last Updated: 2026-01-25
  • Status: Production Ready

Changelog

  • v3.2 (2026-01-25): Added session consistency enforcement
    • Added MANDATORY REQUIREMENTS section with 9 required sections checklist
    • Added Weather section (Charlotte, NC) as mandatory data source
    • Added Email Details section requiring specific emails from each account
    • Added PHASE 5: Validation Checklist before marking "Ready"
    • Added Common Mistakes to Avoid section
    • Added Teams Actions to Quick Stats table
    • Page Name now explicitly required in checklist
  • v3.1 (2026-01-24): Added CRITICAL requirement for clickable Wrike task links with permalink format
  • v3.0 (2026-01-14): Initial PTC-optimized implementation

Score

Total Score

45/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

0/5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon