Repository navigation
uk AI AGENTS
Languages: English · العربية · Čeština · Deutsch · Español · فارسی · Français · हिन्दी · Bahasa Indonesia · Italiano · 日本語 · 한국어 · Nederlands · Polski · Português · Русский · Svenska · ไทย · Türkçe · Українська · Tiếng Việt · 中文
VDBackup зроблено так, щоб асистент чи агент на основі ШІ міг керувати кожним вмістом та дією модуля безголово, так само, як це робить людина через WebUI. WebUI: це лише один клієнт невеликого JSON API; ваш агент: інший. Використовуйте API, не скрейпте WebUI.
Усе проходить через одну точку входу, запущену з правами root на пристрої:
sh /data/adb/modules/vdbackup/scripts/helper.sh <verb> <base64(JSON-args)>
- Аргументи: це єдиний об'єкт JSON, закодований у base64, переданий як один токен argv.
- Команда виводить один об'єкт JSON у stdout:
{"ok":true,...}або{"ok":false,"code":"ERR_...","message":"..."}. Розбирайте це; ніколи не скрейпте текст. - Довгі операції (
backup,restore,import,backup-batch,restore-batch,config-export,config-import) одразу повертають{"ok":true,"opid":"..."}і працюють відокремлено (вони переживають зникнення викликача/WebUI). Опитуйте їхній поступ; вони не завершені, коли виклик повертається. -
progressіcancelприймають base64 сирого рядка opid, а не об'єкт JSON.
Крихітний помічник для вашого shell:
b64() { printf '%s' "$1" | base64 -w0; }
H=/data/adb/modules/vdbackup/scripts/helper.sh
sh "$H" backup "$(b64 '{"package":"com.example.app","mode":"full"}')"Щоб керувати ним з робочої станції, запускайте це через ваш звичайний root-канал до пристрою
(adb shell з правами root або налаштування SSH-to-root). Модуль постачає вбудовані бінарники, тож
щойно встановлений, він не потребує інтернету для локального резервного копіювання/відновлення; лише хмарні
призначення (rclone/restic/ssh) спілкуються з мережею.
| Дієслово | Аргументи (JSON) | Повертає |
|---|---|---|
ping |
{} |
{ok,version,abi} |
overview |
{user?} |
{ok:true,apps,instances,path_backups,jobs,backups_size,free,total} лічильники (розміри в байтах): застосунки з резервними копіями, загальна кількість екземплярів резервних копій, окремі резервні копії шляхів, заплановані завдання, загальний розмір резервних копій і вільне/загальне місце файлової системи резервних копій. Невідокремлене, повертається одразу; використовується домашнім оглядом WebUI. |
config-get |
{} |
{ok,config} |
config-set |
об'єкт config (або {key,value}) |
{ok} |
keygen |
{} |
генерує пару ключів age для шифрування |
list-apps |
{user?} |
{ok,apps:[{package,label,system,versionCode}]} (dex, запасний варіант на shell) |
label |
{package,user?} |
{ok,label} (справжня локалізована назва застосунку, без контексту) |
icon |
{package,user?,vc?} |
{ok,package,icon} (base64 PNG; кешовано на пакунок+vc) |
backup |
див. нижче |
{ok,opid} (відокремлено) |
restore |
див. нижче |
{ok,opid} (відокремлено) |
import |
{from,ref,password,ssaid,user} |
{ok,opid} (відокремлено) |
import-scan |
{from,path} |
{ok,backups:[...]} |
progress |
base64(opid) | живий progress-<opid>.json
|
cancel |
base64(opid) | {ok,cancelled} |
list-ops |
{} |
{ok,ops:[...]} (знову приєднатися після повторного під'єднання) |
list-apps/icons
|
{user?} / {user?,items:[{package,vc}]}
|
список застосунків / пакет base64-піктограм |
list-backups |
{package?} |
{ok,backups:[{ref,package,label,versionName,versionCode,created_at,mode,items}]} |
list-users |
{} |
{ok,users:[{id,name}]} користувачі Android пристрою (багатокористувацькість). |
list-dirs |
{path} |
{ok,path,parent,dirs:[...]} підтеки шляху (засіб вибору теки). |
path-list |
{user?} |
{ok,backups:[...]} окремі резервні копії теки/файлу. |
provenance |
{} |
маніфест аудиту вбудованих бінарників (PROVENANCE.json). |
backup-info |
{ref} |
{ok,...} повні деталі однієї резервної копії (версія, джерело встановлення, стан, дата, режим, розмір, елементи, лічильники дозволів, пристрій) |
backup-icon |
{ref} |
{ok,icon} base64 PNG з маніфесту (працює, коли застосунок видалено) |
delete-backup |
{ref} |
{ok,deleted} (ref має бути під текою резервних копій) |
prune |
{package,user?,keep} |
{ok,pruned:[...]} залишити N найновіших для пакунка |
log-read |
{limit?} |
{ok,entries:[...]} журнал аудиту, найновіші спершу |
log-export |
{user?} |
{ok:true,path} (абсолютний шлях записаного .txt під текою резервних копій) або {ok:false,code:"ERR_LOG_EXPORT"}. Записує журнал активності (audit.jsonl) плюс короткий заголовок збірки/пристрою в єдиний видимий користувачеві текстовий файл, щоб його можна було додати до звіту про ваду. Невідокремлене, повертається одразу. |
special-categories |
{} |
{ok,categories:[{id,available}]} (messages/contacts/wifi/bluetooth/calendar/wallpaper/dns/system_settings) |
special-backup |
{categories,compression?,password?,portable?} |
{ok,opid} загальносистемна резервна копія (відокремлено) |
special-restore |
{ref,confirm:true,categories?,password?} |
{ok,opid} (потребує перезавантаження; confirm обмежує її) |
special-list |
{} |
{ok,backups:[{ref,created_at,categories}]} |
path-backup |
{path,compression?,password?} |
{ok,opid} резервна копія будь-якого абсолютного шляху як tar.zst+manifest.json під .paths/ (відокремлено) |
path-restore |
{ref,confirm:true,password?} |
{ok,opid} відновлення резервної копії шляху до її початкового розташування (confirm обмежує її; відокремлено) |
sysmount-status |
{} |
{ok,nomount,nm,ksu,live_capable} |
sysmount-add / sysmount-del / sysmount-list
|
{package,priv?} |
монтувати встановлений застосунок як системний (безсистемний підмодуль; наживо через NoMount інакше при наступному завантаженні) |
companion-status / companion-install
|
{} |
статус компаньйона Google Drive / встановлення на вимогу |
dests-list / dest-add / dest-test / dest-del
|
{id,type,...} |
керування призначеннями |
remote-add / remote-list / remote-del
|
{name,backend,params:{...}} |
керування віддаленими rclone (створює запис rclone.conf, на який вказує призначення type:"rclone"); backend може бути будь-яким бекендом rclone, без білого списку |
remote-authorize |
{backend} |
{ok:true,url} (рушій уже відкрив браузер телефона на цій URL згоди через Android VIEW intent) або {ok:false,code:"ERR_AUTHORIZE"}. Запускає rclone authorize <backend> на локальному сервері зворотного виклику (127.0.0.1:53682) для OAuth на пристрої. |
remote-authorize-poll |
{} |
{ok:true,done:false,url} під час очікування, {ok:true,done:true,token} щойно користувач погодився (token для передачі в remote-add), або {ok:false,code:"ERR_AUTHORIZE"}. |
remote-authorize-cancel |
{} |
{ok:true,cancelled:true}; зупиняє очікувану авторизацію. |
cloud-status |
{} |
{ok,rclone,restic,fetchable,size} (чи присутні бінарники rclone/restic, чи може це видання lite їх отримати, розмір завантаження в байтах) |
cloud-fetch |
{} |
{ok,opid} (відокремлено) отримати+перевірити+встановити аддон rclone/restic у виданні lite
|
schedule-set / schedule-list / schedule-delete
|
див. нижче | заплановані завдання (резервне копіювання чи відновлення; націлене на один застосунок, набір чи всі застосунки) |
scheduler-tick |
{} |
запускає завдання, що настали + застосовує утримання + спостерігач авторезервування (це викликає серцебиття завантаження) |
update-check |
{} |
{ok,current_version,current_code,latest_version,latest_code,update_available,zipUrl,changelog,notes} (не відокремлене; повертається одразу; ERR_UPDATE_CHECK у разі невдачі, див. нижче) |
backup-batch |
{packages:[...], ...backup args} |
{ok,opid} (відокремлено) копіює багато застосунків в одній відокремленій операції; поступ несе n/of. Невдача на один застосунок не зупиняє пакет. |
restore-batch |
{refs:[...], ...restore args} |
{ok,opid} (відокремлено) відновлює багато резервних копій в одній відокремленій операції; поступ несе n/of. Невдача на один застосунок не зупиняє пакет. |
list-volumes |
{} |
{ok,volumes:[{path,removable,id?}]} томи сховища для засобу вибору теки: внутрішнє плюс знімна SD-картка / USB. |
config-export |
{password} |
{ok,opid} (відокремлено) експортує конфігурацію, завдання, призначення, облікові дані та ключі в один файл, зашифрований парольною фразою, під текою резервних копій. |
config-import |
{ref,password} |
{ok,opid} (відокремлено) зливає експортований файл конфігурації назад у цей пристрій (ніколи не перезаписує наосліп). |
config-exports |
{} |
{ok,exports:[{ref,name,size}]} перелічує зашифровані файли конфігурації, доступні для імпорту. |
wipe-credentials |
{} |
{ok,wiped} видаляє збережені віддалені паролі та ключ шифрування пристрою; призначення, завдання й резервні копії лишаються. |
log-prune |
{} |
{ok} обрізає журнали давно завершених операцій, обмежує слід аудиту й виселяє застарілі піктограми (це викликає служба завантаження). |
Опитування progress повертає живий progress-<opid>.json для операції. Ці поля
завжди присутні:
| Поле | Тип | Значення |
|---|---|---|
opid |
string | ідентифікатор операції |
percent |
int | завершеність 0-100 |
phase |
string | мітка поточної фази |
item |
string | поточний тип елемента, що обробляється |
done |
bool | true під час термінального запису (finish / dry-run / restore-test) |
Поточна операція також може нести ці опційні живі поля. Вони відсутні або порожні, коли невідомі, і опускаються під час термінальних записів (finish / dry-run / restore-test):
| Поле | Тип | Значення |
|---|---|---|
rate |
string | швидкість передачі, напр. "4.2 MiB/s" (порожнє = невідомо) |
eta |
string | орієнтовний час, що лишився, напр. "1m12s" (порожнє = невідомо) |
n |
int | індекс поточного елемента (0 = невідомо) |
of |
int | загальна кількість елементів (0 = невідомо) |
cur |
string | назва поточного елемента (порожнє = немає) |
Хмарні передачі заповнюють rate/eta (відсоток надходить від rclone); локальні резервні копії Full
заповнюють n/of/cur. Мітки фаз включають фазу запечатування контрольної суми verified і,
для хмарних передач, transfer та mirror <item>.
{
"package": "com.example.app",
"user": 0,
"mode": "full", // full | snapshot | mirror
"compression": "zstd:10", // none | lz4 | zstd[:N] | gzip
"items": ["apk","data","data_de","obb","external","media"],
"encrypt_data": false,
"encrypt_apk": false,
"dest": "local", // local | <destination id>
"verify": true, // re-hash each archive vs the manifest (default on for Full)
"dry_run": false, // true = report a size plan, write nothing
"ssaid": false, // OPT-IN, see below
"manual": false // true = single interactive backup, keeps these exact items;
// omit/false lets config.app_items (a per-app item map) override
// the set on bulk, auto and scheduled runs
}restore/import приймають {ref} (ref теки резервної копії / сканування). restore також приймає:
"items" (підмножина типів елементів резервної копії для відновлення; опустіть для всіх), "test": true
(видобути до тимчасової теки й перевірити, не зачіпаючи живого застосунку), "mode" для
snapshot/mirror, "password" для зашифрованої резервної копії, "ssaid" (за згодою) та
опції джерела встановлення "spoof_installer" (за замовчуванням із конфігурації, встановлює інсталятора на
Play Store під час встановлення) і "deep_spoof": true (просунуто, за згодою; також підробляє
пакет-ініціатор і джерело пакунка, редагуючи базу даних пакунків, застосовується після
перезавантаження). import приймає "from": "neo" | "databackup" і, для зашифрованої резервної копії Neo,
"password".
Завдання розкладу обирає одну ціль і дію:
{
"id": "nightly-games",
"action": "backup", // "backup" (default) | "restore"
"package": "com.example.app", // one app (OR)
"packages": ["com.a","com.b"], // a set of apps (OR)
"all": true, // all apps, minus the excluded-apps list
"cron": "daily", // hourly | daily | weekly
"at": "02:30", // HH:MM
"mode": "full",
"dest": "local",
"keep": 5,
"items": ["apk","data"],
"require_wifi": false, // gate: only run on Wi-Fi
"require_charging": false, // gate: only run while charging
"min_battery": 0, // gate: only run at/above this battery % (0-100)
"days": [1,2,3,4,5] // gate: only run on these weekdays (0=Sunday)
}Вкажіть точно одне з package, packages чи all для цілі. Завдання backup
зберігає звичайні mode/dest/keep/items. Завдання restore (action: "restore")
відновлює найновішу резервну копію кожного цільового застосунку (або явний ref) і перезаписує
поточні дані застосунку на кожному запуску: це навмисне й за згодою, тож встановлюйте його лише на
прямий запит користувача.
Заплановане завдання може нести опційні умови-обмеження. Коли обмеження завдання, що настало, не виконано, воно
пропускається й повторюється на наступному такті, не просуваючи свій розклад (його last_run
не проставляється, тож воно спрацьовує, щойно умова виконується):
| Поле | Тип | Обмеження |
|---|---|---|
require_wifi |
bool | запускати лише на Wi-Fi |
require_charging |
bool | запускати лише під час заряджання |
min_battery |
int (0-100) | запускати лише на цьому рівні батареї чи вище |
days |
масив int (0-6, 0=неділя) | запускати лише в ці дні тижня |
Мінімальна перевірка теплової безпеки завжди застосовується поверх цих: запланована операція
пропускається, поки пристрій критично гарячий. Кожен пропуск за обмеженням записується у слід аудиту як
op:"scheduler-gated" з reason, що дорівнює wifi / charging / battery / days /
thermal.
Хмарне призначення: це призначення type:"rclone", яке називає віддалене rclone; створіть
це віддалене спершу через remote-add. backend може бути будь-яким бекендом rclone: немає
білого списку. remote-add приймає будь-яку назву бекенда (dropbox, onedrive, box,
pcloud, mega, b2, s3, sftp, smb, webdav, ftp, drive та ~70 інших, які
підтримує rclone), а params передаються прямо в конфігурацію rclone як
пари key=value. Поля паролів зберігаються затемненими, ніколи не відкритими. Поширені бекенди
та їхні params:
sftp : host, port, user, pass smb : host, port, user, pass
ftp : host, port, user, pass webdav: url, vendor, user, pass
s3 : provider, access_key_id, secret_access_key, endpoint, region
drive : token, scope (token = output of `rclone authorize "drive"`)
OAuth на пристрої (без ПК). Бекенди, що потребують входу через браузер (Google Drive, Dropbox,
OneDrive, Box, pCloud), не потребують настільного комп'ютера чи вручну вставленого токена. Викличте
remote-authorize з {backend}: рушій запускає rclone authorize <backend> проти
локального сервера зворотного виклику (127.0.0.1:53682) і відкриває власний браузер телефона на сторінці
згоди провайдера через Android VIEW intent, повертаючи {ok:true,url} (або
{ok:false,code:"ERR_AUTHORIZE"}). Опитуйте remote-authorize-poll ({}): він повертає
{ok:true,done:false,url} під час очікування і {ok:true,done:true,token} щойно користувач
схвалить, передайте цей token у remote-add. remote-authorize-cancel ({}) зупиняє
очікувану авторизацію ({ok:true,cancelled:true}). Ручне вставляння виводу
rclone authorize "<backend>" з будь-якого комп'ютера все ще підтримується як запасний варіант.
Google Drive має два шляхи: це віддалене drive (не потрібен проєкт Google Cloud, використовує
власний OAuth rclone, авторизуйте на пристрої через remote-authorize, або запустіть
rclone authorize "drive" раз на будь-якому комп'ютері й передайте токен) або застосунок-компаньйон за згодою
(ваш власний OAuth client id). Обидва завершуються як звичайні призначення.
Поле конфігурації network_policy керує тим, яке з'єднання можуть використовувати хмарні передачі:
any (за замовчуванням), wifi або mobile. Встановіть його через config-set. Коли воно wifi чи
mobile, кожна хмарна передача (вивантаження Full rclone/Drive, синхронізація Mirror, віддалене
резервне копіювання/відновлення знімка restic, відновлення Mirror) спершу перевіряє активний транспорт і
переривається з ERR_NET_POLICY, якщо він не збігається, як для ручних, так і для запланованих завдань.
Локальні призначення ніколи не обмежуються.
-
Запечатування контрольної суми (хмара). Після успішного хмарного копіювання рушій запускає віддалену перевірку
контрольної суми (
rclone check); розбіжність провалює операцію зERR_VERIFY. Бекенди, що не мають спільного хешу з локальною стороною, пропускаються (не невдача). -
Перевірка квоти (хмара, режим Full). Перед вивантаженням у режимі Full до віддаленого
rcloneрушій запитує вільне місце віддаленого (rclone about --json) і відмовляє зERR_QUOTA, якщо резервна копія не вмістилася б. Віддалені, що не повідомляють інформації про квоту, пропускаються. Режим Mirror: це дельта-синхронізація й звільнений.
Видання full вбудовує кожен бінарник і ніколи не потребує мережі. Видання lite опускає
два найбільші, rclone і restic, і отримує їх на вимогу під час першого запуску
хмарної дії чи дії зі знімком. cloud-status повідомляє, чи вони вже присутні, чи може це
видання їх отримати, і розмір завантаження в байтах. cloud-fetch працює відокремлено (опитуйте
progress з його opid): він завантажує аддон rclone+restic для конкретної архітектури, перевіряє
його щодо SHA-256, вшитого в модуль, і встановлює його в кеш часу виконання. Його
фази поступу: downloading, verifying та installing; фінальний код: ERR_NONE
у разі успіху, або ERR_FETCH (завантаження не вдалося) / ERR_FETCH_VERIFY (розбіжність контрольної суми, відкинуто)
у разі невдачі. У виданні full він непотрібний. backup/restore до хмарного чи знімкового
призначення у виданні lite, перш ніж бінарники присутні, зазнає невдачі з
ERR_CLOUD_FETCHABLE; клієнт має запропонувати запустити cloud-fetch, потім повторити.
special-categories повідомляє, які загальносистемні категорії має пристрій; special-backup
захоплює ті, що ви передаєте в categories, а special-restore повторно застосовує їх.
Категорії такі:
| Категорія | Що це | Семантика відновлення |
|---|---|---|
messages |
SMS/MMS | заміна провайдера (wipe + extract) |
contacts |
контакти та журнал дзвінків | заміна провайдера (wipe + extract) |
wifi |
збережені мережі Wi-Fi | заміна провайдера (wipe + extract) |
bluetooth |
спарування Bluetooth | заміна провайдера (wipe + extract) |
calendar |
провайдер календаря (com.android.providers.calendar, застосунок + дані); також портативно експортовано в calendar.json
|
заміна провайдера (wipe + extract) |
wallpaper |
домашні шпалери й шпалери блокування плюс wallpaper_info.xml, збережено сирими (двійковими) |
файли замінено |
dns |
режим і специфікатор приватного DNS, зчитані з налаштувань | ідемпотентне settings put
|
system_settings |
повний дамп system/global/secure settings |
за згодою, ідемпотентне settings put, перезаписує налаштування пристрою |
system_settings строго за згодою й руйнівне під час відновлення. Як і ssaid, воно
перезаписує загальнопристрійні налаштування, коли відновлюється, тож обмежене явною згодою
користувача й записується у слід аудиту. Ніколи не обирайте його за замовчуванням; лише на прямий,
навмисний запит користувача.
path-backup / path-restore копіюють і відновлюють будь-який абсолютний шлях: теку чи
один файл, на спільному сховищі чи під /data, поза моделлю на застосунок. Архів
записується як tar.zst плюс manifest.json у власному форматі VDBackup (запечатаний SHA-256,
з набором RECOVERY, коли зашифровано) під .paths/ у теці резервних копій.
// path-backup
{ "path": "/sdcard/DCIM/Camera", "compression": "zstd:10", "password": "..." }
// path-restore
{ "ref": "<.paths ref>", "confirm": true, "password": "..." }- Вихідний шлях має бути абсолютним і під одним із дозволених коренів:
/storage/emulated,/data/media,/sdcard,/data. Шлях, що не існує, зазнає невдачі зERR_NO_PATH; шлях поза дозволеними коренями, або що містить.., зазнає невдачі зERR_BAD_PATH. -
path-restoreзаписує назад до початкового розташування, тож воно руйнівне й потребує"confirm": true, обмеження з важким тертям, якspecial-restore.ref, що не є дійсною резервною копією шляху, зазнає невдачі зERR_BAD_REF. - Обидва працюють відокремлено; опитуйте
progressз поверненимopid.
update-check повідомляє, чи опубліковано новішу версію модуля, щоб агент
(або WebUI) міг її показати. Це дієслово читання, що повертається одразу: воно не
відокремлене, тож немає opid для опитування. Запускається лише явною дією користувача, воно отримує
опублікований маніфест оновлення модуля (URL updateJson з module.prop) вбудованим
curl через HTTP-запит на боці root, це працює поза WebView, тож не підпорядковане
CSP WebUI, і порівнює опублікований versionCode зі встановленим. Воно не приймає жодних
аргументів.
У разі успіху воно повертає:
| Поле | Тип | Значення |
|---|---|---|
ok |
bool | true |
current_version |
string | встановлений versionName |
current_code |
int | встановлений versionCode |
latest_version |
string | опублікований versionName |
latest_code |
int | опублікований versionCode |
update_available |
bool |
true, коли latest_code більший за current_code
|
zipUrl |
string | опублікована URL zip |
changelog |
string | опублікована URL changelog |
notes |
string | нотатки до релізу |
Якщо немає URL updateJson, мережевий запит зазнає невдачі або маніфест неможливо розібрати, воно
повертає {"ok":false,"code":"ERR_UPDATE_CHECK"}.
update-check лише повідомляє про доступність і нотатки до релізу; саме оновлення виконує
ваш менеджер root (KernelSU / APatch / Magisk) через updateJson модуля, ніколи не це
дієслово.
-
ssaidстрого за згодою (за замовчуванням вимкнено). Воно копіює / відновлює пристроєвий ANDROID_ID, переписуючи системний файл; відновлення застосовується лише після перезавантаження, а попередній файл завжди зберігається спершу для відкату. Надсилайте"ssaid": trueлише на прямий, навмисний запит користувача, ніколи за замовчуванням. -
Дії, що змінюють стан (restore, delete, import), руйнівні й записуються в
локальний слід аудиту (
logs/audit.jsonl). Відновлення точне (wipe-then-extract), тож воно повертає застосунок до точного стану резервної копії. Підтверджуйте намір, перш ніж викликати їх. -
system_settingsза згодою й руйнівне, точно якssaid. Його відновлення перезаписує загальнопристрійні налаштування, тож надсилайте його лише на прямий запит користувача; воно обмежене явною згодою й записується у слід аудиту. -
Відновлення ідемпотентне. Сирі відновлення провайдера (messages/contacts/wifi/bluetooth/
calendar) замінюють, а не зливають, дані провайдера стираються й архів
видобувається поверх них, тож повторне відновлення тієї самої резервної копії не може дублювати рядки.
dnsтаsystem_settingsповторно застосовуються ідемпотентнимsettings put. -
Видобування архіву захищене від обходу шляху. Відновлення працює з правами root, тож
кожен архів (restore, import, special-restore, path-restore) перевіряється перед будь-яким
записом: той, чиї члени використовують абсолютні шляхи або містять
.., одразу відхиляється зERR_UNSAFE_ARCHIVE, перш ніж станеться хоч один руйнівний запис (GNU tar також працює з--no-absolute-names). Підроблений архів ніколи не може втекти зі своєї цільової теки. -
Ніколи не послаблюйте збереження (SELinux/uid/gid/режими/xattr) чи правило APK (APK
завжди стиснуті, ніколи не зашифровані, якщо не встановлено
encrypt_apk). - Вважайте вивід JSON джерелом істини; перевіряйте
ok/code, опитуйтеprogressі показуйте кодиERR_*, а не вгадуйте.
Див. ARCHITECTURE.md і FILE-STRUCTURE.md щодо внутрішньої будови.
Ця документація створена за допомогою Claude (Anthropic) і підтримується VD171. Виправлення та покращення вітаються; див. CONTRIBUTING.md.