Skill: pmaeter/daily-digest (version 1.0.0)

# daily-digest Skill Purpose: Generate a daily digest from memory and interactions, stored as journals/digest/digest-YYYY-MM-DD.md. Usage: - Run the digest_daily.py script to generate today's digest. - Optional: integrate with clawdbot to run automatically via a cron job or a scheduler. Notes: - The script reads memory/YYYY-MM-DD.md and optionally memory/YYYY-MM-DD.md from yesterday to extract decisions, lessons, actions, and questions. - It also provides a placeholder summary when no structured entries exist in memory.

path: README.md
content: # Daily Digest Skill

This skill generates a daily Markdown digest from memory notes and the broader interactions for Clawdbot. The digest is saved as journals/digest/digest-YYYY-MM-DD.md.

Usage:
- Run: python3 digest_daily.py
- Expected output: A file created at journals/digest/digest-YYYY-MM-DD.md with a structured summary.

Automation:
- You can schedule this to run daily via Clawdbot's cron or your system cron.


path: digest_daily.py
content: #!/usr/bin/env python3
"""Daily digest generator for Clawdbot.

Generates journals/digest/digest-YYYY-MM-DD.md by extracting key items
from memory/MM-DD-YYYY.md and memory/previousday.md.
"""
from datetime import date, timedelta
import os
import re

def read_text(p):
    try:
        with open(p, 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return ''

def extract_section(text, marker):
    # Look for lines starting with marker (case-insensitive) and subsequent bullet lines
    lines = text.splitlines()
    collecting = False
    items = []
    for line in lines:
        if re.match(rf"^\s*{re.escape(marker)}\s*:?", line, flags=re.IGNORECASE):
            collecting = True
            continue
        if collecting:
            if line.strip().startswith('-'):
                items.append(line.strip().lstrip('- ').rstrip())
            elif line.strip() == '' or line.strip().startswith('#'):
                # stop on blank or new section-ish header
                break
            else:
                # treat as continuation of bullet
                if items:
                    items[-1] = items[-1] + ' ' + line.strip()
                else:
                    if line.strip():
                        items.append(line.strip())
    return items

def gather_digest(base_dir, today):
    date_str = today.isoformat()
    yesterday = today - timedelta(days=1)
    y_str = yesterday.isoformat()

    mem_today = os.path.join(base_dir, 'memory', f"{date_str}.md")
    mem_yest = os.path.join(base_dir, 'memory', f"{y_str}.md")

    text_today = read_text(mem_today)
    text_yest = read_text(mem_yest)

    dec = extract_section(text_today, 'Décision') or extract_section(text_today, 'Decision')
    les = extract_section(text_today, 'Leçon') or extract_section(text_today, 'Lesson')
    act = extract_section(text_today, 'Action') or extract_section(text_today, 'Prochain')
    ques = extract_section(text_today, 'Question') or extract_section(text_today, 'Question')

    # If no sections for today, try to summarize from memory text
    summary = text_today.strip().splitlines()
    if summary:
        summary = summary[:5]
        summary_text = ' '.join(l.strip() for l in summary)
    else:
        summary_text = ''

    # Build digest sections
    parts = []
    if summary_text:
        parts.append("## Résumé\n" + summary_text.strip())
    if dec:
        parts.append("## Décisions\n" + '\n'.join(f"- {i}" for i in dec))
    if les:
        parts.append("## Leçons / Points clés\n" + '\n'.join(f"- {i}" for i in les))
    if act:
        parts.append("## Prochaines étapes\n" + '\n'.join(f"- {i}" for i in act))
    if ques:
        parts.append("## Questions\n" + '\n'.join(f"- {i}" for i in ques))

    if not parts:
        parts.append("## Digest automatique\nAucune entrée structurée trouvée dans memory pour aujourd'hui.")

    content = f"# Daily Digest - {date_str}\n\n" + '\n\n'.join(parts)
    return date_str, content

def main():
    script_dir = os.path.dirname(os.path.realpath(__file__))
    base_dir = os.path.abspath(os.path.join(script_dir, '..', '..'))  # /root/clawd
    today = date.today()

    date_str, content = gather_digest(base_dir, today)
    out_dir = os.path.join(base_dir, 'journals', 'digest')
    if not os.path.exists(out_dir):
        os.makedirs(out_dir, exist_ok=True)
    out_path = os.path.join(out_dir, f"digest-{date_str}.md")
    with open(out_path, 'w', encoding='utf-8') as f:
        f.write(content)
    print(f"Wrote {out_path}")

if __name__ == '__main__':
    main()


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