Take ktfmt's formatting on the files just added

Four files went in unformatted: I ran the formatter mid-change and then
kept editing. ktfmtCheck is part of finishing, not part of starting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-08-29 06:28:24 -04:00
1 parent d580461bd5
commit 8fe13634cb
4 files changed
+39 -21

No files matched your search

@@ -29,8 +29,7 @@ sealed class SessionEvent {
val options: List<String>, val options: List<String>,
/** The tool call this is permission for, or null when it is not about one. */ /** The tool call this is permission for, or null when it is not about one. */
val about: String?, val about: String?,
) : ) : SessionEvent()
SessionEvent()
data class Answered(val id: String, val answer: String) : SessionEvent() data class Answered(val id: String, val answer: String) : SessionEvent()
@@ -15,12 +15,12 @@ import androidx.compose.ui.unit.dp
/** /**
* An assistant's reply, with anything it says it remembered drawn as a note rather than as markup. * An assistant's reply, with anything it says it remembered drawn as a note rather than as markup.
* *
* Claude Code marks a sentence that came from its stored memory by wrapping it in * Claude Code marks a sentence that came from its stored memory by wrapping it in `<cc-memory
* `<cc-memory filenames="...">`. Markdown has nothing to say about that, so it arrived on screen as * filenames="...">`. Markdown has nothing to say about that, so it arrived on screen as literal
* literal angle brackets in the middle of a sentence -- which reads as the model having emitted * angle brackets in the middle of a sentence -- which reads as the model having emitted broken
* broken HTML. It is really the opposite: a claim about where something came from, which is worth * HTML. It is really the opposite: a claim about where something came from, which is worth showing,
* showing, because "I was told this before" and "I worked this out just now" are different things * because "I was told this before" and "I worked this out just now" are different things and the
* and the reader cannot otherwise tell them apart. * reader cannot otherwise tell them apart.
* *
* A tag that has not finished arriving is left alone. Streaming means the closing tag may be * A tag that has not finished arriving is left alone. Streaming means the closing tag may be
* seconds away, and a half-written marker is not a marker yet. * seconds away, and a half-written marker is not a marker yet.
@@ -81,8 +81,7 @@ fun splitMemoryNotes(text: String): List<MessagePart> {
for (match in MEMORY_NOTE.findAll(text)) { for (match in MEMORY_NOTE.findAll(text)) {
val before = text.substring(at, match.range.first) val before = text.substring(at, match.range.first)
if (before.isNotBlank()) parts += MessagePart.Prose(before.trim()) if (before.isNotBlank()) parts += MessagePart.Prose(before.trim())
val files = val files = match.groupValues[1].split(",").map { it.trim() }.filter { it.isNotEmpty() }
match.groupValues[1].split(",").map { it.trim() }.filter { it.isNotEmpty() }
parts += MessagePart.Remembered(match.groupValues[2].trim(), files) parts += MessagePart.Remembered(match.groupValues[2].trim(), files)
at = match.range.last + 1 at = match.range.last + 1
} }
@@ -84,8 +84,8 @@ sealed class TranscriptItem {
* *
* On the call's own row rather than beside it: the ask used to arrive as a second card * On the call's own row rather than beside it: the ask used to arrive as a second card
* repeating the input verbatim, so the reader saw the same command twice and had to work * repeating the input verbatim, so the reader saw the same command twice and had to work
* out that it was one event. The backend says which call a permission is about, so this * out that it was one event. The backend says which call a permission is about, so this is
* is a fact rather than a match on the input. * a fact rather than a match on the input.
*/ */
val ask: QuestionCard? = null, val ask: QuestionCard? = null,
) : TranscriptItem() ) : TranscriptItem()
@@ -138,7 +138,10 @@ fun foldEvent(items: List<TranscriptItem>, event: SessionEvent): List<Transcript
// A question with no tool behind it -- AskUserQuestion, or an ask // A question with no tool behind it -- AskUserQuestion, or an ask
// whose call fell outside the loaded window -- is a card of its // whose call fell outside the loaded window -- is a card of its
// own, which is what every question was before this. // own, which is what every question was before this.
if (event.about != null && items.any { it is TranscriptItem.ToolRun && it.id == event.about }) { if (
event.about != null &&
items.any { it is TranscriptItem.ToolRun && it.id == event.about }
) {
updateTool(items, event.about) { it.copy(ask = card) } updateTool(items, event.about) { it.copy(ask = card) }
} else { } else {
items + card items + card
@@ -28,8 +28,8 @@ import org.json.JSONObject
* Every tool's input arrives as JSON, and showing it raw makes the reader parse `{"command":"…", * Every tool's input arrives as JSON, and showing it raw makes the reader parse `{"command":"…",
* "timeout":120000}` themselves to find the one line they care about. So the fields that carry the * "timeout":120000}` themselves to find the one line they care about. So the fields that carry the
* meaning are pulled out -- the command a shell will run, what it is for, how long it may take -- * meaning are pulled out -- the command a shell will run, what it is for, how long it may take --
* and anything left over is still shown, because dropping a field would be claiming the tool has * and anything left over is still shown, because dropping a field would be claiming the tool has no
* no other input when it might. * other input when it might.
*/ */
data class ToolInput( data class ToolInput(
/** The thing that will actually be run or read, if this tool has one. */ /** The thing that will actually be run or read, if this tool has one. */
@@ -70,13 +70,21 @@ fun parseToolInput(tool: String, input: String): ToolInput {
} catch (_: org.json.JSONException) { } catch (_: org.json.JSONException) {
// Not an object: older transcripts and some tools send a bare // Not an object: older transcripts and some tools send a bare
// string. It is still the input, so it is still shown. // string. It is still the input, so it is still shown.
return ToolInput(null, null, null, input.takeIf { it.isNotBlank() }?.let { listOf(it) }.orEmpty()) return ToolInput(
null,
null,
null,
input.takeIf { it.isNotBlank() }?.let { listOf(it) }.orEmpty(),
)
} }
val (subjectKey, language) = SUBJECTS[tool] ?: (null to null) val (subjectKey, language) = SUBJECTS[tool] ?: (null to null)
val subject = subjectKey?.let { json.optString(it) }?.takeIf { it.isNotBlank() } val subject = subjectKey?.let { json.optString(it) }?.takeIf { it.isNotBlank() }
val description = DESCRIPTIONS.firstNotNullOfOrNull { json.optString(it).takeIf { v -> v.isNotBlank() } } val description = DESCRIPTIONS.firstNotNullOfOrNull {
json.optString(it).takeIf { v -> v.isNotBlank() }
}
val rest = val rest =
json.keys() json
.keys()
.asSequence() .asSequence()
.filter { it != subjectKey || subject == null } .filter { it != subjectKey || subject == null }
.filter { it !in DESCRIPTIONS || description == null } .filter { it !in DESCRIPTIONS || description == null }
@@ -107,7 +115,9 @@ fun ToolInputView(tool: String, input: String, modifier: Modifier = Modifier) {
fontFamily = FontFamily.Monospace, fontFamily = FontFamily.Monospace,
softWrap = false, softWrap = false,
modifier = modifier =
Modifier.padding(top = 4.dp).fillMaxWidth().horizontalScroll(rememberScrollState()), Modifier.padding(top = 4.dp)
.fillMaxWidth()
.horizontalScroll(rememberScrollState()),
) )
} }
parsed.rest.forEach { parsed.rest.forEach {
@@ -136,14 +146,21 @@ private fun highlighted(code: String, language: SyntaxLanguage?): AnnotatedStrin
return remember(code, language, theme, plain) { return remember(code, language, theme, plain) {
if (language == null) return@remember AnnotatedString(code) if (language == null) return@remember AnnotatedString(code)
val marks = val marks =
Highlights.Builder(code = code, language = language, theme = theme).build().getHighlights() Highlights.Builder(code = code, language = language, theme = theme)
.build()
.getHighlights()
buildAnnotatedString { buildAnnotatedString {
append(code) append(code)
marks.forEach { mark -> marks.forEach { mark ->
when (mark) { when (mark) {
is ColorHighlight -> is ColorHighlight ->
addStyle( addStyle(
SpanStyle(color = androidx.compose.ui.graphics.Color(mark.rgb or 0xFF000000.toInt())), SpanStyle(
color =
androidx.compose.ui.graphics.Color(
mark.rgb or 0xFF000000.toInt()
)
),
mark.location.start, mark.location.start,
mark.location.end, mark.location.end,
) )