---
name: smarttv
description: Control and customize a Fire TV (or Android / Google TV) over ADB from Claude Code. Custom Apple-TV-style home screen (add, move or remove apps, change backgrounds), install apps from official sources, disable Amazon bloat (reversible), measure before/after numbers, and put the TV back to stock. Trigger "/smarttv", "edit my TV", "add X to my TV home screen", "change the TV background", "install X on the TV", "put the TV back to stock".
---

# /smarttv

Free skill from aidanholt.ca/smartTV. Save this file as `~/.claude/skills/smarttv/SKILL.md`, then fill in the two lines under "My TV".
Everything for the TV lives in one project folder (default `~/Projects/smart-tv`).

## My TV (fill these in)
- TV IP address: `{{TV_IP}}`  (Fire TV: Settings > My Fire TV > About > Network)
- Model / OS / CPU: `{{MODEL}}`  (Claude fills this in after the first connect: `adb shell getprop ro.product.model`, `ro.build.version.release`, `ro.product.cpu.abi`)

## Connect
- Install ADB with Homebrew: `brew install android-platform-tools`. Never use installers that need sudo from inside the agent (they fail silently without a terminal).
- `adb connect {{TV_IP}}:5555`. The first time, the TV shows "Allow USB debugging?": tick "Always allow" and press OK on the remote.
- If the IP changed, ask the user for the new one from the TV's Network screen.
- Most Fire TV sticks are 32-bit (armeabi-v7a). Always download the APK build that matches `ro.product.cpu.abi`.

## Rules
- **Measure before you change anything.** Save to `before/`: home screen screenshot (`adb exec-out screencap -p > before/home.png`), ads/promos visible without scrolling, cold start times (`am start -W`, report it as "time to first frame"), free RAM (`/proc/meminfo` MemAvailable), scroll smoothness (`dumpsys gfxinfo <package> reset`, scroll 12 presses, read Janky frames + 50th percentile). Reboot before both before and after.
- **Never fake a win.** Free RAM barely moves after disabling apps (Android refills the cache). Say so.
- **Everything reversible.** Disable with `pm disable-user --user 0 <pkg>`, never uninstall system apps. Keep the list in `debloat_disabled.txt`. Keep `restore_stock.sh` working at all times.
- **Official sources only.** Amazon Appstore pages via `adb shell am start -a android.intent.action.VIEW -d "amzn://apps/android?p=<pkg>"` (the user presses Get), or the official GitHub release of an open source app (check the file size against the release page), installed with `adb install -r`. No pirated or unlicensed streaming apps.
- **Be honest about ads.** A custom home screen removes home-screen ads only. Ads inside Prime Video, Netflix and other ad tiers are in the stream and stay. SmartTube is what removes YouTube ads.

## The home screen (`launcher/`)
- `launcher/web/index.html` is the whole design. The app list is a `ROWS` array at the top of the script: row 0 = big app tiles, row 1 = small pills. Each entry: name, package, background photo, kicker, one line of text.
- Background photos in `launcher/web/walls/` at 1280x720, JPEG quality ~78. Bake the dark gradient INTO the photo; never draw a full-screen gradient live.
- Preview on the Mac first (open the HTML in Chrome, arrow keys + Enter). Show the user a screenshot before installing.
- Android wrapper `launcher/android/`: a WebView app. Handle the remote's D-pad natively in `dispatchKeyEvent` and call a JS `nav()` function. Do not let the WebView handle keys (double moves + a yellow focus ring).
- Taking over the Home button on Fire TV: Amazon does not let you pick a default launcher, so use an accessibility service that watches for Amazon's home activity and brings the custom home back. Include a "Fire TV" pill that opens the original Amazon home on purpose.
- Ship with `./install_launcher.sh`: build, `adb install -r`, then RE-ENABLE the accessibility service (reinstalling silently turns it off):
  `adb shell settings put secure enabled_accessibility_services <pkg>/<pkg>.HomeService` and `adb shell settings put secure accessibility_enabled 1`.
- After every install: `adb exec-out screencap -p` and actually look at it.

## Gotchas
- Never force-stop the launcher app (`am force-stop`, `am start -S`): Android drops a force-stopped app from the enabled accessibility services and the Home takeover silently dies.
- `adb shell input keyevent HOME` is injected and does not reach an accessibility key filter. Test the Home button with the real remote too.
- Send remote keys with ~0.25 s between them or presses get dropped.
- Fire TV Settings lives inside Amazon's launcher package. Open it directly with action `amazon.intent.action.MAINSETTINGS`.

## Performance (streaming sticks are weak)
- Animate only `transform` and `opacity`. No `backdrop-filter`, no `filter: blur`, no infinite animations, no animated box-shadow, no slow-zoom backgrounds.
- Two background layers only; swap the photo after a ~220 ms settle; preload images.
- Pause the WebView and timers in `onPause` so Netflix and Prime get the memory.
- Check idle CPU after every change: `adb shell top -b -n 1 -m 10` should not list the launcher after 10 s idle.

## Optional features
- Radio: a tuner sheet (left/right tunes, up/down band, OK play/stop). Find official station streams with the Radio Browser API. Play them natively with ExoPlayer (media3 + HLS), send a browser user agent, allow cross-protocol redirects, keep the screen on while playing. Verify every station actually reaches "started", not just "a player exists".
- Navigation sounds: short original WAVs in `res/raw/`, played natively with SoundPool.

## Audit
Write `audit.sh`: drive the real remote to every tile and pill, press OK, check the app that opened (`dumpsys activity activities | grep mResumedActivity`), press Home, check the custom home came back. Print PASS/FAIL per app.

## Undo
`restore_stock.sh`: turn off the accessibility service, uninstall the launcher, re-enable every package in `debloat_disabled.txt`, uninstall anything you sideloaded, press Home. When the user is done tinkering, suggest turning ADB debugging back off in Developer Options.
