Read a timeout in units, share one usage answer, and let a tilde mean home

The composer's settings row is outlined bubbles opening round menus, and
the message box is a TextFieldValue so anything put into it without being
typed -- a draft, a share, a slash command -- leaves the cursor at the end.

A tap that puts a text selection away no longer also collapses the card the
text was drawn in: every open and close on the session screen goes through
one guard that spends such a press on the selection.

The usage bar and the usage dialog were two polls of one measurement and
disagreed for up to a minute at a time; they are one feed now, and the
countdown rounds up to the minute in the one place both read.

A working directory typed as ~/repos/ai-app was four literal characters on
the local transport and as an argument on both, so the existence check
refused every home-relative path. It is checked by entering the directory
now, expanded for a local spawn the way the remote shell expands it, and
stored short so the phone draws what somebody would write.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-03 19:56:36 -04:00
1 parent 2970a6cf9a
commit 32b2a4871a
16 files changed
+414 -99

No files matched your search

@@ -31,8 +31,8 @@ data class ToolInput(
/** The tool's own one-line summary, when it wrote one. */
val description: String?,
/**
* How long the call may take, as the tool expressed it. Shown apart because it is a limit on
* the call rather than part of what the call does.
* How long the call may take, in the largest units it fits ([formatMillis]). Shown apart
* because it is a limit on the call rather than part of what the call does.
*/
val timeout: String?,
/** Everything else, as `name: value` lines. Never dropped. */
@@ -84,7 +84,7 @@ fun parseToolInput(tool: String, input: String): ToolInput {
val description = DESCRIPTIONS.firstNotNullOfOrNull {
json.optString(it).takeIf { v -> v.isNotBlank() }
}
val timeout = json.optString("timeout").takeIf { it.isNotBlank() }
val timeout = json.optString("timeout").takeIf { it.isNotBlank() }?.let { formatMillisText(it) }
val rest =
json
.keys()