Add workflow system that lets users describe automations in natural
language through the same input field. The server LLM classifies
input as either an immediate goal or a workflow rule, then:
- Parses workflow descriptions into structured trigger conditions
- Stores workflows per-user in Postgres
- Syncs workflows to device via WebSocket
- NotificationListenerService monitors notifications and triggers
matching workflows as agent goals
Also cleans up overlay text and adds network security config.
CIO uses Java NIO selectors which Android's power management freezes
when the app is backgrounded, dropping the WebSocket connection. OkHttp
is Android-native and maintains connections through the OS network stack.
- Add draggable agent overlay pill (status dot + step text + stop button)
that shows over other apps while connected. Fix ComposeView rendering
in service context by providing a SavedStateRegistryOwner.
- Add stop_goal protocol message so the overlay/client can abort a
running agent session; server aborts via AbortController.
- Persist screen-capture consent to SharedPreferences so it survives
process death; restore on ConnectionService connect and Settings resume.
- Query AccessibilityManager for real service state instead of relying
on in-process MutableStateFlow that resets on restart.
- Add overlay permission checklist item and SYSTEM_ALERT_WINDOW manifest
entry.
- Filter DroidClaw's own overlay nodes from the accessibility tree so the
agent never interacts with them.
Railway proxy closes idle DB connections after ~60s, causing
CONNECTION_CLOSED errors on stale sockets. Set idle_timeout=20s and
max_lifetime=5m so postgres-js recycles connections before they die.
Also fix sendCommand to fall back to persistent device ID on reconnect.
DataStore flow re-emissions were resetting editingApiKey via remember(apiKey),
hiding the save button mid-edit. Now uses null sentinel to track edit state
independently from stored value.
- Make screen capture permission and battery optimization states reactive
- Add lifecycle observer to refresh battery status on resume
- Add lifecycle-runtime-compose dependency for non-deprecated LocalLifecycleOwner
- Replace deprecated LocalLifecycleOwner import
- Remove unused REQUEST_CODE constant
- Use KTX createBitmap() and bitmap[x,y] extensions
- Add misc.xml and junie.xml to .gitignore
- Android: fetch installed apps via PackageManager, send to server on connect
- Android: add QUERY_ALL_PACKAGES permission for full app visibility
- Android: fix duplicate Intent import, increase accessibility retry window
- Android: default server URL to ws:// instead of wss://
- Server: store installed apps in device metadata JSONB
- Server: inject installed apps context into LLM prompt
- Server: preprocessor resolves app names from device's actual installed apps
- Server: add POST /goals/stop endpoint with AbortController cancellation
- Server: rewrite session middleware to direct DB token lookup
- Server: goals route fetches user's saved LLM config from DB
- Web: show installed apps in device detail Overview tab with search
- Web: add Stop button for running goals
- Web: replace API routes with remote commands (submitGoal, stopGoal)
- Web: add error display for goal submission failures
- Shared: add InstalledApp type and apps message to protocol
- Add device/session/step DB persistence in server agent loop
- Add goal preprocessor for compound goals (e.g., "open YouTube and search X")
- Add step-level logging to agent loop
- Fix dashboard WebSocket auth (direct DB token lookup instead of auth.api)
- Fix web layout to use locals.session.token instead of cookie
- Add dashboard-ws.svelte.ts WebSocket store with auto-reconnect
- Rewrite devices page with direct DB queries and real-time updates
- Add device detail page with live step display and session history
- Add Android companion app resources, themes, and screen capture consent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>