agent-activity
Streams what the agent is doing into the room, as rows the desktop client renders in an **events drawer** above the composer (collapsed: avatar, pulsing dots,…
Generate a daily morning briefing: email, calendar, Discord, and news — delivered via voice or Discord DM.
$ npx -y skills add sonichi/sutando --skill morning-briefing --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/morning-briefingContext preview
The summary Claude sees to decide when to auto-load this skill.
Generate a daily morning briefing: email, calendar, Discord, and news — delivered via voice or Discord DM.
name: morning-briefing description: "Generate a daily morning briefing: email, calendar, Discord, and news — delivered via voice or Discord DM." user-invocable: true
Generate a prioritized daily briefing from all your channels.
**Usage**: `/morning-briefing`
ARGUMENTS: $ARGUMENTS
**Step 0 — Calendar cache. CONDITIONAL: Google-calendar hosts only.**
`src/morning-briefing.py` cannot reach the owner's Google Workspace calendar; it reads a cache the *agent* writes. Omitting this is silent: the briefing reports "couldn't read your calendar", or falls back to a local macOS Calendar read that stalls and can miss the work account entirely. Pull today's local-day events from the Google connector, then:
echo '[{"raw":"9:00-9:30am 1:1 w/ Sam","calendar":"work"}]' | python3 src/write_calendar_cache.py
python3 src/write_calendar_cache.py --empty # ONLY for a genuinely empty day**Hosts with no Google connector skip STEP 0 ONLY** — the reader falls back to local macOS Calendar. Step 1 below still runs on every host. See "Calendar source (Google Workspace) — activation" for the full contract.
**Step 1 — Base data (canonical; runs on EVERY host, including hosts that skipped Step 0):**
WORKSPACE="$(bash scripts/sutando-config.sh workspace)" python3 src/morning-briefing.py
`src/morning-briefing.py` is the single source of truth for core briefing data: weather (Open-Meteo), macOS Calendar, macOS Reminders, overnight Discord DMs, pending questions, and system health. It writes output to `results/proactive-<ts>.txt` and sends a Discord DM directly. Review its output before composing the full briefing — do NOT re-fetch those sources manually.
**Then augment with the following if configured (skip if not available):**
1. **Email** — Run `gws gmail +triage` to get unread inbox. Summarize top 5 by priority. Flag anything urgent.
2. **GWS Calendar** — If the user uses Google Calendar (not just macOS Calendar), run `gws calendar +agenda --today`. List any meetings not already covered by the macOS Calendar output above.
3. **Friction check** — Run `python3 src/friction-detector.py`. If friction items found, include as "⚠️ Friction: [count] items need attention" with the top 3.
`src/morning-briefing.py` already writes `results/proactive-<ts>.txt` (spoken by voice) and sends a Discord DM for the base data. If you gathered email in steps 1–3, append it as a follow-up proactive file:
echo "📧 Email: [count] unread. [summary]" > "$WORKSPACE/results/proactive-$(date +%s).txt"
`src/morning-briefing.py` is a standalone script and **cannot reach the owner's Google Workspace calendar** — the Station/Composio connector is agent-only. So the briefing reads a cache that the *agent* produces:
echo '[{"raw":"9:00-9:30am 1:1 w/ Sam","calendar":"work"}]' | python3 src/write_calendar_cache.py
python3 src/write_calendar_cache.py --empty # verified no events todayNothing writes the cache automatically, so **a briefing that only runs the reader reports unread on a Google-source host.** The producer is therefore step 0 of this skill's own flow (above), which covers both `/morning-briefing` and a cron declared as `"prompt_skill": "morning-briefing"` — the natural config. The expanded cron prompt under "Scheduling" below remains valid but is no longer the only place the producer appears.
Observed on Chis-Mac-mini: `state/calendar-today.json` was last written **2026-07-30 07:28** and the host's cron was `{"name": "morning-briefing", "prompt_skill": "morning-briefing"}`, so nothing invoked the producer. Three consecutive briefings reported no calendar, and the local fallback added a ~23s AppleScript stall before returning nothing.
The canonical daily schedule produces the Google-calendar cache first, then runs the briefing against it (see the activation section above):
{
"name": "morning-briefing",
"cron": "57 6 * * *",
"prompt": "Morning briefing. FIRST produce the calendar cache from the owner's REAL Google calendar (the standalone script can't reach the connector): pull today's events via the Google-calendar connector (e.g. sutando-station composio_exec GOOGLECALENDAR_EVENTS_LIST, calendarId=primary, today's local-day window), then pipe them as a JSON array of {raw,calendar} to `python3 src/write_calendar_cache.py` (or `--empty` if genuinely no events). THEN run `MORNING_BRIEFING_CALENDAR_SOURCE=google python3 src/morning-briefing.py` to deliver the briefing. Speak the result if voice is connected, send as Discord DM otherwise."
}Calling `/morning-briefing` manually runs the same script plus GWS augmentation.
My AI Stand — Realtime by Day, Rewriting Itself by Night. Summon my AI superpower. Voice, vision, screen, meetings, calls when I'm engaged. Learns my patterns, ships its own code when I'm not. Runs across my Macs, interacts with people & their Stands.
Repo: sonichi/sutando
Streams what the agent is doing into the room, as rows the desktop client renders in an **events drawer** above the composer (collapsed: avatar, pulsing dots,…
Local Agent Registry — a standalone, dependency-free service that tracks running Claude Code (and other) agent instances. Agents self-register on startup and…
**Prefer the `ag2-space` MCP tools when they are connected and the room exposes them** — availability is per-room and per-actor, so check…
Deterministic final-answer normalizer — a last-step pass for any task that ends in a *precise* answer (a number, a short string, a comma-list). Applies the…
Transcribes audio files and voice notes to text via Gemini 2.5-flash. Integrates with Slack, Discord, and Telegram bridges so voice clips surface as readable…
Act back on the owner's Bee wearable — the TOOL half of the Bee integration (channels-vs-tools split). The Bee CHANNEL (ag2-sparrow's `sources/bee.py` watcher)…