AgentDeck · Dashboard Surfaces
daemon hub(port 9120)에 붙어 에이전트 상태를 보여주거나 제어하는 모든 surface — 하드웨어 디스플레이/입력 디바이스 11종 + 소프트웨어 플랫폼(Apple 3 · Android 다수) + 터미널 TUI = 14 surface. 동시 구동 가능.
| Surface | 종류 | SoC · 플랫폼 | 디스플레이 / 해상도 | 전송 | 연결성 | App Store |
|---|---|---|---|---|---|---|
| IPS 3.5" | ESP32 FW | ESP32-S3 | AXS15231B IPS · 480×320 | USB Serial / WiFi WS | USB-Serial + WiFi | YES |
| Round AMOLED 1.8" | ESP32 FW | ESP32-S3 | ST77916 AMOLED · 360×360 | USB Serial / WiFi WS | USB-Serial + WiFi | YES |
| 86 Box 4" | ESP32 FW | ESP32-S3 | ST7701 IPS · 480×480 | USB Serial / WiFi WS | USB-Serial + WiFi | YES |
| TTGO T-Display 1.14" | ESP32 FW | ESP32 (classic) | ST7789 TFT · 135×240 | USB Serial / WiFi WS | USB-Serial + WiFi | YES |
| ESP32-C6 1.47" | ESP32 FW | ESP32-C6 (RISC-V) | ST7789 TFT · 172×320 | USB Serial / WiFi WS | USB-CDC + WiFi | YES |
| IPS 10.1" | ESP32 FW | ESP32-P4 + C6 | JD9365 IPS MIPI-DSI · 800×1280 | USB Serial / WiFi WS | USB-Serial + WiFi | YES |
| XTeink X3 | ESP32 FW | ESP32-C3 | e-ink · 528×792 (3.7") | WiFi WS (계획) | WiFi | EXP7 |
| Divoom Pixoo64 | 상용 LED | Divoom (비-ESP32) | RGB LED · 64×64 | HTTP REST :80 | WiFi | YES |
| InkDeck e-ink | ESP32 FW | XIAO ESP32-S3 Plus | e-ink · 800×480 (Seeed OG, UC8179) | WiFi WS (계획) | WiFi | EXP4 |
| iDotMatrix 32×32 | 상용 BLE | BLE SoC (비-ESP32) | RGB AMOLED · 32×32 | BLE GATT | Bluetooth LE | YES |
| Divoom Timebox Mini | 상용 BLE | BLE SoC (비-ESP32) | RGB LED · 11×11 | BLE GATT (ISSC) | Bluetooth LE | YES |
| Ulanzi TC001 | ESP32 FW | ESP32 (classic) | WS2812B · 8×32 (256 LED) | USB Serial / WiFi WS | USB-Serial + WiFi | GAP1 |
| Ulanzi D200H | HID deck | SigmaStar SSD210 | nv3052c LCD · 960×540 (14 keys) | Ulanzi Studio 플러그인 (단일 드라이버; direct-HID retire) | USB | YES |
| Elgato Stream Deck (15-key) | HID deck | Elgato (내장) | LCD keys 15 (5×3) | WebSocket :9120 | USB → 네트워크 | YES3 |
| Elgato Stream Deck+ | HID deck | Elgato (내장) | LCD keys 8 (4×2) + dials 4 + touch strip | WebSocket :9120 | USB → 네트워크 | YES3 |
| Apple — macOS | SW | Apple Silicon / Intel | 호스트 디스플레이 | 내장 Swift daemon / WS | — | YES |
| Apple — iOS / iPadOS | SW | A / M-series | 디바이스 디스플레이 | WebSocket :9120 | WiFi (same-LAN) | YES |
| Android — e-ink | SW | 벤더별 (RK3566 등) | e-ink 디스플레이 | WebSocket (ADB localhost) | USB / ADB | CLI2 |
| Android — 태블릿 | SW | ARM / x86 | 컬러 LCD | WebSocket + mDNS | WiFi (same-LAN) | LAN2 |
| SSE 스트림 | 프로토콜 | 호스트 | 브라우저 / 스크립트 | HTTP SSE :9120 /sse | 로컬 / LAN | YES* |
| 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)의 /sse는 event: 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).
공통: 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 env는 platformio.ini의 실제 [env:...](불변). flash.sh가 친근명→pio로 매핑하며 legacy 별칭(round_amoled·ttgo·ips10 등)도 계속 받는다. CI/pio run -e는 pio env 사용.
| 보드 | friendly명 | pio env | 모델 (제조사) | SoC | 해상도 | 디스플레이 IC | 터치 IC | Flash | PSRAM | USB-UART |
|---|---|---|---|---|---|---|---|---|---|---|
| IPS 3.5" | ips_35 | ips35 | JC3248W535 (Guition) | ESP32-S3 | 480×320 | AXS15231B (QSPI) | 통합 | 16MB | YES | Native USB JTAG |
| Round AMOLED 1.8" | amoled_18 | amoled | JC3636W518 (Guition) | ESP32-S3 | 360×360 | ST77916 (QSPI) | CST816S (I2C) | 8MB | YES | Native USB JTAG |
| 86 Box 4" | box_40 | box_866 | ESP32-S3-4848S040 (Guition) | ESP32-S3 | 480×480 | ST7701 (RGB 16-bit) | GT911 (I2C) | 16MB | YES | CH340 |
| TTGO T-Display 1.14" | tft_114 | ttgo | LilyGO T-Display | ESP32-D0WDQ6 | 135×240 | ST7789 (SPI) | 없음 (버튼 2) | 16MB | NO | CH3404 |
| ESP32-C6 1.47" | c6_147 | esp32_c6_147 | Waveshare ESP32-C6-LCD-1.47" | ESP32-C6 | 172×320 | ST7789 (SPI) | 없음 (BOOT) | 4MB | NO | Native USB CDC |
| IPS 10.1" | ips_101 | ips10 | JC8012P4A1C (Guition) | ESP32-P4NRW32 (400MHz) | 800×1280 | JD9365 (MIPI-DSI) | GSL3680 (I2C) | 4MB5 | 32MB | CH340 |
| XTeink X37 | — | — | XTeink X3 (XTeink) | ESP32-C3 | 528×792 | e-ink EPD (미확정) | 없음 | 4MB | NO | pogo 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 rgb48가 platformio.ini의 default_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 참조.
상용 LED 액자 · 비-ESP32
상용 BLE 픽셀 · BLE SoC
상용 BLE 픽셀 · BLE SoC
ESP32 펌웨어 · env led8x32
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.
| SoC | SigmaStar SSD210 — dual ARM Cortex-A7 @ 1GHz, 64MB DDR2 SIP |
|---|---|
| RAM | 33MB total (~16MB free) |
| 패널 | nv3052c LCD, 물리 540×960 (6BIT, 59fps) → 960×540 가로(rotateScreen:90), BGRA32 |
| 키 | 14 keys (3행×5열, Row2 col3+col4 합체), ~192×180px |
| OS | FlythingsOS 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 하드웨어를 지원 — 액션 코드는 디바이스-불문이며 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).
SwiftUI Multiplatform 단일 코드베이스, App Store(bound.serendipity.agent.deck). 출처: apple/project.yml.
| 항목 | macOS | iOS / iPadOS |
|---|---|---|
| 최소 OS | macOS 26.0 | iOS / iPadOS 17.0 |
| 빌드 | Xcode 26.4 · Swift 6.0 | Xcode 26.4 · Swift 6.0 |
| 아키텍처 | Apple Silicon + Intel universal | A-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 뷰어.
Jetpack Compose 런처(dev.agentdeck) · minSdk 29 / target·compile 34 / JDK 17. 출처: android/app/build.gradle.kts.
| 디바이스 | 칩 / 벤더 | 디스플레이 | EPD API |
|---|---|---|---|
| Crema S | Rockchip RK3566 | B&W e-ink (16-level) | EinkManager setMode/sendOneFullFrame |
| Onyx Boox | Onyx | B&W / 컬러(Kaleido 3) | BaseDevice.setViewDefaultUpdateMode() |
| MOAAN Pantone 6 | Rockchip (rebrand) | 컬러 e-ink (Kaleido 3, 4096색) | EinkManager (moaan) |
| Bigme (Galy / inkNote) | Bigme | 컬러 e-ink (Gallery 3/4) | 컬러 einkPick() |
| Kobo (Android) | Kobo | B&W e-ink | fallback 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이 생겨 유지보수가 오히려 나빠짐 — 현 구조가 옳다.
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 뷰) |
매트릭스의 ❌/⚠ 가 샌드박스 근본 제약인지 구현/분류 갭인지 구분 (코드 근거).
| 항목 | 표기 | 실제 사유 | 최선 여부 / 개선안 |
|---|---|---|---|
| TC001 | GAP | 구현 갭. 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-ink | CLI | 진짜 제약. USB-테더 + adb reverse 서브프로세스 필요 → sandbox 불가 | 현 구조 합리적(e-ink WiFi 불안정·USB 전제). 변경 불요 |
| Timebox / iDotMatrix | YES | CoreBluetooth 네이티브 | 최선. 단 데몬당 BLE 단일 연결 — 동시 1대만. (구 Timebox-SPP serial 변종은 제거됨) |
| SSE 스트림 | YES* | 구현 갭. 풀 스트리밍(broadcastSse, 멀티클라이언트+하트비트)은 Node 브리지(hook-server.ts)만 구현. App Store Swift 데몬(DaemonServer.swift)의 /sse는 event: connected 1회 후 끊는 스텁 | 개선 권장: 샌드박스 제약 아님(같은 HTTP 서버에 SSE 가능). Swift 데몬에 멀티클라이언트 SSE 구현 시 ✅ 승격. 현 App Store 빌드는 라이브 SSE에 외부 Node 데몬 필요 |
| D200H | YES | (갭 아님) Ulanzi Studio 플러그인이 단일 드라이버. direct-HID 폴백은 retire(2026-06-21, 380c6510) — Node d200h:false/Swift enableD200hDirectHID=false, 모듈은 dormant 보존 | 최선. 플러그인 없이 HID 직구동 시 화면 깨짐 → 의도적 비활성. 재활성은 두 flip-point만 되돌리면 됨 |
| XTeink X3 | EXP | 구현 진행 중(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 검증 후속).