Skip to content
Agent Workspaces
Skill

/card-refresh

Invoked by cron (or manually) to refresh the widgets on the ai-desk-card e-ink display with fresh data. Reads the current widget cache, decides which widgets need new data, pulls from the user's data sources (calendar, mail, git, weather APIs, etc.), and pushes back via the

From plugin
ai-desk-card
1534 skills9 commands

Claude Code

$ npx -y skills add op7418/ai-desk-card --skill card-refresh --agent claude-code

SKILL.md

card-refresh.SKILL.md
name: card-refresh
description: |
  Invoked by cron (or manually) to refresh the widgets on the ai-desk-card
  e-ink display with fresh data. Reads the current widget cache, decides
  which widgets need new data, pulls from the user's data sources
  (calendar, mail, git, weather APIs, etc.), and pushes back via the
  card-widget skill. Use when invoked headless from cron, or when user
  says "刷新一下卡片" / "refresh card" / "update widgets now".
trigger_keywords:
  - card refresh
  - 刷新卡片
  - 更新卡片
  - 更新组件
  - refresh widgets
allowed-tools:
  - Bash
  - Read
  - Write

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 副屏. This typically runs from cron every 2 hours (see [REFRESH.md](./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 "刷新一下卡片" in conversation, do the same thing but **briefly tell them what you did**:

> Refreshed: calendar (3 events), weather (24°C 晴), 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.

Read more
@op7418
Ships withai-desk-card

🌏 English version: README.en.md 一个适配 Claude Code / Codex 等 Agent 的桌面副屏 Skill。把 M5Paper V1.1 4.7 寸墨水屏立在显示器旁边,由 AI Agent 推送 widget:天气、日程、todo、PR 队列、AI 状态、休息提醒…… 装上 Skill 后,烧固件 / 配 Wi-Fi / 推内容 / 设置定时全部由 Agent 引导,你不用自己跑一行 pio 或 curl。

Stars on GitHub

Momentum

stars in total
153
Star history of op7418/ai-desk-card on GitHub, a chart by star-history.com

Other skills on ai-desk-card.

card-onboard

card-onboard

Onboard a user setting up AI Desk Card for the first time, or after moving to a new machine, plugging the device into a new…

@op7418@op7418Install Skill
card-widget

card-widget

Push live data to the user's ai-desk-card M5Paper e-ink companion display. Use whenever the user asks to show todos, calendar,…

@op7418@op7418Install Skill
card-wifi-setup

card-wifi-setup

Walk a user through provisioning Wi-Fi on their AI Desk Card device. After provisioning, device joins the user's home Wi-Fi,…

@op7418@op7418Install Skill

More skills from other plugins.

paseo

paseo

Paseo reference for managing hosts, projects, workspaces, workspace scripts, agents, schedules, and heartbeats.

paseo2w23k
@getpaseo@getpaseoInstall Skill
10x
Auto-invoked

10x

Personalized audit that teaches the advanced Paradev (formerly Superset) features the user isn't using yet (automations, parallel…

paradev5d16k
@superset-sh@superset-shInstall Skill
capabilities

capabilities

Your capability catalog — read this at boot. Lists the temporal date-range skills and the external integrations (reached via the…

@chaitanyagiri@chaitanyagiriInstall Skill

Questions about card-refresh.

Which coding agents can use card-refresh?
card-refresh installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.