{"id":51324737,"url":"https://github.com/webdevtodayjason/subctl-buddy","last_synced_at":"2026-07-01T17:03:55.048Z","repository":{"id":362620455,"uuid":"1249620591","full_name":"webdevtodayjason/subctl-buddy","owner":"webdevtodayjason","description":"ESP32 desk-side hardware companion for subctl — animated pet + live dashboard for your AI subscription orchestrator. Speaks the claude-desktop-buddy BLE wire protocol.","archived":false,"fork":false,"pushed_at":"2026-05-25T22:29:52.000Z","size":156,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T07:18:49.177Z","etag":null,"topics":["ai-agents","arduino","ble","bluetooth-low-energy","bun","claude","claude-code","esp32","hardware-companion","m5stack","m5stack-cores3","nordic-uart-service","platformio","subctl","typescript"],"latest_commit_sha":null,"homepage":"https://github.com/webdevtodayjason/subctl","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webdevtodayjason.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-25T22:26:24.000Z","updated_at":"2026-05-26T03:12:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/webdevtodayjason/subctl-buddy","commit_stats":null,"previous_names":["webdevtodayjason/subctl-buddy"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/webdevtodayjason/subctl-buddy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webdevtodayjason%2Fsubctl-buddy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webdevtodayjason%2Fsubctl-buddy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webdevtodayjason%2Fsubctl-buddy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webdevtodayjason%2Fsubctl-buddy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webdevtodayjason","download_url":"https://codeload.github.com/webdevtodayjason/subctl-buddy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webdevtodayjason%2Fsubctl-buddy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35015061,"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-07-01T02:00:05.325Z","response_time":130,"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-agents","arduino","ble","bluetooth-low-energy","bun","claude","claude-code","esp32","hardware-companion","m5stack","m5stack-cores3","nordic-uart-service","platformio","subctl","typescript"],"created_at":"2026-07-01T17:03:54.373Z","updated_at":"2026-07-01T17:03:55.043Z","avatar_url":"https://github.com/webdevtodayjason.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 🐸 subctl-buddy\n\n**Your desk-side hardware sidekick for [subctl](https://github.com/webdevtodayjason/subctl) — an M5Stack ESP32 companion that watches your AI subscriptions, mirrors orchestrator state, and answers operator prompts with a button tap.**\n\n![Platform](https://img.shields.io/badge/platform-ESP32-blue?logo=espressif\u0026logoColor=white)\n![Hardware](https://img.shields.io/badge/hardware-M5Stack%20CoreS3%20%2F%20StickC%20Plus-orange)\n![Bridge](https://img.shields.io/badge/bridge-Bun%20%2B%20TypeScript-black?logo=bun\u0026logoColor=white)\n![Transport](https://img.shields.io/badge/transport-BLE%20NUS-5E5DF0?logo=bluetooth\u0026logoColor=white)\n![Status](https://img.shields.io/badge/status-Phase%202%20shipped-success)\n![License](https://img.shields.io/badge/license-MIT-lightgrey)\n\n\u003c/div\u003e\n\n---\n\n## What is this?\n\nA tiny ESP32 device that sits on your desk and **mirrors the state of [subctl](https://github.com/webdevtodayjason/subctl)** — Jason Brashear's multi-account AI subscription orchestrator — in real time. Instead of context-switching to Telegram or a terminal to see what your fleet of Claude/Codex/etc. agents are up to, you glance at the buddy:\n\n- 🐸 **Animated pet** on the left (bufo GIF or one of 18 ASCII species) that levels up from real output-token throughput\n- 💬 **Thought-bubble dashboard** on the right with dispatch verdict, per-account chips, active conversation summary, and cost-saved-this-month\n- 🔘 **Button taps** answer operator yes/no prompts — APPROVE / DENY without opening Telegram\n- ⚙️ **Settings menu** for brightness, sound, demo mode, and device info\n- 🔄 **launchd-supervised** bridge daemon: power-cycle the device and it auto-reconnects in \u003c1s\n\n## Hardware\n\n| Device | Firmware | Status |\n|---|---|---|\n| **M5Stack CoreS3** | `firmware-cores3/` v0.2.0 | Primary target — full-color GIF pet, dashboard, settings menu |\n| **M5StickC Plus** | `firmware/` v0.1.x | Bare dashboard only, forward-compatible with the v0.2 bridge |\n\nBoth speak the **same Nordic UART Service JSON wire protocol** as Anthropic's [`claude-desktop-buddy`](https://github.com/anthropics/claude-desktop-buddy) — the project that inspired this one. The bridge daemon translates subctl's state into that protocol and routes button taps back to subctl's notification inbox.\n\n## Architecture\n\n```\n┌─────────────────┐     BLE NUS JSON      ┌──────────────────────┐\n│  M5Stack CoreS3 │  ◀──────────────────▶ │ bridge/ (Bun+noble)  │\n│  - pet + dash   │                       │ - subctl state poll  │\n│  - btn taps     │                       │ - launchd supervised │\n└─────────────────┘                       └──────────┬───────────┘\n                                                     │\n                                                     ▼\n                                            ┌────────────────┐\n                                            │     subctl     │\n                                            │ (tmux orch +   │\n                                            │  rate-limit +  │\n                                            │  ask inbox)    │\n                                            └────────────────┘\n```\n\n## Repo layout\n\n```\nbridge/             Bun + noble BLE central daemon (TypeScript)\nfirmware/           M5StickC Plus firmware (v0.1.x, Arduino/PlatformIO)\nfirmware-cores3/    M5Stack CoreS3 firmware (v0.2.0, full-color UI)\ndocs/               Design doc, integration notes, BLE investigation log\nHANDOFF.md          Latest session state — read this first\n```\n\n## Status\n\n**Phase 2 shipped (2026-05-24/25).** CoreS3 runs the v0.2.0 firmware with animated pet, live dashboard, settings menu, buddy profile overlay, and a level-up loop wired to real output-token counts. Bridge daemon runs under launchd with KeepAlive + continuous BLE scan — device off/on auto-reconnects in \u003c1s once the first-run BT permission is granted.\n\n**Blocked on subctl-side surface:** the operator-prompt path (buddy receives a question, taps APPROVE/DENY, reply lands in subctl). Firmware is wired; waiting on `/api/asks/pending` from the subctl maintainer. See `docs/handoff-subctl-surface.md`.\n\n## Quick start\n\n```bash\n# One-time install of the launchd-supervised daemon\n# (auto-opens System Settings → Bluetooth for the one-time TCC grant):\nbridge/src/cli.ts install --device subctl-E4C1\n\n# OR run manually:\ncd bridge \u0026\u0026 bun run src/cli.ts daemon --device subctl-E4C1\n```\n\nIf `subctl-buddy` resolves globally (wrapper at `~/.bun/bin/subctl-buddy`), just `subctl-buddy install`.\n\n## Read this next\n\n- [`HANDOFF.md`](./HANDOFF.md) — full state-of-the-world, \"where are we, what's next\"\n- [`docs/design.md`](./docs/design.md) — original architecture sketch\n- [`docs/handoff-subctl-surface.md`](./docs/handoff-subctl-surface.md) — what we need from the subctl maintainer to unblock the operator-prompt path\n\n## Credits\n\nBuilt by **[Jason Brashear](https://jasonbrashear.com)** ([@webdevtodayjason](https://github.com/webdevtodayjason)) as part of the [subctl](https://github.com/webdevtodayjason/subctl) ecosystem.\n\nInspired by Anthropic's [**claude-desktop-buddy**](https://github.com/anthropics/claude-desktop-buddy) — the reference Bluetooth API for makers building hardware companions for Claude. subctl-buddy speaks the same wire protocol so any firmware built for claude-desktop-buddy will also light up when paired with the subctl-buddy bridge.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebdevtodayjason%2Fsubctl-buddy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebdevtodayjason%2Fsubctl-buddy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebdevtodayjason%2Fsubctl-buddy/lists"}