Skip to main content

Android

@shrug/androidv2026.10.13.1· 1d agoBEHAVIORSREPORTSACCEPTED WARNINGS
01README

Swamp-managed Android device over ADB. One model type (@shrug/android/device) drives the local adb CLI (via Deno.Command, behind an injectable exec seam) to pull device state into typed, versioned snapshots and to manage apps through gated, auditable mutations. Reads (all non-root): device identity + capability ceiling + owners (syncDevice), full app inventory joined from pm list + dumpsys package (syncPackages), per-app usage + standby buckets (syncUsage), on-disk code sizes (syncStorage), user-facing runtime permissions with a privacy-category rollup (syncPermissions), estimated per-app power use in mAh (syncBattery), special-access appops holders (syncAppControls), and per-app notification posture (syncNotifications); a fan-out sync captures the whole surface in one model-lock run. Management (dry-run by default, confirm=true to apply, protected-app guard, every run audited to a mutation/reconcile log): disable/enable/uninstall/restore (single + fan-out), force-stop, clear-data, set an appop, and a declarative desired-state reconcile (applyDesired). syncLabels resolves human-readable app names from Play / F-Droid. Privacy-conscious: notification posture is derived from the POST_NOTIFICATIONS grant, never from notification content, and nothing leaves the device except the opt-in store-label lookups. Ships an app-classification report that flags unused junk, enriched by the Universal Debloater Alliance (UAD-NG) community list. Pure parsers over captured adb stdout make the whole surface unit-testable with no device.

02Behaviors1
@shrug/android/devicev2026.10.13.1android.ts

Global Arguments

ArgumentTypeDescription
serial?stringadb device serial (-s). Pin it when a stale emulator or a second device
adbBinary?stringPath to the adb binary
fn syncDevice()
Capture device identity, capability ceiling (root), users, and owners
fn syncPackages()
Capture the full installed-package inventory joined with metadata
fn syncUsage()
Capture per-app usage stats (last-used, launch count, standby bucket)
fn syncStorage()
Capture per-app code size on disk and totals
fn sync()
Fan-out: capture the full read surface (device, packages, usage,
fn syncPermissions(user?: number, scope?: enum)
Capture per-app runtime permission grants (the user-facing,
ArgumentTypeDescription
user?numberAndroid user id (0 = owner)
scope?enumLimit to third-party apps (default) or include system apps
fn syncBattery()
Capture estimated per-app power use (mAh) from batterystats,
fn syncAppControls(ops?: array)
Capture holders of special-access appops (display-over-other-apps,
ArgumentTypeDescription
ops?arrayappops op names to query (default: the special-access set)
fn syncNotifications(user?: number, scope?: enum)
Capture per-app notification posture from the POST_NOTIFICATIONS
ArgumentTypeDescription
user?numberAndroid user id (0 = owner)
scope?enumLimit to third-party apps (default) or include system apps
fn disableApp(pkg: string, user?: number, confirm?: boolean, force?: boolean)
Disable an app for a user (pm disable-user). Reversible. Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstringPackage name to act on
user?numberAndroid user id (0 = owner)
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?booleanOverride the protected-app guard (management tooling).
fn enableApp(pkg: string, user?: number, confirm?: boolean, force?: boolean)
Re-enable a disabled app (pm enable). Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstringPackage name to act on
user?numberAndroid user id (0 = owner)
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?booleanOverride the protected-app guard (management tooling).
fn uninstallApp(pkg: string, user?: number, confirm?: boolean, force?: boolean)
Uninstall an app for a user (pm uninstall --user). Restorable. Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstringPackage name to act on
user?numberAndroid user id (0 = owner)
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?booleanOverride the protected-app guard (management tooling).
fn restoreApp(pkg: string, user?: number, confirm?: boolean, force?: boolean)
Restore an uninstalled-for-user app (cmd package install-existing). Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstringPackage name to act on
user?numberAndroid user id (0 = owner)
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?booleanOverride the protected-app guard (management tooling).
fn disableApps(packages: array, user?: number, confirm?: boolean, force?: boolean)
Fan-out disable: act on many packages in one lock (repo rule 6). Dry-run unless confirm=true.
ArgumentTypeDescription
packagesarrayPackages to act on
user?number
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?boolean
fn uninstallApps(packages: array, user?: number, confirm?: boolean, force?: boolean)
Fan-out uninstall for a user. Dry-run unless confirm=true. Restorable.
ArgumentTypeDescription
packagesarrayPackages to act on
user?number
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?boolean
fn applyDesired(desired?: array, user?: number, confirm?: boolean, force?: boolean)
Reconcile the device to a declarative desired-state list
ArgumentTypeDescription
desired?arrayDesired per-package states. If omitted, read from globalArguments.desired.
user?number
confirm?booleanActually converge. Default false = dry-run reconcile plan, device untouched.
force?booleanOverride the protected-app guard for destructive steps.
fn forceStop(pkg: string, user?: number, confirm?: boolean, force?: boolean)
Force-stop a running app (am force-stop). Reversible. Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstringPackage name to act on
user?numberAndroid user id (0 = owner)
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?booleanOverride the protected-app guard (management tooling).
fn clearAppData(pkg: string, user?: number, confirm?: boolean, force?: boolean)
Clear an app's data/caches for a user (pm clear). DESTRUCTIVE + protected-guarded. Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstringPackage name to act on
user?numberAndroid user id (0 = owner)
confirm?booleanActually run. Default false = dry-run preview, device untouched.
force?booleanOverride the protected-app guard (management tooling).
fn syncLabels(scope?: enum, refresh?: boolean, limit?: number, delayMs?: number)
Resolve human-readable app names from Play / F-Droid (og:title) and
ArgumentTypeDescription
scope?enum
refresh?booleanRe-fetch even if already cached
limit?numberCap new lookups this run (0 = no cap)
delayMs?numberThrottle between HTTP lookups (ms)
fn getAppOps(pkg: string, user?: number)
Read per-app operation modes (cmd appops get). Read-only.
ArgumentTypeDescription
pkgstring
user?number
fn setAppOp(pkg: string, op: string, mode: enum, confirm?: boolean)
Set one appops op mode for an app (cmd appops set). Dry-run unless confirm=true.
ArgumentTypeDescription
pkgstring
opstringappops op name, e.g. RUN_IN_BACKGROUND, FINE_LOCATION
modeenumallow | deny | ignore | default | foreground
confirm?booleanActually set. Default false = dry-run preview, device untouched.

Resources

device-info(infinite)— Device identity, capability ceiling, users, and owners
packages(infinite)— Full installed-package inventory (pm list + dumpsys join)
usage(infinite)— Per-app last-used, launch count, and standby bucket
storage(infinite)— Per-app code size on disk and app/data/cache totals
mutation-log(infinite)— Audit of the last app-disposition run (dry-run plan or applied result)
reconcile-log(infinite)— Audit of the last desired-state reconcile (plan + applied steps)
appops(infinite)— Per-app operation modes (appops get) for one package
labels(infinite)— Human-readable app names resolved from Play / F-Droid (cached)
permissions(infinite)— Per-app runtime permission grants plus a privacy-category rollup
battery(infinite)— Estimated power use (mAh): global components + per-app totals
app-controls(infinite)— Holders of special-access appops (overlay, all-files, install, ...)
notifications(infinite)— Per-app POST_NOTIFICATIONS posture (can the app notify?)
03Reports1
@shrug/android/app-classificationmodel
app-classification.ts

Per third-party app: category + keep/review/remove verdict from usage,

androidappscleanupinventory
04Stats
A
93 / 100
Downloads
1
Archive size
144.9 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License1/2partial

    no SPDX license declared

  • Verified public repository2/2earned

06Platforms
07Labels