{"id":50953495,"url":"https://github.com/op7418/ai-desk-card","last_synced_at":"2026-06-18T04:01:32.612Z","repository":{"id":359556364,"uuid":"1245797515","full_name":"op7418/ai-desk-card","owner":"op7418","description":"桌面 AI 副屏 Skill：M5Paper 墨水屏 + AI Agent 推送 widget。装 Skill 后由 Agent 自动引导烧固件、配 Wi-Fi、推送内容。本地运行、无云依赖。","archived":false,"fork":false,"pushed_at":"2026-05-22T17:13:59.000Z","size":2487,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T17:36:10.939Z","etag":null,"topics":["ai-agent","ai-skill","ambient-display","claude-code","codex","dashboard","desk-card","e-ink","esp32","glanceable-display","m5paper","secondary-display","skill","skills"],"latest_commit_sha":null,"homepage":"https://github.com/op7418/ai-desk-card","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/op7418.png","metadata":{"files":{"readme":"README.en.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-21T15:07:07.000Z","updated_at":"2026-05-22T17:30:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/op7418/ai-desk-card","commit_stats":null,"previous_names":["op7418/ai-desk-card"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/op7418/ai-desk-card","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/op7418%2Fai-desk-card","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/op7418%2Fai-desk-card/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/op7418%2Fai-desk-card/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/op7418%2Fai-desk-card/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/op7418","download_url":"https://codeload.github.com/op7418/ai-desk-card/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/op7418%2Fai-desk-card/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34475375,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","ai-skill","ambient-display","claude-code","codex","dashboard","desk-card","e-ink","esp32","glanceable-display","m5paper","secondary-display","skill","skills"],"created_at":"2026-06-18T04:01:27.967Z","updated_at":"2026-06-18T04:01:32.603Z","avatar_url":"https://github.com/op7418.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AI Desk Card · An AI-Driven Desk Companion Skill\n\n![GitHub stars](https://img.shields.io/github/stars/op7418/ai-desk-card?style=flat-square)\n![License](https://img.shields.io/github/license/op7418/ai-desk-card?style=flat-square)\n![Skill](https://img.shields.io/badge/Skill-Agent-111111?style=flat-square)\n![M5Paper](https://img.shields.io/badge/M5Paper-V1.1-0A7CFF?style=flat-square)\n![Claude Code](https://img.shields.io/badge/Claude%20Code-Supported-6B5B95?style=flat-square)\n![Codex](https://img.shields.io/badge/Codex-Supported-222222?style=flat-square)\n\n\u003e 🇨🇳 **中文版（主文档）: [README.md](./README.md)**\n\nA Skill that turns an [M5Paper V1.1](https://docs.m5stack.com/en/core/m5paper)\ne-ink panel into a desk companion driven by an AI agent (Claude Code,\nCodex, Cursor, etc.). The agent decides what to push: weather, calendar,\ntodos, PR queue, AI session status, break reminders…\n\n**Once you install the Skill, the agent walks you through firmware\nflashing, Wi-Fi provisioning, and daily widget pushes** — you don't run\na single `pio` or `curl` command by hand.\n\n![AI Desk Card hero](https://github.com/user-attachments/assets/b4777ba7-d668-42c1-9920-3e6d8bef534e)\n\n```\nYou ──ask naturally──▶ AI Agent ──triggers──▶ Skill ──auto-runs──▶ M5Paper\n```\n\n## 30 seconds to start\n\n```bash\nnpx skills add https://github.com/op7418/ai-desk-card --skill ai-desk-card\n```\n\nOr paste this to any AI Agent with shell access:\n\n```text\nInstall the ai-desk-card Skill. Clone https://github.com/op7418/ai-desk-card\ninto ~/.claude/skills/ai-desk-card. After install, verify SKILL.md, flows/,\ndaemon/, src/, assets/ all exist.\n```\n\nTo update an existing install:\n\n```text\nUpdate ai-desk-card. cd into ~/.claude/skills/ai-desk-card, git pull, and\ntell me the latest commit.\n```\n\nThen assuming you have an M5Paper V1.1 and a USB-C data cable, just say:\n\n```text\nHelp me set up ai-desk-card. I have an M5Paper V1.1 plugged in over USB-C.\n```\n\nThe Skill will automatically:\n\n1. Probe current state (PlatformIO, USB device, daemon, Wi-Fi)\n2. Install what's missing (`pipx install platformio` if needed)\n3. Compile + flash CJK font + flash firmware (~1 minute)\n4. Start the daemon\n5. Ask for your Wi-Fi password → provision\n6. Push the first widget\n\nAfter that, daily use is a natural conversation:\n\n```text\nShow today's Beijing weather on my card.\nRefresh weather and unread mail every 30 min on workday 8am-10pm.\nWhat's on my card right now?\nAuto-sleep at 11pm and show my business card.\n```\n\n## What you get\n\n- 🖥 **Ambient desk display**: a 540×960 e-ink panel sits next to your monitor — glance, don't context-switch\n- 🤖 **AI-pushed content**: the agent decides what widget to send and when; you don't open a browser for weather\n- 📦 **16 widget types**: weather / calendar / todo / focus / inbox / pr-queue / ai-status / git-status / now-playing / break-reminder / scratch / messages / deadlines / next-meeting / system / ai-tasks\n- 🎨 **Server-side render**: daemon uses Python + Pillow; want a new widget? Edit Python, no C++\n- 🔌 **Three power modes auto-switch**: USB-powered / USB-data-only / battery + BLE standby (months of life)\n- 🌐 **Wi-Fi LAN, 0.2 s per frame**: local HTTP, no cloud\n- 💤 **Sleep at zero watts, last frame retained**: e-ink physics; ~6 months on a charge in arch C\n- 👆 **Tappable bottom-bar chips**: \"Sleep\" → push business card + deep sleep; \"Settings\" → settings page. 150 ms tap-ack flash\n- ⏰ **Auto-sleep at quiet hours**: daemon flips to business card without needing the agent online\n\n## When it fits / when it doesn't\n\n**✅ Good fit if**:\n\n- You want an always-on side display but don't want another bright monitor\n- You already use Claude Code / Codex / Cursor and want an ambient physical output\n- You like e-ink's low-strain feel (not glaring, not distracting)\n- You accept a ~10 min one-time hardware setup (then zero maintenance)\n\n**❌ Not a fit if**:\n\n- You need fast-refresh content (stock tickers, video, animation) — e-ink can't\n- You don't want to buy hardware or flash firmware\n- You need rich touch interaction (touch works but e-ink is slow)\n\n## Common scenarios\n\n| You say | Agent does |\n|------|------|\n| \"Help me set up ai-desk-card\" | Full onboarding: probe → flash firmware → start daemon → provision Wi-Fi |\n| \"Show today's weather on my card\" | Push weather widget |\n| \"Put my schedule on it\" | Push calendar widget, auto-read macOS Calendar |\n| \"Show what I'm working on\" | Push focus widget |\n| \"Refresh every 30 min\" | Write `~/.ai-desk-card/interests.yaml` + register loop |\n| \"Auto-sleep at 11pm with my business card\" | Configure quiet_hours, daemon handles it |\n| \"Card won't connect\" | Run diagnostic flow → locate issue → suggest fix |\n| \"I changed Wi-Fi\" | Run wifi-setup flow |\n| \"What's on my card now?\" | curl the daemon for a current-frame PNG preview |\n\n## Platform support\n\n| Agent | Status | Notes |\n|------|------|------|\n| Claude Code | ✅ Primary | Native Skill + slash command convenience layer |\n| Codex CLI | 🟡 Same SKILL.md format | Should work, not deeply tested |\n| Gemini CLI | 🟡 Should work | Same |\n| Cursor | 🟡 Works | Needs shell permission |\n| Aider | 🟡 Works | Same |\n| Self-built agent | ✅ | Any agent that recognizes SKILL.md + has shell access |\n\n## Hardware you need\n\n| Item | Notes |\n|------|------|\n| **M5Paper V1.1** | Primary target. ~¥600 / $90. [Official store](https://shop.m5stack.com/products/m5paper-v1-1) / Amazon / AliExpress |\n| M5Paper V1.0 | Likely works, battery threshold (`4150 mV`) may need tuning |\n| M5Paper S3 | Needs porting (1-2 days, BLE stack differs) |\n| USB-C **data cable** | Used once for flashing. Charge-only cables don't work |\n| (optional) USB-C charger | Needed for always-on Wi-Fi mode |\n\n\u003e ⚠️ **You don't need to pre-install PlatformIO / compilers / Python** — if the Skill detects something missing, it lets the agent install it.\n\n## Install\n\n### Option 1: One-line install (recommended)\n\n```bash\nnpx skills add https://github.com/op7418/ai-desk-card --skill ai-desk-card\n```\n\n### Option 2: Ask the AI to install\n\nCopy this and paste to Claude Code / Cursor / any AI Agent with shell access:\n\n\u003e Install the `ai-desk-card` Skill. Steps:\n\u003e\n\u003e 1. Ensure `~/.claude/skills/` exists (create if not)\n\u003e 2. Run `git clone https://github.com/op7418/ai-desk-card.git ~/.claude/skills/ai-desk-card`\n\u003e 3. Verify: `ls ~/.claude/skills/ai-desk-card/` should show `SKILL.md`, `flows/`, `plugin/`, `daemon/`, `src/`, `assets/`\n\u003e 4. Tell me when done; from then on saying \"set up the card\" will trigger this Skill\n\n### Option 3: Manual clone\n\n```bash\ngit clone https://github.com/op7418/ai-desk-card.git ~/.claude/skills/ai-desk-card\n```\n\n### Trigger keywords\n\nAfter install, the agent auto-triggers the Skill when you mention any of:\n\n- \"card\" / \"desk card\" / \"e-ink display\" / \"secondary display\"\n- \"show X on my card\"\n- \"just got an M5Paper\" / \"first-time setup\" / \"flash firmware\"\n- \"refresh every N min\" / \"auto-refresh\"\n- \"sleep the card\" / \"show business card\"\n- \"ai-desk-card\"\n\n## How it works\n\nThe Skill is a structured workflow; the agent steps through it automatically:\n\n1. **Onboarding (flow 01)** — probe PlatformIO + USB → walk through firmware flash\n2. **Transport diagnosis (flow 02)** — locate issues when device is unreachable\n3. **Wi-Fi setup (flow 03)** — provision credentials into device NVS\n4. **Interests (flow 04)** — first-time \"what do you want to see, how often\"\n5. **Push widget (flow 05)** — daily hot path\n6. **Schedule (flow 06)** — agent's own loop / cron registration\n7. **Sleep (flow 07)** — business card + deep sleep at zero watts\n\nFull sub-flows live in [`flows/`](./flows/). Main routing in [`SKILL.md`](./SKILL.md).\n\n## 16 widget types\n\n**Work staples**:\n- `weather` · `calendar` · `next-meeting`\n- `todo` · `focus` · `deadlines`\n- `inbox` · `messages` · `pr-queue`\n- `git-status` · `system` · `now-playing`\n\n**Notes / pacing**:\n- `scratch` · `break-reminder`\n\n**AI monitoring**:\n- `ai-status` · `ai-tasks`\n\n**4 slots / 2-1-1 layout**:\n\n```\n┌────────────┬────────────┐\n│ top-left   │ top-right  │  ← 270×280 each\n├────────────┴────────────┤\n│         middle          │  ← 540×340 full-width\n├─────────────────────────┤\n│         bottom          │  ← 540×280 full-width\n├─────────────────────────┤\n│  bottom bar (chips)     │  ← 60 px, \"Sleep\" + \"Settings\"\n└─────────────────────────┘\n```\n\nPlus `full` (540×960) which takes over the whole screen — used for the business card / boot splash.\n\nFull schema in [`plugin/skills/card-widget/schemas/`](./plugin/skills/card-widget/schemas/).\n\n## Auto-refresh (optional)\n\nWhen the Skill first asks \"which widgets do you want, how often\", it writes `~/.ai-desk-card/interests.yaml`:\n\n```yaml\nversion: 1\n\nslots:\n  top-left:  weather\n  top-right: calendar\n  middle:    todo\n  bottom:    inbox\n\nschedule:\n  cadence:  \"30m\"           # 5m / 15m / 30m / 1h / 2h\n  hours:    \"08-22\"\n  days:     \"mon-fri\"\n  timezone: \"Asia/Shanghai\"\n\ndata_sources:\n  weather:\n    city: \"Beijing\"\n  calendar:\n    source: \"macos\"          # or google / ics-url\n  todo:\n    source: \"reminders\"      # or things3 / todoist\n  git_status:\n    repo: \"/Users/you/code/main-project\"\n\n# At quiet_hours.start, switch to business card + deep sleep.\n# Daemon handles this in the background — agent doesn't have to be online.\nquiet_hours:\n  enabled: true\n  start:   \"23:00\"\n  end:     \"07:00\"\n```\n\nThree ways to trigger the refresh:\n\n- **Agent's native loop (recommended)**: Claude Code's `/loop 30m`, `ScheduleWakeup`, etc.\n- **cron**: `crontab -e` line: `*/30 8-21 * * 1-5 bash /path/to/ai-desk-card/plugin/skills/card-refresh/scripts/refresh_loop.sh`\n- **No-AI fallback**: weather / system / git don't need AI — run `fallback_refresh.py` directly\n\n## Three power-mode architectures\n\n| Mode | State | Push latency | Battery |\n|------|------|---------|------|\n| **A** Always plugged | USB-C power + Wi-Fi always on | 0.2 s | n/a (powered) |\n| **B** USB only | USB data cable (no Wi-Fi yet) | 1 s region / 32 s full | n/a (powered) |\n| **C** Battery + BLE standby | Wi-Fi off, daemon wakes via BLE | 5 s wake + 0.2 s push | ~6 months |\n\nArch C is the favorite: the panel sits on your desk for months without charging; when the agent has something to push, BLE wake → bring up Wi-Fi → HTTP push → 30 s linger → drop Wi-Fi. ~0.2 mAh per push × 24 pushes/day × 6 months = 1150 mAh battery.\n\n## Directory structure\n\n```\nai-desk-card/\n├── SKILL.md                  ← Agent entry point (any-agent)\n├── scripts/state.sh          ← State probe — JSON: daemon / transport / wifi / device / interests\n├── flows/                    ← 7 sub-flows (~60-100 lines each)\n│   ├── 01_install.md             Zero-state hardware + firmware flash\n│   ├── 02_transport.md           Daemon-can't-reach-device diagnostic\n│   ├── 03_wifi.md                Wi-Fi provisioning\n│   ├── 04_interests.md           interests.yaml guided setup\n│   ├── 05_push.md                Widget push hot path\n│   ├── 06_schedule.md            Scheduled-push protocol\n│   └── 07_sleep.md               Business card + deep sleep\n├── plugin/                   ← Claude Code convenience layer (slash + shared scripts)\n│   ├── plugin.json\n│   ├── commands/             ← /card-* commands\n│   ├── scripts/              ← start.sh / stop.sh / status.sh\n│   └── skills/               ← Sub-skills, called indirectly by main SKILL.md\n├── daemon/\n│   ├── card_daemon.py        ← HTTP bridge + transport layer + background loops\n│   ├── card_render.py        ← Widget view renderer\n│   ├── card_render_settings.py\n│   └── card_render_sleep.py  ← Business card renderer\n├── src/                      ← Firmware (frame_receiver / wifi / http / ble / touch poll)\n├── assets/\n│   ├── profile.yaml          ← Your business-card info (shown when sleeping)\n│   ├── qr.png                ← Optional QR\n│   └── avatar.png            ← Optional avatar\n├── data/cjk.ttf              ← CJK font (flashed to LittleFS once)\n├── platformio.ini\n├── partitions.csv\n├── HANDOVER.md               ← Engineering handover\n└── PRODUCT.md                ← Product narrative\n```\n\n## How it really works (one diagram)\n\n```\nYou speak                                      M5Paper\n  │                                               ▲\n  ▼                                               │\nAI Agent ──────┐                                  │\n               │ triggers Skill                   │\n               ▼                                  │\n          SKILL.md routing                        │\n               │                                  │\n               │  scripts/state.sh probes:        │\n               │  · pio / firmware / daemon       │\n               │  · device.alive / wifi           │\n               │  · interests.yaml                │\n               │                                  │\n               └─▶ picks one of 7 sub-flows       │\n                       │                          │\n                       ▼                          │\n                  Agent executes                  │\n                       │                          │\n                       ▼                          │\n              POST to daemon (127.0.0.1:9877)     │\n                       │                          │\n                       ▼                          │\n              daemon renders (Python + Pillow)    │\n                       │                          │\n                       ▼                          │\n              HTTP / USB / BLE push ──────────────┘\n```\n\n## FAQ\n\n**Q: I really don't need to flash firmware myself?**\nNo. After install, just say \"set up the card\" — the agent probes state, installs PlatformIO (if missing), runs `pio run -t upload`, flashes the CJK font, and tells you what it's doing at each step.\n\n**Q: I don't have M5Paper V1.1 — anything else?**\nM5Paper V1.0 likely works. M5Paper S3 needs porting (BLE stack differs). Inkplate / Waveshare / etc. aren't supported yet — roadmap item.\n\n**Q: Do I have to use Claude Code?**\nNo. `SKILL.md` is agent-agnostic — any agent that recognizes the format + has shell permission works (Codex / Cursor / Aider / self-built). The `plugin/` slash commands are a Claude Code convenience layer, not the core.\n\n**Q: What about network?**\nAll local. Daemon runs on your machine (127.0.0.1:9877). Device and computer are on the same Wi-Fi LAN. **ESP32 only supports 2.4 GHz** — 5 GHz-only SSIDs won't connect.\n\n**Q: Chinese characters show as tofu boxes?**\nYou skipped the LittleFS font flash. Ask the agent to \"run uploadfs again\".\n\n**Q: How do I update the firmware?**\nSay \"update ai-desk-card and re-flash\". The Skill pulls new code + builds + uploads.\n\n**Q: Does it work outside macOS?**\nDaemon should work on Linux (not deeply tested). Windows needs WSL2. PlatformIO is cross-platform.\n\n**Q: Does any data go to the cloud?**\nNo. Daemon binds 127.0.0.1 by default (device→daemon status_report goes over LAN). Wi-Fi credentials live in device NVS, never in daemon logs or git.\n\n## Roadmap\n\n- M5Paper V1.0 / S3 port verification\n- Inkplate / Waveshare / other e-ink board support\n- Captive portal Wi-Fi provisioning (no daemon needed)\n- Hardware power-button intercept (long-press 2s → render business card before deep sleep)\n- More widget schemas (Feishu / WeChat / Linear / Notion)\n- Multi-device dashboard sync\n\n## Contributing\n\nIssues and PRs welcome at https://github.com/op7418/ai-desk-card.\n\nMost valuable contributions:\n\n- Hardware photos / videos (helps new users see the form factor)\n- Linux / Windows daemon testing reports\n- M5Paper V1.0 / S3 firmware port verification\n- New widget schemas + renderers\n- Translation / docs improvements\n\n## License\n\nGPL-3.0 with attribution clause · see [LICENSE](./LICENSE)\n\nVendored EPDGUI framework (from upstream M5Paper_FactoryTest): MIT, © 2020 m5stack.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fop7418%2Fai-desk-card","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fop7418%2Fai-desk-card","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fop7418%2Fai-desk-card/lists"}