This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
Clearport is a chat client for an AI model that runs on the phone in your hand.
Two pieces, one loopback socket:
-
The Android app (Flutter): streaming replies, conversations saved on device, a live status dot that polls
/models, a dynamic model picker fed by that list, and settings for the server URL, model ID, API key, system prompt, and temperature. -
The Termux CLI (
clearport): startsllama-serveron127.0.0.1:8080, takes an Android wake lock so the system does not kill background inference, and provides interactive terminal chat if you never open the Flutter app at all.
Neither piece bundles weights, and neither requires an account. The only HTTP request the app ever makes is to the address you specify in Settings, and the default is loopback (127.0.0.1:8080).
I read "Ghost in the Machine" literally first: the ghost is the model, a disembodied voice answering prompts. For almost everyone in 2026, that voice lives in an offshore datacenter behind a closed API, running on rented GPUs that can be gated behind a pricing change or killed with a service deprecation.
Then I read it the other way, and that is what I built. Move the ghost inside the machine, and it stops being a haunting—it becomes a resident. Put the phone in aeroplane mode, cut all radios, and it still answers. The spooky part of AI is not that it talks to you; it is that it talks to you from somewhere else. Clearport makes it talk to you from right here.
So I gave the ghost a home. Clearport ships seven tailored themes, each a full semantic palette: Haunted, Clean, Dark, AMOLED, Midwinter, Ofrenda, and System.
Haunted is the theme crafted for this challenge. It is pure #000000—true OLED black. The accent is pumpkin orange. Cobwebs cling to the top corners, and a spider drops from the ceiling on silk. The empty state features a carved glowing jack-o'-lantern with slanted eyes and an atmospheric prompt: "Something is listening on 127.0.0.1." Because something truly is.
The artwork is vector-drawn in code: PumpkinPainter, SnowflakePainter, MarigoldPainter, and SpiderWebPainter are Flutter CustomPainters. Crisp at every screen density, recolouring dynamically with the palette, and adding zero bloated image assets to the binary.
Demo
Aeroplane mode is the demo. Wi-Fi off, mobile data off, bluetooth off, no hotspot, no laptop tether. Send a prompt and watch tokens stream one by one from a model running in Termux on the same device over loopback:

🎬 Watch Full 1080p Walkthrough Video (clearport-demo.mp4)
The CLI flow runs with equal simplicity in Termux:
clearport pull gemma-tiny # 292 MB Gemma 3 270M, SHA-256 verified
clearport start # starts llama-server on 127.0.0.1:8080 with wake-lock
clearport chat # instant terminal chat session
clearport haunt # the local model inspects your recent bash history
Code
- Android App: github.com/Adams-404/clearport (MIT, Flutter)
- Companion CLI: github.com/Adams-404/clearport-cli (MIT, Bash)
Testing Instructions for Judges:
No login required. No API keys, no signups, no cloud credentials. You can install the release APK directly from GitHub Releases (v1.0.4) or run the one-line Termux installer on an Android device.
How I Built It
Open weights and inference: llama.cpp powers local inference. Gemma 3 is the primary benchmark: clearport pull gemma downloads the 1B Q4_K_M weights (806 MB), while clearport pull gemma-tiny fetches the 270M Q8_0 weights (292 MB) for memory-constrained phones. Downloads support resume and verify byte sizes and SHA-256 hashes against Google's published specifications before use. Any OpenAI-compatible GGUF server also works seamlessly.
Design system: Themes are built on Flutter's ThemeExtension rather than switch statements. Surfaces, text styles, code blocks, borders, and custom painters derive from an AppPalette accessed via context.palette. Switching themes recalculates one inherited value and cleanly repaints the entire tree, including the frosted liquid-glass history modal.
Streaming SSE reliability: Building robust mobile streaming over loopback required solving three tricky edge cases:
-
TCP chunk boundary splits: SSE
data:payloads frequently arrive split across TCP packets. The parser buffers until complete event delimiters arrive and safely flushes remaining tokens on close. - Android lifecycle suspensions: Android suspends activities when backgrounded. Clearport maintains read buffers across transitions rather than dropping active requests.
- Atomic persistence: Conversations are stored in the app's sandboxed document store using atomic writes (writing to a temporary file before renaming) to eliminate corruption from sudden process death.
-
Written lifecycle contract:
docs/lifecycle.mddocuments exact recovery guarantees across backgrounding, low-memory kills, and restart states.
flutter analyze is completely clean and 72 automated tests pass, verifying the stream parser, URL normalizer, secure settings, history search, theme system, model discovery picker, and lifecycle contracts. GitHub Actions automates APK packaging, test suites, and cryptographic signing.
Agent collaboration: Clearport was developed iteratively using an AI coding agent pair-programming setup. Every phase was tracked as an explicit GitHub milestone issue with formal acceptance criteria, verified through test runs, committed, and closed upon push.
Why Does Open Innovation Matter?
Every core capability in Clearport relies directly on open innovation:
- Works with the lights (and internet) off: No external server dependency. If a storm hits or you are at 35,000 feet, inference never halts.
-
Your prompts never leave your pocket: Android's network security configuration is restricted to cleartext HTTP on
127.0.0.1andlocalhost; remote endpoints enforce HTTPS. Your thoughts, logs, and questions never reach an external telemetry aggregator. -
Protocol neutrality: The parser natively understands OpenAI delta streams, Ollama JSON envelopes (
{"message":...}/{"response":...}), NDJSON, and raw text lines. You are never locked into a single server vendor. -
Readable and auditable: Clearport avoids bloated state frameworks in favour of clean
ChangeNotifierandInheritedWidgetpatterns across concise Dart files. - Memory that outlives vendors: Chat histories belong to you. When hosted AI platforms sunset models or alter account terms, user conversations vanish. On Clearport, conversations are local JSON files under your control.
My Agent Session
Interactive session transcript: Building Clearport — Hacktoberfest Week 4: Ghost in the Machine
The build followed a structured phase plan tracked across GitHub issues (#45 through #51): scoping the themes, drawing painters, handling lifecycle states, validating Gemma downloads, producing demo media, and automating releases. Working with a pair-programming agent with clear acceptance criteria ensured that architecture decisions remained disciplined and every feature shipped with test coverage.
The Spirit of It
The moment this project clicked was in a dark room with a black screen: the Haunted theme active, two painted cobwebs in the corners, a spider suspended on thread, a pumpkin grinning in the centre, and the phrase: "Something is listening on 127.0.0.1."
The second moment was clearport haunt: pointing the local model at the phone's recent shell history, having an offline Gemma model analyze the last few commands typed into Termux, and offering dry, eerie commentary.
There is also a Día de los Muertos connection in the Ofrenda theme (marigolds, deep plum, and candlelight). Conversations and thoughts are personal history. Keeping them on hardware you own is how you ensure they are never lost.
Prize Categories
Best Use of Gemma
Clearport natively supports Google's Gemma 3 open-weight models as its primary recommendation for mobile on-device inference:
-
clearport pull gemma: Downloads Gemma 3 1B (Q4_K_M, 806 MB), ideal for devices with 4GB+ RAM. -
clearport pull gemma-tiny: Downloads Gemma 3 270M (Q8_0, 292 MB), purpose-fit for ultra-lightweight, battery-efficient inference on low-spec phones. - All downloads are checksum-validated against Google's published SHA-256 signatures and configured automatically for Termux
llama-serverexecution.



Top comments (0)