ea2da0896d751e6dbf9ec53d4e03da8d1a964722
Tapping a notification landed on whatever the app was last showing. It now opens the session it named. The id rides in the intent's data rather than an extra, because PendingIntent identity is Intent.filterEquals -- with an extra every session's notification would share one PendingIntent and every tap would open whichever session was notified last. MainActivity sorts the aiapp:// URI by host, so enrollment and this are one entry point rather than two. The notification carries only an id, so the session is fetched before there is a screen; a fetch that fails says so and offers to try again, since somebody deliberately tapped and an app that opens to the list explains nothing. That made session-to-session navigation reachable for the first time, and it crashed: SessionScreen remembers a transcript and an event stream, and without a key Compose kept both across the change and merged two conversations into duplicate list keys. Keyed on the session id. The two transcript dividers now say only what they are, centred between two rules: "Compacted <bullet> 128,402 -> 9,617 tok" in blue, and "Context cleared" in red. The rules stay the ordinary divider colour -- they are framing, and the words are what carries the meaning. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Languages
Rust
54%
Kotlin
43.6%
Shell
2.4%