$ ozhungu --folder Download --backend zo

Ozhungu ஒழுங்கு

An Android file organizer where a model proposes and you decide. Nothing moves until you tick it and press Apply — and Undo is one tap.

v0.7.0 · SAF or All-files access · Zo, OpenAI-compatible, or System One decision model (incl. OpenRouter) · GPL-3.0

A familiar face

v0.5 gives Ozhungu a Files-by-Google-style interface: a Browse tab with category tiles (Images, Videos, Audio, Documents, Archives, Apps), a Recent list, and long-press multi-select; a Clean tab where the model's suggestions appear as reviewable cards with an Apply N / Undo bottom bar. Same engine underneath — moves only, local guardrails, journaled undo.

Why this exists

Android file managers are good at showing you files and bad at deciding what to do with them. Cloud "smart" organizers decide for you and upload your data to do it. Ozhungu takes the third path: let a model do the tedious part — reading the pile and proposing a structure — while the phone keeps every decision local, reversible, and visible.

The loop

pick folder → scan (SAF, ≤600 files, 4 levels) → model proposes a plan ↓ undo last apply ← apply ticked rows ← local guardrails validate ←──┘
  1. Scan — a real directory walk through Android's Storage Access Framework. Names, sizes, dates, and small text snippets only. Never a full upload of your files.
  2. Propose — the model returns one JSON plan of move/rename actions, each with a reason. Or a list of new folders to create.
  3. Validate — a local, offline, pure-Kotlin validator rejects anything that escapes the folder, overwrites a file, chains onto another action's output, or isn't a move. You see every rejection with its reason.
  4. Apply — only the rows you ticked, each one journaled.
  5. Undo — the whole batch in reverse, newest first, with per-row reporting.

What it will never do

NeverBecause
Delete or trash anythingMoves and renames only. The vocabulary has no third verb.
Move a file outside the folder you picked.. and absolute paths are rejected before the model's plan is even shown to you.
Overwrite an existing fileTargets colliding with anything from the scan are rejected as rows.
Touch your files without a tapNothing is applied automatically — there is no background organiser mode.
Ask for All files accessStorage Access Framework only, so the app sees exactly the folder you granted.
Phone homeNo telemetry, no analytics, no crash reporter. One network call per plan, to the backend you configured.

Bring your own model

Three backends, same plan contract:

BackendEndpointContinuity
Zo/zo/ask (SSE, via the zo-kotlin SDK)Server-side conversation — refinements don't resend the listing
OpenAI-compatible{base}/chat/completions — OpenRouter, DeepSeek, Groq, Ollama, LM Studio, vLLM…Local transcript, in memory, last two turns
Decision model (System One)Any Jev-compatible endpoint — Cloudflare Clef / Clef-flash on Workers AI, self-hosted Clef — typed choice questions, calibrated probabilities, up to 64 files per requestSingle-shot; confidence floor leaves unsure files in place

Settings is a proper page, not a pile of dialogs: backend cards, masked keys with show-toggles, an inline Test that hits the endpoint before you commit, and a searchable model browser that reads models.dev — only providers that publish an API base URL, with zero-data-retention mentions badged ★ and sorted first. The badge is a hint from public metadata, not a contract — read it as one.

Build & verify

git clone https://github.com/LogicIncZo/ozhungu && cd ozhungu
echo "sdk.dir=/path/to/android-sdk" > local.properties
make verify     # 41 JVM tests + lint + assembleDebug
make apk        # → releases/ozhungu-latest.apk
make coverage   # JaCoCo line table

Requires JDK 17 and Android SDK 35. The Zo backend needs the sibling zo-kotlin checkout (composite build); the OpenAI-compatible backend doesn't.

The tested core — parser, validator, prompt builder, plan grammar, journal, SSE/transcript, decision-model core (97%) — sits at 94–100% line coverage. The untested remainder is UI wiring and SAF plumbing that needs a device. Details in the guide.

Known limits