Agent-first macOS CLI for safe Android photo movement over ADB.
Project description
xiaokeer-android-ops
xiaokeer-android-ops is a macOS-only, agent-first command line tool for reliable Android photo movement through ADB.
The MVP moves image files from an already authorized Android device to a Mac run directory with a two-stage workflow:
photos plancreates a stable manifest and does not copy or delete files.photos move --executecopies only manifest items, verifies SHA-256 on both sides, then deletes only verified Android source files.photos resume --executeresumes the same manifest without selecting new files.
The project is designed for AI agents first. Default output is JSON, commands never prompt for input, and destructive actions require explicit parameters.
Identity
| Item | Value |
|---|---|
| GitHub repository | xiaokeer-android-ops |
| PyPI package | xiaokeer.android.ops |
| Python import namespace | xiaokeer.android.ops |
| CLI command | xandroidops |
| Initial version | 0.1.0 |
| License | MIT |
Scope
Supported host:
- macOS
- Python
>=3.9 - ADB installed separately
Supported device scope:
- authorized Android device connected through ADB
- normal shared storage image directories
- device-side
sha256sumfor deletion-capable execution
Default Android source directory:
/storage/emulated/0/DCIM/Camera
Supported image extensions:
.jpg
.jpeg
.png
.webp
.heic
.heif
.gif
Non-Goals
This project is not a backup tool, sync tool, Android file manager, gallery replacement, GUI, TUI, video transfer tool, app manager, directory diff tool, WiFi pairing manager, or Android permission bypass tool.
The MVP does not support recursive traversal, arbitrary file management, videos, folder sync, hidden files, MIME validation, third-party Python runtime dependencies, Linux, or Windows.
Install
After the package is published to PyPI:
pip install xiaokeer.android.ops
Recommended global CLI install after PyPI publication:
pipx install xiaokeer.android.ops
Current local source install:
cd /Users/chongwen002/project/xiaokeer-android-ops
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e .
The project does not bundle ADB. Install Android platform tools separately and make sure adb is on PATH.
Commands
xandroidops --version
xandroidops doctor
xandroidops photos count
xandroidops photos plan
xandroidops photos plan-all
xandroidops photos move --manifest /path/to/manifest.json --execute
xandroidops photos resume --manifest /path/to/manifest.json --execute
photos verify is reserved for a future release.
Agent Workflow
Check host and device readiness:
xandroidops doctor
Count all album-visible Android images:
xandroidops photos count
Create a read-only movement plan:
xandroidops photos plan --limit 20
Create a read-only movement plan for all album-visible images:
xandroidops photos plan-all
Plan from a different Android shared storage directory:
xandroidops photos plan --device-dir /storage/emulated/0/Pictures/Screenshots --limit 10
Move only the files in the manifest:
xandroidops photos move --manifest /Users/example/Desktop/AndroidPhotoMove-20260604-163000/manifest.json --execute
Resume the same manifest after interruption or partial failure:
xandroidops photos resume --manifest /Users/example/Desktop/AndroidPhotoMove-20260604-163000/manifest.json --execute
Agents should read JSON output, exit codes, and manifest item states. They must not parse human prose for workflow state.
Safety Model
photos count is read-only. It queries Android MediaStore for content://media/external/images/media, so the count reflects album-visible images indexed by Android rather than every image-like cache file on shared storage.
photos plan is the dry run. It is read-only, selects files, creates a run directory, and writes manifest.json.
photos plan-all is also read-only. It creates a manifest for every album-visible image returned by Android MediaStore, sets the manifest source to mediastore, and still requires photos move --manifest ... --execute before any source deletion can occur.
photos move --execute never creates a new plan. It executes only the manifest supplied through --manifest.
Android source deletion is allowed only when all of these facts are true:
- the item is listed in the manifest
- the connected device serial matches the manifest device serial
- the local copy exists
- remote SHA-256 was computed with device-side
sha256sum - local SHA-256 was computed with Python
hashlib.sha256 - hashes match exactly
- the item is under the planned Android source directory
--executewas explicitly provided
The tool never deletes directories, never uses wildcards for deletion, and never deletes manifest-external paths.
Default Output
JSON is the default output for all commands.
Example no-device response:
{
"ok": false,
"tool": "xiaokeer.android.ops",
"tool_version": "0.1.0",
"error": {
"code": "NO_DEVICE",
"message": "No authorized Android device found.",
"category": "device_unavailable"
},
"next_action": {
"type": "connect_device",
"instructions": [
"Connect Android device by USB.",
"Enable USB debugging.",
"Approve this Mac on the device."
]
}
}
Example successful plan shape:
{
"ok": true,
"tool": "xiaokeer.android.ops",
"tool_version": "0.1.0",
"manifest_path": "/Users/example/Desktop/AndroidPhotoMove-20260604-163000/manifest.json",
"run_dir": "/Users/example/Desktop/AndroidPhotoMove-20260604-163000",
"selected_count": 3,
"summary": "plan_created",
"next_action": {
"type": "execute_move",
"command": "xandroidops photos move --manifest /Users/example/Desktop/AndroidPhotoMove-20260604-163000/manifest.json --execute"
}
}
Text output is available only when a command explicitly supports --text.
Exit Codes
| Code | Meaning |
|---|---|
0 |
success, including successful plan |
1 |
generic error |
2 |
device unavailable, unauthorized, or multiple devices without --serial |
3 |
no matching photos or empty plan |
4 |
copy failure |
5 |
verification failure |
6 |
delete failure |
7 |
manifest or argument mismatch |
8 |
ADB capability missing, such as missing device-side sha256sum |
Manifest
The manifest is the source of truth for execution and recovery. It is a stable public contract and uses schema version 1.
Run directory shape:
~/Desktop/AndroidPhotoMove-YYYYMMDD-HHMMSS/
manifest.json
files/
Item states:
selected
copied
verify_failed
verified
delete_failed
deleted
media_refresh_attempted
completed
failed
The manifest is preserved permanently as audit and recovery data.
Development
cd /Users/chongwen002/project/xiaokeer-android-ops
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip build twine
python -m pip install -e .
python -m unittest discover tests -v
python -m build
python -m twine check dist/*
Automated tests use fake ADB behavior and must not require a real Android device.
Real Device Validation
Real device validation is manual and documented in REAL_DEVICE_TEST.md. It may delete real source files on the Android device, so use disposable test images only.
No one-off real-device validation scripts are allowed. If validation needs automation, it must become part of the official CLI or test harness.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xiaokeer_android_ops-0.1.0.tar.gz.
File metadata
- Download URL: xiaokeer_android_ops-0.1.0.tar.gz
- Upload date:
- Size: 23.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c6ac2ea7d8c1354e27b92b0aabbef457b24bb3117408bc8600ccc23d6797376
|
|
| MD5 |
8d2a915dac8fc06d3ffdf56220e90857
|
|
| BLAKE2b-256 |
f5c93da5c178cb580b8c0603a86374cbbb801c5d09c882eea07bc64e9ebcacc0
|
File details
Details for the file xiaokeer_android_ops-0.1.0-py3-none-any.whl.
File metadata
- Download URL: xiaokeer_android_ops-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6c1ab16d08d8dd85874ce230da319c6989cbcb1cc51f016ebab18b47efc6a8b
|
|
| MD5 |
48d24075e8a6024af580d144136f2b18
|
|
| BLAKE2b-256 |
3c8222dddc462daa2548875f019acd849e5f34dfec28cd83a40a5268bd7a7da3
|