A

ai-desk-card

by @op7418v
4.2(120)

ai-desk-card 是一个用于管理和控制 540×960 电子墨水屏的 Skill。它允许 AI 智能体向屏幕推送各种小部件(widgets),如天气、日程等。该 Skill 能够自动检测设备状态,处理固件安装、守护进程启动、Wi-Fi 配置以及内容推送和调度。它简化了 AI 智能体与物理显示设备的交互,确保信息能够高效、准确地呈现在用户的桌面电子卡片上,提升信息获取的即时性和便捷性。

e-inkautomationdevice-controlwidgetsai-agentGitHub
安装方式
git clone https://github.com/op7418/ai-desk-card.git
compare_arrows

Before / After 效果对比

1
使用前

用户需要主动打开手机或电脑应用,逐一查看天气、日程、待办事项等信息,耗时且容易遗漏重要更新。

使用后

AI 智能体自动将关键信息推送到桌面电子卡片,无需手动操作,信息实时更新,一目了然,显著提升信息获取效率。

SKILL.md

ai-desk-card — single Skill entry point

A 540×960 e-ink panel sitting next to the user's monitor. AI agents push widgets to it; the daemon renders frames server-side and ships pixels over Wi-Fi / USB / BLE. This Skill is the only thing an agent needs to call — it auto-detects state and routes to the right flow.

Step 1 — ALWAYS probe state first

Before doing anything, run the state probe. Do not ask the user "have you done X" — find out by checking.

bash $SKILL_DIR/scripts/state.sh

($SKILL_DIR is wherever this Skill is installed. If your agent runtime sets $CLAUDE_PLUGIN_ROOT, use that. Otherwise use the repo root.)

Output is JSON with this shape:

{
  "hardware":   { "pio_installed": bool, "m5paper_usb": str|null },
  "firmware":   { "flashed": bool, "ours": bool, "version": str|null },
  "daemon":     { "running": bool, "pid": int|null },
  "transport":  { "connected": bool, "type": "BLETransport|SerialTransport|WiFiTransport|null" },
  "device":     { "alive": bool, "last_seen_seconds": int|null,
                  "active_transport": "Wi-Fi|USB|BLE|null",
                  "battery_pct": int|null, "uptime": str|null },
  "wifi":       { "provisioned": bool, "ip": str|null },
  "interests":  { "configured": bool, "path": str|null }
}

The most important field is device.alive. It tells you whether the device has sent a status report in the last ~90 s. transport.connected only says "daemon picked a transport class"; device.alive says "we're actually hearing back from the device right now."

Step 2 — Route based on state

Walk the decision tree in this order. First mismatch wins; fix it, then re-probe.

ConditionNext actionDetail flow
firmware.flashed == false AND no device.aliveFirst-time hardware setupflows/01_install.md
daemon.running == falseStart the daemonbash $SKILL_DIR/plugin/scripts/start.sh
device.alive == false AND transport.connected == falseDevice unreachable — could be asleep, off, BLE not paired. Tell user, suggest physical wake (tap rotary / plug USB)flows/02_transport.md
device.alive == false AND transport.connected == true (daemon connected something but no status_report in 90s)Device transport up but not responding — restart daemon, then probeflows/02_transport.md
wifi.provisioned == false (and user wants always-on or battery mode)Provision Wi-Fiflows/03_wifi.md
interests.configured == false AND user just asked for "auto-refresh" or "定时推送"Ask about interests, write ~/.ai-desk-card/interests.yamlflows/04_interests.md
device.alive == true + user said "push X"Build widget JSON, POST to daemonflows/05_push.md
device.alive == true + user said "schedule" / "每 N 分钟" / "auto"Set up scheduled pushflows/06_schedule.md
device.alive == true + user said "sleep" / "息屏"Push business card + deep sleepflows/07_sleep.md

Always tell the user which step you're on. Don't operate silently.

Step 3 — Push a widget (the hot path)

When state is OK and user asks to show something:

curl -sf -X POST "${CARD_DAEMON_URL:-http://127.0.0.1:9877}/widget" \
  -H 'Content-Type: application/json' \
  -d @- <<'JSON'
{
  "slot": "top-left",
  "type": "weather",
  "data": { "city": "Beijing", "temp_c": 22, "icon": "sun", "summary": "晴" }
}
JSON
  • slot: string. Layout is 2-1-1 not 2x2 — top-left (270×280) · top-right (270×280) · middle (540×340) · bottom (540×280) · full (540×960, takes over the whole screen).
  • type: one of 16 — see plugin/skills/card-widget/schemas/ for full JSON schemas with examples.
  • Wi-Fi: response in ~0.2 s. USB: 1–32 s. BLE frame-data: broken — small commands only.

Full per-widget schema + theme reference: plugin/skills/card-widget/SKILL.md

Step 4 — When to suggest scheduled pushes

If the user's request implies recurrence ("keep my calendar updated", "check email every hour", "show me today's todos throughout the day"), don't just push once. Instead:

  1. Confirm the cadence + which widgets they want
  2. Write/update ~/.ai-desk-card/interests.yaml (see flow 04)
  3. Set up the schedule using your agent's native loop primitive:
    • Claude Code: /loop 30m or ScheduleWakeup
    • Codex / Gemini: equivalent scheduling
    • Fallback: cron line via plugin/skills/card-refresh/scripts/refresh_loop.sh

The Skill provides the what (interests + push) — your agent provides the when (loop primitive).

Constraints to never violate

  • No silent operations. Every sub-step gets a one-line update to the user.
  • No retry loops. If something fails, surface the diagnostic and stop.
  • No assuming state. Always re-probe after fixing something.
  • No font escape hatches. The CJK TTF doesn't include ▢ ▶ ✎ ♪ ↑ ↓ ● ○ — … °. Use the safe glyph set documented in plugin/skills/card-widget/SKILL.md.
  • Wi-Fi preferred over USB / BLE. 0.2 s vs 1-32 s vs broken.

Hardware: what the user needs

  • M5Paper V1.1 (~¥600 / $90) — primary target
  • USB-C data cable (one time, for flashing)
  • Optional: USB-C charger for always-on Wi-Fi mode

What this Skill is NOT

  • Not a Claude-Code-only plugin. The plugin/ directory is provided for CLIs that consume slash commands, but this SKILL.md is the agent-agnostic entry point.
  • Not a cloud service. Everything runs on the user's machine (daemon at 127.0.0.1:9877 by default) + the device's local Wi-Fi.
  • Not a generic e-ink renderer. The widgets, themes, and renderer all target this specific device + grid.

AI Desk Card · 桌面 AI 副屏 Skill

GitHub stars License Skill M5Paper Claude Code Codex

🌏 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 引导,你不用自己跑一行 piocurl

AI Desk Card 桌面效果

你 ──说自然语言──▶ AI Agent ──触发──▶ Skill ──自动执行──▶ M5Paper 屏上

30 秒开始

npx skills add https://github.com/op7418/ai-desk-card --skill ai-desk-card

也可以把下面这段话直接发给有 shell 权限的 AI Agent:

帮我安装 ai-desk-card Skill。把 https://github.com/op7418/ai-desk-card 克隆到 ~/.claude/skills/ai-desk-card,安装完成后检查 SKILL.md、flows/、daemon/、src/、assets/ 是否存在。

已经装过想更新:

帮我更新 ai-desk-card。请进入 ~/.claude/skills/ai-desk-card 执行 git pull,然后告诉我当前最新 commit。

装完之后,假设你手上有 M5Paper V1.1 + USB-C 数据线,直接对 Agent 说:

帮我把 ai-desk-card 装上。我手上是 M5Paper V1.1,USB-C 已经插好了。

Skill 会自动:

  1. 探测当前状态(PlatformIO / USB 设备 / daemon / Wi-Fi 配没配)
  2. 缺啥装啥(PlatformIO 没装就 pipx install
  3. 编译 + 烧 CJK 字体 + 烧固件(约 1 分钟)
  4. 启动 daemon
  5. 问你 Wi-Fi 密码 → 自动配上
  6. 推第一个 widget 上去

之后日常使用就是和 Agent 自然对话:

在卡片上显示今天北京的天气。
让卡片每 30 分钟刷新天气和未读邮件,工作日 8 点到 22 点。
现在卡片上是啥?
晚上 11 点之后自动息屏显示我的名片。

效果

  • 🖥 桌面 ambient 副屏:540×960 墨水屏立在显示器旁,瞥一眼就知道今天的状态
  • 🤖 AI 主动推送:Agent 决定推什么 widget、什么时候推;你不用自己开浏览器查天气
  • 📦 16 种 widget:weather / calendar / todo / focus / inbox / pr-queue / ai-status / git-status / now-playing / break-reminder / scratch / messages / deadlines / next-meeting / system / ai-tasks
  • 🎨 服务端渲染:daemon 用 Python + Pillow 渲染像素帧,固件只负责显示;想加新 widget 只改 Python,不用动 C++
  • 🔌 三种供电模式自动切换:USB 常开 / USB 数据线 / 电池 + BLE 待机(几个月续航)
  • 🌐 Wi-Fi LAN 0.2 秒一帧:本地 HTTP 直推,无云依赖
  • 💤 关屏 0 功耗保留最后一帧:墨水屏特性,电池续航 6 个月(架构 C)
  • 👆 底栏触屏 chip:点"睡眠"推电子名片 + 深度休眠;点"设置"翻设置页。150ms 点击态反馈
  • 定时自动息屏:到 quiet hours 自动切到电子名片,daemon 不需要 Agent 在线

适合 / 不适合

✅ 合适

  • 想要 always-on 桌面副屏,但不想再开第二台亮屏显示器
  • 已经在用 Claude Code / Codex / Cursor 等 Agent,想给它一个物理 ambient 输出
  • 喜欢墨水屏低疲劳感(不刺眼、不抢注意力)
  • 接受第一次 ~10 分钟硬件配置(之后 0 维护)

❌ 不合适

  • 需要快速刷新内容(股票实时、视频、动效)— 墨水屏不行
  • 不想买硬件 / 不想烧固件
  • 需要复杂触屏交互(墨水屏触屏可用但慢)

常见使用场景

你说Agent 干什么
"帮我把 ai-desk-card 装上"完整入职流程:探测状态 → 烧固件 → 起 daemon → 配 Wi-Fi
"在卡片上显示今天的天气"推 weather widget
"把日程贴上去"推 calendar widget,自动读 macOS 日历
"显示我现在在做的任务"推 focus widget
"让卡片每 30 分钟刷新"~/.ai-desk-card/interests.yaml + 注册 loop
"23 点自动息屏显示名片"配 quiet_hours,daemon 后台自动处理
"卡片连不上"触发诊断 flow:探测 → 定位问题 → 给修复建议
"我换 Wi-Fi 了"重新走 wifi-setup flow
"卡片现在显示啥"curl daemon 拿当前帧的 PNG 预览

平台支持

平台状态说明
Claude Code✅ 主力测试原生 Skill 工作流 + slash 命令兼容层
Codex CLI🟡 同 SKILL.md 格式应该可用,未深度测试
Gemini CLI🟡 应该可用同上
Cursor🟡 可用需要 shell 权限
Aider🟡 可用同上
自写 Agent只要识别 SKILL.md + 有 shell 权限就行

硬件准备

项目说明
M5Paper V1.1主力支持。约 ¥600 / $90。官方店 / Amazon / AliExpress
M5Paper V1.0大概率可用,电池阈值参数 (4150 mV) 可能要调
M5Paper S3需要 1-2 天移植(BLE stack 不同)
USB-C 数据线烧固件时用一次。普通"只充电"线不行
(可选) USB-C 充电器想用"常插电 + Wi-Fi 常开"模式需要

⚠️ 不需要事先装 PlatformIO / 编译器 / Python 环境 — Skill 检测到缺什么会让 Agent 自己装。

安装

方式一:一行命令(推荐)

npx skills add https://github.com/op7418/ai-desk-card --skill ai-desk-card

方式二:让 AI 帮你装

把下面这段话复制粘贴给 Claude Code / Cursor / 任何有 shell 权限的 AI Agent:

帮我装 ai-desk-card 这个 Skill。请按下面步骤做:

  1. 确保 ~/.claude/skills/ 目录存在(不存在就创建)
  2. 执行 git clone https://github.com/op7418/ai-desk-card.git ~/.claude/skills/ai-desk-card
  3. 验证:ls ~/.claude/skills/ai-desk-card/ 应该看到 SKILL.mdflows/plugin/daemon/src/assets/
  4. 装好告诉我,之后我说"帮我把卡片装上"就会触发这个 Skill

方式三:手动 clone

git clone https://github.com/op7418/ai-desk-card.git ~/.claude/skills/ai-desk-card

触发关键词

装好后 Agent 会在你说这些时自动唤起 Skill:

  • "卡片" / "副屏" / "墨水屏" / "桌面卡片"
  • "把 X 显示在卡片上" / "show X on my card"
  • "刚拿到 M5Paper" / "first-time setup" / "刷固件"
  • "每 N 分钟刷新" / "auto-refresh"
  • "卡片息屏" / "显示名片" / "睡眠"
  • "ai-desk-card"

使用流程

Skill 是结构化工作流,Agent 会按下面顺序自动跑(你不用记每一步):

  1. 入职 (flow 01) — 探测 PlatformIO / USB 设备 → 引导你烧固件
  2. 传输诊断 (flow 02) — 设备连不上时定位问题
  3. 配 Wi-Fi (flow 03) — 把 Wi-Fi 凭证写进设备 NVS
  4. 写偏好 (flow 04) — 第一次问"你想看哪些卡片,多久刷一次"
  5. 推 widget (flow 05) — 日常推送的热路径
  6. 设定时 (flow 06) — Agent 用自己的 loop / cron 定时刷
  7. 息屏 (flow 07) — 推电子名片 + 设备深度休眠 0 功耗

完整子流程在 flows/ 目录。Skill 主路由在 SKILL.md

16 种 Widget

工作日常

  • weather 天气 · calendar 今日日程 · next-meeting 下个会
  • todo 待办 · focus 当前专注任务 · deadlines deadline 提醒
  • inbox 收件箱 · messages 消息 · pr-queue PR 队列
  • git-status git 状态 · system 系统状态 · now-playing 正在播放

笔记 / 节奏

  • scratch 便签 · break-reminder 休息提醒

AI 监控

  • ai-status 当前 AI session · ai-tasks AI 任务列表

4 个槽位 / 2-1-1 布局

┌────────────┬────────────┐
│ top-left   │ top-right  │  ← 270×280 各占半
├────────────┴────────────┤
│         middle          │  ← 540×340 整条
├─────────────────────────┤
│         bottom          │  ← 540×280 整条
├─────────────────────────┤
│  bottom bar (chip 区)   │  ← 60 px,含"睡眠""设置"chip
└─────────────────────────┘

还有一个 full(540×960)覆盖全屏,用来推电子名片 / 启动 splash 等。

完整 schema 在 plugin/skills/card-widget/schemas/

自动刷新(可选)

Skill 第一次问你"想看哪些卡片、什么时段刷"时,会帮你写 ~/.ai-desk-card/interests.yaml

version: 1

slots:
  top-left:  weather
  top-right: calendar
  middle:    todo
  bottom:    inbox

schedule:
  cadence:  "30m"           # 5m / 15m / 30m / 1h / 2h
  hours:    "08-22"
  days:     "mon-fri"
  timezone: "Asia/Shanghai"

data_sources:
  weather:
    city: "Beijing"
  calendar:
    source: "macos"          # 或 google / ics-url
  todo:
    source: "reminders"      # 或 things3 / todoist
  git_status:
    repo: "/Users/you/code/main-project"

# 到 quiet_hours.start 自动切到电子名片 + deep sleep
# daemon 后台自动处理,不需要 Agent 在线
quiet_hours:
  enabled: true
  start:   "23:00"
  end:     "07:00"

定时触发方式:

  • Agent 原生 loop(推荐):Claude Code 的 /loop 30mScheduleWakeup
  • croncrontab -e 加一行 */30 8-21 * * 1-5 bash /path/to/ai-desk-card/plugin/skills/card-refresh/scripts/refresh_loop.sh
  • 纯 Python 无 AI 兜底:weather / system / git 这几个不需要 AI,直接跑 fallback_refresh.py

三种供电模式

模式状态推帧延迟续航
A 常插电USB-C 供电 + Wi-Fi 长开0.2 sn/a(供电中)
B USB onlyUSB 数据线(还没配 Wi-Fi)1 s 区域 / 32 s 全帧n/a(供电中)
C 电池 + BLE 待机Wi-Fi 关,daemon 通过 BLE 唤醒5 s 唤醒 + 0.2 s 推~6 个月

架构 C 是最爱:屏挂在桌边几个月不充电,AI Agent 推内容时 BLE 唤醒一次 → 拉 Wi-Fi → HTTP 推帧 → 30 秒 linger 后断 Wi-Fi。一次推送约 0.2 mAh,24 次/天 × 6 个月 = 1150 mAh 电池。

目录结构

ai-desk-card/
├── SKILL.md                  ← 任意 Agent 的入口
├── scripts/state.sh          ← 状态探测:JSON 输出 daemon/transport/wifi/device/interests 状态
├── flows/                    ← 7 个子流程(每个 ~60-100 行)
│   ├── 01_install.md             零状态硬件 + 固件烧录
│   ├── 02_transport.md           daemon 连不上设备的诊断
│   ├── 03_wifi.md                Wi-Fi 配网
│   ├── 04_interests.md           interests.yaml 引导写入
│   ├── 05_push.md                推 widget 热路径
│   ├── 06_schedule.md            定时刷新协议
│   └── 07_sleep.md               电子名片 + deep sleep
├── plugin/                   ← Claude Code 兼容层(slash 命令 + 共享脚本)
│   ├── plugin.json
│   ├── commands/             ← /card-* 命令
│   ├── scripts/              ← start.sh / stop.sh / status.sh
│   └── skills/               ← 子 skill,由主 SKILL.md 间接调用
├── daemon/
│   ├── card_daemon.py        ← HTTP 桥 + 传输层 + 后台 loop
│   ├── card_render.py        ← widget view 渲染
│   ├── card_render_settings.py
│   └── card_render_sleep.py  ← 电子名片渲染
├── src/                      ← 固件 (frame_receiver / wifi / http / ble / 触屏 poll)
├── assets/
│   ├── profile.yaml          ← 你的电子名片信息(息屏时显示)
│   ├── qr.png                ← 可选 QR
│   └── avatar.png            ← 可选头像
├── data/cjk.ttf              ← CJK 字体(首次烧到 LittleFS)
├── platformio.ini
├── partitions.csv
├── HANDOVER.md               ← 工程交接
└── PRODUCT.md                ← 产品定位

工作原理(一图看懂)

你说话                                        M5Paper
  │                                               ▲
  ▼                                               │
AI Agent ──────┐                                  │
               │ 触发 Skill                        │
               ▼                                  │
          

...

用户评价 (0)

发表评价

效果
易用性
文档
兼容性

暂无评价

统计数据

安装量520
评分4.2 / 5.0
版本
更新日期2026年5月22日
对比案例1 组

用户评分

4.2(120)
5
37%
4
43%
3
13%
2
5%
1
2%

为此 Skill 评分

0.0

兼容平台

🤖claude-code

时间线

创建2026年5月22日
最后更新2026年5月22日