Skip to main content

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:

  1. photos plan creates a stable manifest and does not copy or delete files.
  2. photos move --execute copies only manifest items, verifies SHA-256 on both sides, then deletes only verified Android source files.
  3. photos resume --execute resumes 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 sha256sum for 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
  • --execute was 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xiaokeer_android_ops-0.1.0.tar.gz (23.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xiaokeer_android_ops-0.1.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

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

Hashes for xiaokeer_android_ops-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4c6ac2ea7d8c1354e27b92b0aabbef457b24bb3117408bc8600ccc23d6797376
MD5 8d2a915dac8fc06d3ffdf56220e90857
BLAKE2b-256 f5c93da5c178cb580b8c0603a86374cbbb801c5d09c882eea07bc64e9ebcacc0

See more details on using hashes here.

File details

Details for the file xiaokeer_android_ops-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for xiaokeer_android_ops-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b6c1ab16d08d8dd85874ce230da319c6989cbcb1cc51f016ebab18b47efc6a8b
MD5 48d24075e8a6024af580d144136f2b18
BLAKE2b-256 3c8222dddc462daa2548875f019acd849e5f34dfec28cd83a40a5268bd7a7da3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page