ARIA
863ab34915
fix(app): apply whole-review fixes (HIGH/MEDIUM/LOW) + dead code & stale comments
...
CI / Gateway plugin tests (push) Failing after 6m35s
CI / Kotlin tests (android host + desktop) (push) Successful in 6m57s
HIGH:
- ntfy listener: replace blocking exhausted() loop with SSE read + capped
exponential-backoff reconnect; 60s read timeout
- GatewayClient.stop(): reset HTTP leg (http, httpCursor, sseFailures,
usingLongPoll, lastAck)
- non-atomic shared state -> synchronized/@Volatile/AtomicLong/
CopyOnWriteArrayList
MEDIUM:
- mediaId path-traversal guard (isValidMediaId) at network/app/fs boundaries
- loadFromCache: move ts=0 pending bubbles to end, keep stored order
- attachment placeholder tracked by identity, not filename
- optimistic ChannelStore updates on favorite/icon/automation/default
- secure-store caching (desktop map, android store)
- secret passed to keyring via stdin (macOS + Linux)
- SecureStore.clear() clears deviceId/syncCursor/fcmToken/ntfy*
- random ids for system messages; SSE EOF reconnect delay
- PowerShell $ escaping; dispose() cancels job before saving flows
- wire up "Forget pairing" in Settings
- move machine-specific org.gradle.java.home to user-level gradle.properties
LOW + dead code + stale comments:
- .aac->audio/aac; locale-fixed cost/size; 3-digit hex; hour+ latency
- Backdrop.DEFAULT defined once; notification id 24-bit; channel id cap
- remove dead FileSource, unused protocol/theme/media constants, empty
onDispose, SDK_INT<O guard, hostFromUrl
- fix stale WS/SSE, M1/M5, and milestone KDoc comments
Verified: Kotlin desktop+android host tests, 100/100 Python gateway tests,
LSP clean, installed & running on device.
2026-08-23 12:57:35 +02:00
ARIA
7a6d922d12
Add QR pairing (terminal QR, in-app scanner, iris://pair deep link)
CI / Kotlin tests (android host + desktop) (push) Successful in 8m5s
CI / Gateway plugin tests (push) Successful in 9m47s
2026-08-22 22:43:13 +02:00
ARIA
abf1374c1e
Font size setting: app-wide text scale (0.8x-1.5x, default 1.0x) via Settings > Appearance slider — applied through LocalDensity.fontScale so all sp text scales while dp layout keeps its proportions; the multiplier stacks on top of the system font scale; persisted per platform (EncryptedSharedPreferences / settings.json) like the other appearance settings
2026-08-21 08:54:48 +02:00
ARIA
7ba5632a03
HTML artifacts: render agent-sent HTML/CSS/JS code blocks in an in-app WebView (Android platform WebView, desktop JCEF/KCEF) via a full-screen preview; artifact card with Preview button + code toggle, shown only once the message stops streaming; webview-multiplatform 1.9.40 + KCEF deps, detection + unit tests
2026-08-21 00:43:39 +02:00
ARIA
37c13b4d02
Compact single-row header: tappable status bubble (green/yellow-pulsing/red) + search, status toast on tap; removed overflow menu (rename/forget)
2026-08-20 19:33:45 +02:00
ARIA
0e8f69a43c
User theme: customizable bubble colors + background (color/image) in Settings → Appearance
...
- UserTheme model (ARGB ints) + LocalUserTheme, persisted via SecureStore
- HSV color picker dialog (Apply keeps open, OK applies+closes, Cancel)
- Background: solid color or image (SAF on Android, JFileChooser on desktop)
- Reasoning block: 0.6 black overlay on agent bubble color (adapts automatically)
- Contrast-aware text on bubbles + pinned contentColor on root Surface
2026-08-20 19:14:35 +02:00
ARIA
efecf2732e
Auto-threading, history pagination, streaming toggle + tool/reasoning display settings
...
- Auto-threading (Telegram topic-mode workflow): message.send {auto_thread}
mints a fresh AI-named thread (instant derived title, LLM upgrade via
channel.renamed); channel.created {auto:true}; the app jumps into the new
thread and relocates the optimistic pending bubble.
- history frame: paged full message history for initial channel open /
scroll-up pagination (reconstructed from the outbox log).
- Streaming on/off: gateway side (display.platforms.android.streaming) plus a
per-device app toggle (Settings → Streaming); reasoning/model/tokens carried
on message frames.
- Context menu: long-press (touch) / right-click (desktop) thread affordances
via a KMP rightClick expect/actual.
- Settings → Reasoning: auto-collapse long reasoning blocks (default on).
- Tool detail: the gateway now always supplies full tool data — it forces
verbose tool progress (full args → tool.start.args) and captures each
completed call via the post_tool_call hook (output/duration/ok → tool.end).
The app reveals the full call + output on expand (Truncated) and
auto-expands cards in Everything mode.
2026-08-20 16:26:52 +02:00
ARIA
bf6bf7e8bd
M7: polish + E2E + docs (layout pass, theming, states, e2e driver, schema, setup.md, security)
2026-08-20 12:00:13 +02:00
ARIA
2ecfe1c05c
M5: push (FCM + ntfy) + offline catch-up + background notifications
...
Server (gateway-plugin):
- push.py: FCM (HTTP v1 service-account / legacy key) + ntfy backends; NtfyBackend.server_url for app discovery
- adapter.py: push on offline broadcast + high-priority push when live; fcm.register; server_caps.push_ntfy_server; outbox now ALWAYS appends so a reconnecting app catches up on live-delivered frames (fixes empty chat after notification tap / activity recreation)
- protocol.py / ws_server.py / outbox.py / plugin.yaml: M5 frames + env vars
App (Kotlin CMP):
- Protocol.kt: notification / fcm.register / sync frames + push caps
- GatewayClient.kt: hello carries push creds; auto-sync on reconnect
- IrisController.kt: banners, deep-link, notifyMessageIfBackgrounded (system notification on a regular reply when backgrounded)
- Android: PlatformPush, AppBridge, IrisNotifications, NtfyListenerService, IrisFirebaseMessagingService, AndroidPush, AndroidSecureStore
- Desktop: DesktopPush, DesktopSecureStore
- build files + manifest (permissions, services, deep-links)
Tests: 35-test tests/gateway/test_android.py suite passes (incl. new regression test_live_delivered_frame_still_parked_for_sync). E2E verified on device: push fire, reconnect sync, background notification, and message replay after ChatStore reset.
2026-08-19 19:20:55 +02:00
ARIA
218c50d688
M1+M2: gateway core loop + agent transparency
...
M1 (gateway core loop / text round-trip):
- WS server (ws_server.py): bind, hello auth (constant-time), hello.ack, heartbeat, connection registry
- pairing.py: token generation, pairing store, QR payload
- adapter.py: send() -> message frame; inbound message.send -> MessageEvent -> handle_message
- app: Connect screen, GatewayClient (connect + reconnect), ChatScreen send/render, SecureStore (Android/Desktop)
- tests/ws_probe.py: probe harness driving a real turn
M2 (streaming + reasoning + tools + commentary):
- protocol.py: M2 frame types (message.start/update/stop, tool.start/progress/end, commentary)
- adapter.py: per-chat turn-state machine; classify outbound into frames; _split_reasoning; tool-line parsing
- reasoning in streaming: capture via on_stream_delta hook (kind=reasoning, gated by plugins.stream_reasoning_deltas) with a FIFO barrier, attach to message.stop
- app: live streaming bubble, ReasoningBlock (collapse + copy), ToolCard (Everything/Truncated/Nothing), dimmed commentary, typing
- docs/14-milestones.md: M1/M2 marked done; reasoning note corrected
2026-08-19 13:56:19 +02:00
ARIA
59acf66c89
M0: toolchain, monorepo scaffold, gateway plugin skeleton, CMP app
...
- gateway-plugin/: android platform plugin (plugin.yaml + adapter.py
register(ctx) + no-op AndroidAdapter) + stub modules for M1-M5
- app/: Compose Multiplatform project (shared KMP + androidApp +
desktopApp) with Gradle wrapper; builds :androidApp:assembleDebug
and :desktopApp:compileKotlin
- scripts/guard_hermes_agent.sh + pre-commit hook: fail if hermes-agent/
is staged (read-only reference, never committed)
- .gitignore excludes hermes-agent/; docs/ reference library
2026-08-19 11:27:02 +02:00