Attach any file, take shares from other apps, and survive a backwards highlight
Attachments were images only. Now any file can be attached: from the file chooser behind the "+" menu, or from Android's share sheet, which the app is now in. An image still goes to the model as a picture; anything else is stored under its own name (`<hex>-<name>`, cleaned by `safe_file_name`) and the Claude driver ends the message with `Attached file: /abs/path`, since the CLI reads files by path and a model cannot be shown a trace. The user-message field is renamed `images` -> `attachments` on both sides, with a serde alias reading the rows written before. A share arrives before anyone has said which session it is for, so it is held in AppRoot with a banner on the list until a session takes it; an open session takes it at once. Unreadable shares are reported beside the composer, not thrown. The tool card crashed the app when opened on a command holding a quoted glob such as `-path '*/.git/*'`: highlights 1.1.0's shell lexer answers `x '*/a/*'` with a span whose end is before its start, and AnnotatedString refuses the range. Such spans are dropped; the library is the place for the fix. The echo driver gains `/bash <command>` so a card with a given command can be produced on the emulator. ui-sandbox.sh's token salvage read the tokens block's close only at a line start, ran past the compact `),],` the server writes, and copied `setups` into the new config twice, which the server then refused. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
4bc69e8f9c
commit
6180663f14
25 files changed
+672
-165
No files matched your search
@@ -37,6 +37,10 @@ class MainActivity : ComponentActivity() {
|
||||
private var openRequest by mutableStateOf<SessionOpenRequest?>(null)
|
||||
private var opens = 0
|
||||
|
||||
// What another app shared into this one, for the same reason and with the same serial.
|
||||
private var shareRequest by mutableStateOf<ShareRequest?>(null)
|
||||
private var shares = 0
|
||||
|
||||
// Registered up front since permission launchers must be registered
|
||||
// before the activity reaches STARTED.
|
||||
private val requestLocalNetworkPermission =
|
||||
@@ -139,7 +143,7 @@ class MainActivity : ComponentActivity() {
|
||||
// scoped to what actually moves.
|
||||
.navigationBarsPadding()
|
||||
) {
|
||||
AppRoot(settingsVersion, openRequest)
|
||||
AppRoot(settingsVersion, openRequest, shareRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,14 +159,21 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The one place an incoming `aiapp://` URI is sorted into what it means.
|
||||
* The one place an incoming intent is sorted into what it means.
|
||||
*
|
||||
* Two things arrive this way -- an enrollment code and a notification naming a session -- and
|
||||
* they are told apart by the URI's host rather than by two entry points, so a third kind is a
|
||||
* branch here rather than another intent to remember to handle.
|
||||
* Three things arrive this way -- a share from another app, and an `aiapp://` URI that is
|
||||
* either an enrollment code or a notification naming a session. The URIs are told apart by host
|
||||
* rather than by two entry points, so a further kind is a branch here rather than another
|
||||
* intent to remember to handle.
|
||||
*/
|
||||
private fun handleIntent(intent: Intent?) {
|
||||
val uri = intent?.data ?: return
|
||||
intent ?: return
|
||||
sharedContent(intent, shares + 1)?.let { shared ->
|
||||
shares = shared.serial
|
||||
shareRequest = shared
|
||||
return
|
||||
}
|
||||
val uri = intent.data ?: return
|
||||
val sessionId = notifiedSessionId(uri)
|
||||
if (sessionId != null) {
|
||||
opens++
|
||||
|
||||
Reference in new issue
Block a user