AgentDeck · Dashboard Surfaces

지원 Dashboard 하드웨어 / OS 사양

daemon hub(port 9120)에 붙어 에이전트 상태를 보여주거나 제어하는 모든 surface — 하드웨어 디스플레이/입력 디바이스 11종 + 소프트웨어 플랫폼(Apple 3 · Android 다수) + 터미널 TUI = 14 surface. 동시 구동 가능.

Host: App Store dashboard macOS 26+ · Node bridge macOS 15+ (Sequoia) · Node.js ≥ 22 · iTerm2 — Windows/Linux 미지원

SSOT: docs/hardware-compatibility.md · 전송 매트릭스: docs/devices.md · 기능 tier: appstore-feature-matrix.md

종합 매트릭스

Surface종류SoC · 플랫폼디스플레이 / 해상도 전송연결성App Store
IPS 3.5"ESP32 FWESP32-S3AXS15231B IPS · 480×320USB Serial / WiFi WSUSB-Serial + WiFiYES
Round AMOLED 1.8"ESP32 FWESP32-S3ST77916 AMOLED · 360×360USB Serial / WiFi WSUSB-Serial + WiFiYES
86 Box 4"ESP32 FWESP32-S3ST7701 IPS · 480×480USB Serial / WiFi WSUSB-Serial + WiFiYES
TTGO T-Display 1.14"ESP32 FWESP32 (classic)ST7789 TFT · 135×240USB Serial / WiFi WSUSB-Serial + WiFiYES
ESP32-C6 1.47"ESP32 FWESP32-C6 (RISC-V)ST7789 TFT · 172×320USB Serial / WiFi WSUSB-CDC + WiFiYES
IPS 10.1"ESP32 FWESP32-P4 + C6JD9365 IPS MIPI-DSI · 800×1280USB Serial / WiFi WSUSB-Serial + WiFiYES
XTeink X3ESP32 FWESP32-C3e-ink · 528×792 (3.7")WiFi WS (계획)WiFiEXP7
Divoom Pixoo64상용 LEDDivoom (비-ESP32)RGB LED · 64×64HTTP REST :80WiFiYES
InkDeck e-inkESP32 FWXIAO ESP32-S3 Pluse-ink · 800×480 (Seeed OG, UC8179)WiFi WS (계획)WiFiEXP4
iDotMatrix 32×32상용 BLEBLE SoC (비-ESP32)RGB AMOLED · 32×32BLE GATTBluetooth LEYES
Divoom Timebox Mini상용 BLEBLE SoC (비-ESP32)RGB LED · 11×11BLE GATT (ISSC)Bluetooth LEYES
Ulanzi TC001ESP32 FWESP32 (classic)WS2812B · 8×32 (256 LED)USB Serial / WiFi WSUSB-Serial + WiFiGAP1
Ulanzi D200HHID deckSigmaStar SSD210nv3052c LCD · 960×540 (14 keys)Ulanzi Studio 플러그인 (단일 드라이버; direct-HID retire)USBYES
Elgato Stream Deck (15-key)HID deckElgato (내장)LCD keys 15 (5×3)WebSocket :9120USB → 네트워크YES3
Elgato Stream Deck+HID deckElgato (내장)LCD keys 8 (4×2) + dials 4 + touch stripWebSocket :9120USB → 네트워크YES3
Apple — macOSSWApple Silicon / Intel호스트 디스플레이내장 Swift daemon / WSYES
Apple — iOS / iPadOSSWA / M-series디바이스 디스플레이WebSocket :9120WiFi (same-LAN)YES
Android — e-inkSW벤더별 (RK3566 등)e-ink 디스플레이WebSocket (ADB localhost)USB / ADBCLI2
Android — 태블릿SWARM / x86컬러 LCDWebSocket + mDNSWiFi (same-LAN)LAN2
SSE 스트림프로토콜호스트브라우저 / 스크립트HTTP SSE :9120 /sse로컬 / LANYES*
TUI Dashboard터미널호스트 CPU터미널 (truecolor)WebSocket :9120로컬YES

1 GAP = TC001 ⚠는 샌드박스 제약이 아니라 구현 갭. 다른 ESP32 보드와 동일한 serial/WiFi state-JSON으로 자기 UI를 렌더하며 serial entitlement로 이미 커버됨(테스트가 serial board로 보고). Swift 데몬에 led8x32 경로 미검증이라 CLI-tier. 과거 "ADB" 표기는 legacy/dead code 였고 2026-06-25 제거됨AdbDeviceClass.ulanziTc001 와이어 클래스 producer가 없어 ADB 분기는 죽어 있었고 라이브 경로는 serial. AdbModule.classifyDevice 분기·enum 케이스·UI 룩업 모두 삭제(라이브 row는 USB-serial 섹션). 남은 ⚠는 Swift led8x32 경로 HW 검증만 후속 — 검증 후 ✅ 승격 가능. 2 Android 앱은 mDNS LAN(iOS와 동일) + ADB localhost 양쪽 지원. USB-테더 e-ink는 Mac 앱이 adb reverse를 못 띄워 CLI 전용(진짜 제약). 같은 LAN의 태블릿은 mDNS로 App Store Mac 데몬에 직접 접속 가능(LAN). 3 Elgato Stream Deck 앱 별도 설치(플러그인 호스트). 표준 15키(agentdeck-sd, DeviceType 0)·SD+(agentdeck-sdplus, DeviceType 7)는 동일 플러그인의 두 프로파일이며 mini(1)·XL(2)도 familyForDeviceType()로 그리드 자동 산출. · 포트는 가변 — ESP32는 device_info_request로 식별.
* SSE 풀 스트리밍은 Node 브리지(bridge/src/hook-server.ts, broadcastSse) 한정. App Store macOS Swift 데몬(DaemonServer.swift)의 /sseevent: connected 1회 후 끊는 스텁이라 스트리밍 안 함 — App Store 빌드의 라이브 SSE 대시보드는 외부(Node) 데몬 필요. 실 소비자는 리포 내 /status·/pixoo HTML 대시보드(인라인 EventSource).
4 InkDeck = experimental(펌웨어 개발 중): 하드웨어는 Seeed TRMNL 7.5" OG DIY Kit — XIAO ESP32-S3 Plus + 800×480 monochrome e-ink(GDEY075T7 / UC8179), 상시 USB 급전. 커스텀 AgentDeck ESP32 펌웨어(esp32/ PlatformIO env inkdeck, 개발 중)로 재플래시해 다른 ESP32 보드처럼 WiFi WS로 데몬에 붙고 데몬이 1-bit 대시보드 프레임을 push, 패널은 부분 리프레시(~0.3s) + 주기적 full refresh로 렌더. 아직 device_info/WS 미발신 → 대시보드 미표시. 전송은 다른 ESP32와 동일한 WiFi WS(서브프로세스 없음)라 샌드박스 제약 아님 — 펌웨어가 WS 발신 시작하면 ✅ 승격 가능. 구 "TRMNL" 상용 BYOS pull 통합(Node bridge/src/trmnl/ + Swift Trmnl* 모듈)은 제거됨(Node commit c71044bd) → 순정 TRMNL 패널 미지원.
7 XTeink X3 = experimental: ESP32-C3 e-ink 포켓 리더로, AgentDeck 펌웨어가 아니라 오픈소스 CrossPoint Reader 포크(crosspoint-agentdeck, branch agentdeck-decision-card)로 "Decision Card" 펌웨어 개발 중. 아직 device_info/WS 미발신 → 대시보드 미표시. 전송은 다른 ESP32와 동일한 WiFi WS(서브프로세스 없음)라 샌드박스 제약 아님. 소유 유닛은 pogo USB-data 패드 사망 → SD update.bin 플래시만 가능, AgentDeck esp32/에 board def 없음. 펌웨어가 WS/device_info 발신 시작하면 ✅ 승격 가능(현재 not-yet-shipping).

A. ESP32 펌웨어 디스플레이 보드

공통: PlatformIO + Arduino, LVGL 9.2.0(TC001·XTeink X3 제외), 115200 baud, flash mode DIO, 이중 경로(USB Serial 기본 + WiFi WebSocket 독립). 출처: esp32/platformio.ini · esp32/boards/board_*.h.

env 이름 두 층: friendly명esp32/scripts/flash.sh가 받는 canonical 친근명(panel/form + 인치: 3.5→35·1.8→18·1.14→114·1.47→147·10.1→101)이고, pio envplatformio.ini의 실제 [env:...](불변). flash.sh가 친근명→pio로 매핑하며 legacy 별칭(round_amoled·ttgo·ips10 등)도 계속 받는다. CI/pio run -e는 pio env 사용.

보드friendly명pio env모델 (제조사)SoC해상도디스플레이 IC터치 ICFlashPSRAMUSB-UART
IPS 3.5"ips_35ips35JC3248W535 (Guition)ESP32-S3480×320AXS15231B (QSPI)통합16MBYESNative USB JTAG
Round AMOLED 1.8"amoled_18amoledJC3636W518 (Guition)ESP32-S3360×360ST77916 (QSPI)CST816S (I2C)8MBYESNative USB JTAG
86 Box 4"box_40box_866ESP32-S3-4848S040 (Guition)ESP32-S3480×480ST7701 (RGB 16-bit)GT911 (I2C)16MBYESCH340
TTGO T-Display 1.14"tft_114ttgoLilyGO T-DisplayESP32-D0WDQ6135×240ST7789 (SPI)없음 (버튼 2)16MBNOCH3404
ESP32-C6 1.47"c6_147esp32_c6_147Waveshare ESP32-C6-LCD-1.47"ESP32-C6172×320ST7789 (SPI)없음 (BOOT)4MBNONative USB CDC
IPS 10.1"ips_101ips10JC8012P4A1C (Guition)ESP32-P4NRW32 (400MHz)800×1280JD9365 (MIPI-DSI)GSL3680 (I2C)4MB532MBCH340
XTeink X37XTeink X3 (XTeink)ESP32-C3528×792e-ink EPD (미확정)없음4MBNOpogo USB (데이터 사망)

4 TTGO 플래시는 57600 baud + --no-stub(~5분). PSRAM 없는 classic이라 정적 DRAM ~10KB → 테라리움 축소 버퍼. 5 P4NRW32 모듈은 16MB Flash + 32MB PSRAM 통합이나 빌드는 4MB 파티션. WiFi는 co-processor ESP32-C6-MINI-1U-N4(esp-hosted), TX 20dBm. 6 box_86의 legacy 중복 env rgb48platformio.inidefault_envs(같은 box_86.csv 파티션, platform source만 다른 near-dup). 친근명 정리 범위에서 pio env는 유지 — pio run 무인자 빌드 시 rgb48 선택됨에 주의. 7 XTeink X3 = experimental. AgentDeck esp32/ 펌웨어 아님 — 오픈소스 CrossPoint Reader 포크(crosspoint-agentdeck, branch agentdeck-decision-card)로 "Decision Card" 펌웨어 개발 중이라 friendly명/pio env 없음, LVGL 미사용(CrossPoint GfxRenderer). 전송 WiFi WS(계획). 소유 유닛은 USB-data 패드 사망 → SD update.bin만. 종합 매트릭스 각주7 참조.

B. LED 매트릭스 디바이스

Divoom Pixoo64

상용 LED 액자 · 비-ESP32

해상도64×64 RGB
전송HTTP REST :80
연결WiFi 2.4G
드라이버pixoo/ · Swift
특이PicID 단조증가

iDotMatrix 32×32

상용 BLE 픽셀 · BLE SoC

해상도32×32 AMOLED
전송BLE GATT
연결Bluetooth LE
드라이버sync.py · CoreBT
특이USB=전원전용

Divoom Timebox Mini

상용 BLE 픽셀 · BLE SoC

해상도11×11 RGB
전송BLE GATT (ISSC)
연결Bluetooth LE
드라이버TimeboxBLE.swift · sync_ble.py
특이BLE 단일연결

Ulanzi TC001

ESP32 펌웨어 · env led8x32

해상도8×32 (256 LED)
SoCESP32 D0WD
렌더FastLED 3.7
Flash8MB · no PSRAM
App Store⚠ 구현 갭(각주3)

C. 입력 / 제어 하드웨어 (HID 데크)

Ulanzi D200H "Deck Dock"

stock HID 프로토콜(ADB/펌웨어 변조 없음), daemon-only. Ulanzi Studio 플러그인(plugin-ulanzi)이 유일한 지원 드라이버 — D200H 는 Mac Ulanzi Studio 앱을 통해야만 안정 렌더. direct-HID 폴백은 retire(2026-06-21, 380c6510): 두 데몬 모두 더 이상 HID 로 열지 않음(Node d200h: false / Swift enableD200hDirectHID = false). 모듈 코드와 stand-down arbitration 은 dormant(보존·재활성 가능)하나 비활성. 출처: docs/plugin-conventions.md §D200H, 커밋 380c6510.

SoCSigmaStar SSD210 — dual ARM Cortex-A7 @ 1GHz, 64MB DDR2 SIP
RAM33MB total (~16MB free)
패널nv3052c LCD, 물리 540×960 (6BIT, 59fps) → 960×540 가로(rotateScreen:90), BGRA32
14 keys (3행×5열, Row2 col3+col4 합체), ~192×180px
OSFlythingsOS V2.1 (Zkswe_SSD21X_SPINOR)
연결USB HID — VID 0x2207 / PID 0x0019, 1024B 패킷, 헤더 0x7C7C, ZIP 청킹 (WiFi 없음)
드라이버유일: Ulanzi Studio 플러그인 plugin-ulanzi/(daemon WS). direct-HID 모듈(Swift D200hHidModule.swift IOKit / Node bridge/src/d200h/ node-hid)은 retire — dormant(비활성)

Elgato Stream Deck (표준 15키) · Stream Deck+

하나의 플러그인이 두(이상의) Elgato 하드웨어를 지원 — 액션 코드는 디바이스-불문이며 familyForDeviceType()(plugin/src/actions/session-slot-button.ts)가 등록 디바이스의 columns×rows로 키패드 슬롯(slot = row*columns + col) 자동 산출.

항목표준 Stream Deck (15키)Stream Deck+
프로파일agentdeck-sd (DeviceType 0)agentdeck-sdplus (DeviceType 7)
키패드LCD 키 15개 (5×3)LCD 키 8개 (4×2)
인코더/스트립없음로터리 인코더 4개 + LCD 터치 스트립
추가 지원mini(DeviceType 1) · XL(2)도 familyForDeviceType()로 그리드 자동 산출

공통: 호스트 USB → Elgato Stream Deck 앱 플러그인 → daemon WebSocket(:9120) · Stream Deck SDK v2 · UUID bound.serendipity.agentdeck · 양방향 BridgeEvent 13종 전부. 인코더 매핑(SD+ 전용): E1 유틸리티 · E2 액션 · E3 터미널 · E4 음성 (음성 takeover 시 E2–E4 wide-canvas).

D. 모바일 / 데스크톱 소프트웨어 플랫폼

Apple (iOS · iPadOS · macOS)

SwiftUI Multiplatform 단일 코드베이스, App Store(bound.serendipity.agent.deck). 출처: apple/project.yml.

항목macOSiOS / iPadOS
최소 OSmacOS 26.0iOS / iPadOS 17.0
빌드Xcode 26.4 · Swift 6.0Xcode 26.4 · Swift 6.0
아키텍처Apple Silicon + Intel universalA-series / M-series
데몬in-process Swift daemon (:9120)WS client → 외부 daemon
샌드박스App Store, 서브프로세스 0 (AGENTDECK_APP_STORE)App Store sandbox
엔타이틀먼트audio · bluetooth · serial · usb · network · files없음 (WS only)

macOS만 하드웨어 모듈(ESP32 serial / D200H USB / Pixoo·iDotMatrix·Timebox BLE) 직접 구동. iOS/iPadOS는 same-LAN WebSocket 뷰어.

Android (e-ink 리더 · 태블릿)

Jetpack Compose 런처(dev.agentdeck) · minSdk 29 / target·compile 34 / JDK 17. 출처: android/app/build.gradle.kts.

디바이스칩 / 벤더디스플레이EPD API
Crema SRockchip RK3566B&W e-ink (16-level)EinkManager setMode/sendOneFullFrame
Onyx BooxOnyxB&W / 컬러(Kaleido 3)BaseDevice.setViewDefaultUpdateMode()
MOAAN Pantone 6Rockchip (rebrand)컬러 e-ink (Kaleido 3, 4096색)EinkManager (moaan)
Bigme (Galy / inkNote)Bigme컬러 e-ink (Gallery 3/4)컬러 einkPick()
Kobo (Android)KoboB&W e-inkfallback invalidate()
일반 태블릿 (Lenovo 등)ARM / x86컬러 LCD 60fps표준 Android 렌더

e-ink 리프레시: GC16(표준) · DU(dither) · A2(fast). 컬러 e-ink는 1/4 해상도 컬러 / full B&W. 연결: Android 앱은 mDNS LAN(iOS와 동일) + ADB localhost 양쪽 지원 — USB-테더 e-ink는 adb reverse 필요(CLI 전용), 같은 LAN 태블릿은 mDNS로 App Store Mac 데몬 직접 접속(각주⁴).

왜 Android 렌더링이 iOS(SwiftUI)와 다른가 — 근본적 차이, 통일 이득 없음. Android는 e-ink 리더 자체가 타깃(Crema/Onyx/Kobo/Pantone/Bigme)이라 벤더별 EPD 제어 인프라(EinkDetector.kt·EinkRenderer.kt 16-level 그레이 양자화·EinkRefreshZone.kt GC16/DU/A2 존)를 갖는다. iOS는 컬러 LCD/OLED 전용이라 SwiftUI Canvas+TimelineView 60fps면 충분하고 EPD 리프레시 모드 개념이 OS에 없어 분기 불가·불요. 데이터/프로토콜 계층은 이미 공유(shared/src/protocol.ts, 양쪽 동일 WS dialect) — 갈라지는 건 렌더 파이프라인 + 디스커버리 플러밍(NsdManager/OkHttp vs NWBrowser/URLSessionWebSocketTask)뿐이고 둘 다 플랫폼-네이티브가 안정적이라 의도된 최적화. 더 통일하면 iOS에 무의미한 no-op e-ink shim이 생겨 유지보수가 오히려 나빠짐 — 현 구조가 옳다.

E. 터미널 Surface

TUI Dashboard agentdeck dashboard

요건truecolor 지원 터미널 (의존성 0)
연결WS client → daemon (findDaemonPort(): daemon.json → sessions.json fallback)
렌더raw ANSI escape · braille 테라리움 · 3단 반응형 (wide 120+ / standard 80–119 / narrow 60–79)
이벤트BridgeEvent 13종 (push-only 뷰)

평가 노트 — App Store 게이팅이 최선인가

매트릭스의 ❌/⚠ 가 샌드박스 근본 제약인지 구현/분류 갭인지 구분 (코드 근거).

항목표기실제 사유최선 여부 / 개선안
TC001GAP구현 갭. serial entitlement로 커버되는 self-rendering ESP32(테스트가 serial board로 보고). 과거 "ADB" 표기는 producer 없는 dead code(AdbDeviceClass.ulanziTc001) 였음표기 정정 + dead-code 제거 완료(2026-06-25, matrix·Swift 5곳). 후속: HW 검증 후 ✅ 승격
Android 태블릿LAN과분류. mDNS로 App Store Mac 데몬 직접 접속이 코드상 가능개선 권장: e-ink(USB/adb)와 태블릿(LAN/mDNS) tier 분리
Android e-inkCLI진짜 제약. USB-테더 + adb reverse 서브프로세스 필요 → sandbox 불가현 구조 합리적(e-ink WiFi 불안정·USB 전제). 변경 불요
Timebox / iDotMatrixYESCoreBluetooth 네이티브최선. 단 데몬당 BLE 단일 연결 — 동시 1대만. (구 Timebox-SPP serial 변종은 제거됨)
SSE 스트림YES*구현 갭. 풀 스트리밍(broadcastSse, 멀티클라이언트+하트비트)은 Node 브리지(hook-server.ts)만 구현. App Store Swift 데몬(DaemonServer.swift)의 /sseevent: connected 1회 후 끊는 스텁개선 권장: 샌드박스 제약 아님(같은 HTTP 서버에 SSE 가능). Swift 데몬에 멀티클라이언트 SSE 구현 시 ✅ 승격. 현 App Store 빌드는 라이브 SSE에 외부 Node 데몬 필요
D200HYES(갭 아님) Ulanzi Studio 플러그인이 단일 드라이버. direct-HID 폴백은 retire(2026-06-21, 380c6510) — Node d200h:false/Swift enableD200hDirectHID=false, 모듈은 dormant 보존최선. 플러그인 없이 HID 직구동 시 화면 깨짐 → 의도적 비활성. 재활성은 두 flip-point만 되돌리면 됨
XTeink X3EXP구현 진행 중(experimental, 샌드박스 제약 아님). ESP32-C3 e-ink + 외부 CrossPoint 포크 펌웨어(crosspoint-agentdeck) 개발 중이라 아직 device_info/WS 미발신 → 대시보드 미표시. 전송은 다른 ESP32와 동일 WiFi WS(서브프로세스 없음)개선 예정: 펌웨어가 WS/device_info 발신 시작하면 App Store ✅ 가능. 현재 not-yet-shipping

요약: 진짜 sandbox 제약은 e-ink(adb) 경로뿐이며 CLI 대체 경로가 정당하다. TC001·Android 태블릿의 ❌ 는 구현/분류 갭이라 ⚠로 정정했고, SSE ✅* 는 Swift 데몬 SSE 미구현이라는 구현 갭(샌드박스 제약 아님)이라 별도 표기 — upstream appstore-feature-matrix.md·AdbModule.swift·AgentState.swift·TopologyRail.swift 의 ADB 오기를 정정하고 legacy dead-code 는 2026-06-25 제거 완료(TC001 의 ✅ 승격만 HW 검증 후속).