Commit graph

7 commits

Author SHA1 Message Date
Bruno Deanoz
68721d8ddf feat: KaizenIcons system — Lucide base, full Material Icons migration
Introduces a centralized icon registry (ui/icon/KaizenIcons.kt) that
decouples every UI component from the underlying icon library. All 10
source files migrated from Material Icons Rounded to KaizenIcons backed
by Lucide (1.5px stroke, same library as the web frontend).

Architecture:
- KaizenIcons object with semantic getters (Send, Lock, Brain, etc.)
- Grouped by function (Navigation, Chat, Modes, Files, Settings, etc.)
- Custom brand section ready for hand-drawn SVG overrides
- One-line swap: change the getter, every usage updates
- Zero Material Icon imports remaining in app source

Dependency: com.composables:icons-lucide-android:1.0.0
2026-06-22 14:11:34 +02:00
Bruno Deanoz
88559bf49e biometric unlock for locked conversations
Hardware-enforced via Android KeyStore + CryptoObject:
- AES key in TEE/StrongBox with setUserAuthenticationRequired(true)
- BiometricPrompt receives Cipher as CryptoObject, unlocked only
  after real biometric auth (fingerprint/face), not bypassable
- Key auto-invalidated on biometric enrollment change

Flow: tap locked chat → BiometricPrompt → on success request
server unlock token (POST /api/v1/auth/unlock) → fetch messages
with X-Unlock-Token header → display conversation.

Dependencies: androidx.biometric:biometric:1.4.0-alpha02
2026-06-21 23:56:57 +02:00
Bruno Deanoz
9759d478a7 feat: offline-first cache layer with Room
Room 2.8.4 as local SQLite read-cache for conversations and messages.
Sidebar and chat history load instantly from cache, background refresh
syncs with the server. Streaming stays in-memory, flushed to Room after
completion. Includes ChatViewModel, repositories, mappers, TypeConverters,
and unit tests.
2026-06-21 12:50:46 +02:00
Bruno Deanoz
827a2f307c fix: streaming performance, error handling, and API diagnostics
- Eliminate recomposition hell: isolate auto-scroll via derivedStateOf + snapshotFlow
- Preserve partial response on connection drop instead of replacing with error
- O(1) incremental stream parser (StreamConsumer.Incremental) replacing O(N²) re-scan
- Parallel conversation creation via async/await to reduce TTFT
- TCP/TLS prewarm on app resume via LifecycleResumeEffect
- Surface API failures with Log.w and UI error banner instead of silent emptyList()
- Fix nullable KaizenModel.name crash in ModelSheet
2026-06-19 15:34:59 +02:00
Bruno Deanoz
44c17b6f9f feat: wire chat to the real Kaizen backend (in-app login + streaming)
Replaces the Phase-0 fakeReply mock with the real v1 API. Deployment-agnostic:
one binary, one Authorization: Bearer contract, server-URL field switches between
the official instance and any self-host.

- auth/LoginScreen: server-URL + email + password -> POST /api/v1/auth/token
- net/SecureStore: kzn_ token in EncryptedSharedPreferences (KeyStore AES-256-GCM)
- net/SessionViewModel: snapshot-state login/logout routing, restores on launch
- net/KaizenApi: POST /api/v1/chat streaming + GET /api/v1/me for the default model
- net/StreamConsumer: Kotlin port of lib/chat/stream-consumer.ts (JVM-unit-tested)
- deps: okhttp, kotlinx-serialization, security-crypto; INTERNET permission

Code-complete; not yet built/run on device (no Android SDK on the dev Mac).
2026-06-19 01:04:55 +02:00
Bruno Deanoz
4cd117e703 Redesign hero to match web (suggestion pills, date/time, mode pill row, +/call/send input); add thinking phase with phase-aware haptics; glassier orb 2026-06-18 15:49:47 +02:00
a5a6dbff61 Initial commit - Kaizen App 2026-06-18 15:08:09 +02:00