Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

avdm — Headless AVD Manager

A terminal-based manager for Android Virtual Devices and ADB-connected devices. Wraps the Android SDK command-line tools (emulator, adb, avdmanager) in an interactive TUI — no Android Studio required.

┌─────────────────────────────────────────────────────┐
│  avdm — Headless AVD Manager             v0.1.0     │
├─────────────────────────────────────────────────────┤
│                                                     │
│  > AVD Devices          (manage virtual devices)    │
│    Connected Devices    (ADB-connected devices)     │
│    Wireless Connect     (connect via IP)            │
│    Wireless Pairing     (pair new device)           │
│    Doctor               (environment health check)  │
│    Settings             (SDK path, defaults)        │
│    Quit                                             │
│                                                     │
├─────────────────────────────────────────────────────┤
│  ↑/↓ navigate  ⏎ select  q quit  ? help            │
└─────────────────────────────────────────────────────┘

Features

Feature Status
List, start, and stop AVDs Planned (Phase 1)
Real-time emulator log viewer Planned (Phase 1)
List connected ADB devices Planned (Phase 1)
Wireless ADB connect / disconnect Planned (Phase 1)
Wireless ADB pairing (Android 11+) Planned (Phase 1)
Environment health check (doctor) Planned (Phase 1)
SDK path configuration Planned (Phase 1)
Create / delete AVDs Planned (Phase 2)
System image management Planned (Phase 2)
Snapshot management Planned (Phase 3)
Logcat viewer with filtering Planned (Phase 3)

Requirements

  • Go 1.22+ (for building from source)
  • Android SDK with the following components installed:
    • platform-tools (provides adb)
    • emulator
    • cmdline-tools (provides avdmanager, sdkmanager)
  • macOS or Linux (Windows support is not planned)

The ANDROID_HOME environment variable should point to your SDK root, or the SDK should be in a standard default location (see SDK Detection).

Run avdm doctor to verify your environment before first use.

Installation

Pre-built binaries

Download the latest binary from the Releases page.

# macOS (Apple Silicon)
curl -L https://github.com/koechian/headless-avd-manager/releases/latest/download/avdm-darwin-arm64 -o avdm
chmod +x avdm && sudo mv avdm /usr/local/bin/

Build from source

git clone https://github.com/koechian/headless-avd-manager.git
cd headless-avd-manager
make build
# Binary is at ./bin/avdm

Install to $GOPATH/bin

make install

Usage

avdm              # Launch the interactive TUI
avdm doctor       # Run environment health checks (no TUI)
avdm version      # Print version information
avdm help         # Show help

Key bindings (TUI)

Key Action
/ or k / j Navigate list
Enter Select / confirm
Esc Go back
q Quit
? Toggle help
r Refresh current view
s Start selected AVD
x Stop selected AVD
d Disconnect selected device

SDK Detection

avdm searches for the Android SDK in this order:

  1. ANDROID_HOME environment variable
  2. ANDROID_SDK_ROOT environment variable (deprecated, but still checked)
  3. Platform default paths:
    • macOS: ~/Library/Android/sdk, ~/Android/Sdk
    • Linux: ~/Android/Sdk, ~/android-sdk, /opt/android-sdk

AVDs are read from ~/.android/avd/ (the standard location used by Android Studio).

Configuration

avdm stores preferences in ~/.config/avdm/config.json:

{
  "sdk_path": "",
  "default_headless": false,
  "default_gpu_mode": "auto",
  "default_no_audio": false
}
Field Default Description
sdk_path "" Override the auto-detected SDK root. Leave empty to use auto-detection.
default_headless false Launch emulators without a window by default.
default_gpu_mode "auto" GPU mode: auto, host, swiftshader_indirect, off.
default_no_audio false Disable emulator audio by default.

Project Structure

.
├── cmd/
│   └── avdm/
│       └── main.go              # Entry point, CLI subcommand routing
├── internal/
│   ├── config/
│   │   └── config.go            # Persistent JSON config (~/.config/avdm/)
│   ├── doctor/
│   │   ├── doctor.go            # Orchestrates environment health checks
│   │   ├── checks.go            # Individual check implementations
│   │   └── types.go             # CheckResult, Report, Status types
│   ├── sdk/
│   │   ├── types.go             # Shared types: AVD, Device, SDKPaths, etc.
│   │   ├── detect.go            # Android SDK auto-detection
│   │   ├── adb.go               # adb command wrappers
│   │   ├── emulator.go          # emulator command wrappers
│   │   └── avdmanager.go        # avdmanager command wrappers
│   ├── tui/
│   │   ├── app.go               # Root Bubble Tea model, screen routing
│   │   ├── styles.go            # Shared lipgloss styles and theme
│   │   ├── messages.go          # Custom tea.Msg types
│   │   ├── keys.go              # Key binding definitions
│   │   └── screens/
│   │       ├── menu.go          # Main menu screen
│   │       ├── avdlist.go       # AVD list + start/stop actions
│   │       ├── devicelist.go    # Connected ADB devices list
│   │       ├── connect.go       # Wireless connect form
│   │       ├── pair.go          # Wireless pairing form
│   │       ├── logviewer.go     # Real-time emulator/logcat output
│   │       ├── doctor.go        # Doctor health check screen
│   │       └── settings.go      # Settings screen
│   └── version/
│       └── version.go           # Build-time version metadata
├── .github/
│   └── workflows/
│       ├── ci.yml               # Lint + test on push/PR
│       └── release.yml          # Cross-platform release builds on tag push
├── .gitignore
├── .golangci.yml                # golangci-lint configuration
├── CHANGELOG.md                 # Keep a Changelog format
├── Makefile                     # Build, test, lint, release targets
├── go.mod
└── go.sum

Development

Prerequisites

# Install golangci-lint
brew install golangci-lint        # macOS
# or: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

Common commands

make build        # Build the binary (./bin/avdm)
make test         # Run all tests with race detector
make test-cover   # Run tests and open HTML coverage report
make lint         # Run golangci-lint
make fmt          # Format all Go source files
make check        # Full quality gate: vet + lint + test
make release      # Cross-compile for macOS and Linux
make clean        # Remove build artifacts

Running tests

go test ./...                          # All tests
go test ./internal/sdk/...             # Specific package
go test -run TestIsValidSDKRoot ./...  # Single test

Commit conventions

This project follows Conventional Commits:

feat: add wireless ADB pairing screen
fix: correct AVD status detection when emulator-5554 is offline
docs: add configuration reference to README
refactor: extract adb device parsing into separate function
test: add unit tests for doctor disk space check
chore: bump golangci-lint to v2.10.1

Commits should be atomic — one logical change per commit.

Versioning

avdm uses Semantic Versioning:

  • MAJOR — breaking changes to CLI interface or config format
  • MINOR — new features, new doctor checks, new TUI screens
  • PATCH — bug fixes, dependency updates, documentation

To create a release:

git tag -a v0.1.0 -m "chore: release v0.1.0"
git push origin v0.1.0
# The release GitHub Action builds and publishes binaries automatically.

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Make your changes with atomic commits
  4. Ensure all checks pass: make check
  5. Open a pull request against main

Please update CHANGELOG.md under [Unreleased] with a summary of your changes.

License

MIT — see LICENSE for details.

About

A terminal-based manager for Android Virtual Devices and ADB-connected devices.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages