SuperAPI AI Directory

card-refresh

Office & productivity

View repository

Updated 10-16 02:39

About this skill

card-refresh — periodic widget data refresh

You're invoked to re-pull data for whatever widgets are currently shown on the user's ai-desk-card secondary screen. This typically runs from cron every 2 hours (see REFRESH.md for the setup). Be quick, idempotent, and silent unless something's wrong.

Operating principles

  • Read first, push second. Pull the current widget cache from GET /widget — it tells you which slots are filled with which widget types. Only refresh those; don't push new widget types unprompted.
  • No data → don't push. If a data source is unreachable (calendar not synced, mail offline), skip that widget. Leave the existing one in place rather than wiping with stale data.
  • Be fast. Don't burn 30 s on one data source. 5 s timeout per fetcher; move on.
  • Be quiet. No "I'm refreshing..." chatter when invoked from cron. Emit nothing on stdout unless there's an actionable error.

What to do (every run)

1. Snapshot current cache

curl -sf http://127.0.0.1:9877/widget | python3 -m json.tool

Parse widgets[]. For each {slot, type, age}, decide:

  • age < 60 s → just pushed, skip.
  • type in {ai-status, ai-tasks} → driven by conversation, skip.
  • type in {focus, scratch} → user-supplied, only refresh if explicitly asked.
  • All others → refresh if you can.

2. Fetch fresh data per widget type

The card-widget skill's schemas tell you the data shape. Below are the recommended sources per widget (use whatever's actually available on the user's machine):

Widget Source Notes
weather wttr.in / OpenWeather / system weather Need user's location
calendar icalbuddy on macOS / Google Calendar API / .ics file macOS easiest
next-meeting same as calendar — pick first event with starts_in_min ≥ 0
inbox gmail API / mailctl / IMAP / Slack API Per-source counts only
messages iMessage db / Slack DMs macOS: ~/Library/Messages/chat.db (read-only)
pr-queue gh pr list against user's repos List repos via config
git-status git -C <cwd> status --porcelain + git log -1 One repo only
system psutil / uptime / vm_stat macOS: vm_stat for mem, df for disk
now-playing macOS: osascript -e 'tell application "Spotify"...' Skip if not running
todo macOS Reminders (use fetch_todo_reminders.py in card-widget)
deadlines user-maintained list (see assets/deadlines.yaml if it exists)
break-reminder local idle / activity tracking Best-effort

You don't need to support all of these in one refresh. Start with the 3-4 widgets the user actually has on the card, refresh those, push, exit.

3. Push back

Use the card-widget skill's push_widget.py helper or curl. Re-push the SAME {slot, type} with new data. Daemon will replace and trigger a single debounced frame render.

Per-widget TTL: pass ttl=7800 (2h 10min) so widgets fade if cron breaks. That way a stuck cron doesn't leave hours-old data on the panel forever.

4. Done — exit

Don't summarize, don't ask follow-up questions. Just exit. Cron user sees nothing in their terminal.

When invoked interactively (not from cron)

If the user says "refresh the card" in conversation, do the same thing but briefly tell them what you did:

Refreshed: calendar (3 events), weather (24°C clear), pr-queue (2 reviews waiting). Skipped: inbox (gmail API not configured).

Error handling

  • Daemon down → run /card-onboard decision tree, but don't try to start it from cron (user won't see the prompt). Just exit with a diagnostic line on stderr.
  • Network down → skip remote sources, push local ones (system, git-status) anyway.
  • Schema mismatch on push → log to stderr, continue. The daemon rejects the bad widget; other widgets still get refreshed.

What NOT to do

  • ❌ Don't change which widgets are in which slot. That's user-controlled.
  • ❌ Don't push widgets that weren't already there (e.g., "I noticed you don't have a weather widget, let me add one").
  • ❌ Don't write ai-status from this skill — that's driven by interactive interactive AI agent sessions.
  • ❌ Don't fetch data from sources that need OAuth without checking if credentials are configured.

Helper scripts

  • scripts/refresh_loop.sh — one-shot refresh entry point. Used as the cron command. Wraps the headless AI CLI invocation.
  • scripts/fallback_refresh.py — pure-Python no-AI version that only refreshes system, git-status, and weather (wttr.in). For users who don't want token cost.