Thin the app's comments

The same pass the server had, on the Kotlin side: comments restating what
the code says are gone, and the ones recording a measurement, a constraint
or an incident are kept but cut to a few lines each. 6540 comment lines to
5674, and 920 lines off the app.

Two doc comments had drifted onto the item above the one they describe --
`contextAfter`'s onto `sessionWorking` in Events.kt, and `UsageMonitor`'s
equivalent on the server was fixed in the previous commit. Each is back on
its own item, which is the only non-comment line this diff moves.

The comments are reflowed to the column limit at their own indentation:
several were written wide, and ktfmt re-wrapped them into lines holding a
single orphan word. `/tmp` script, not kept -- ktfmt is idempotent over the
result, which is the check.

Left alone deliberately: this codebase's remaining comment density is high
because the comments carry things the code cannot say -- what a null means,
what a number was measured against, which bug a guard exists for. Of the
238 one-line doc comments in the app, five were pure restatement of the
name and were removed; the rest each say something the signature does not.

ktfmtFormat, compileDebugKotlin, lintDebug and testDebugUnitTest pass;
cargo test (127), clippy --all-targets and fmt still clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-04 16:20:16 -04:00
1 parent 79682f03a7
commit edc39c7371
68 files changed
+2077 -2997

No files matched your search

@@ -39,14 +39,11 @@ import kotlinx.coroutines.withContext
* controls and hid the thing they act on.
*
* The model and the permission mode are deliberately still on the session's own bar, because those
* are changed *while* reading a turn -- "not this model, try that one" -- and a control belongs
* with the thing it acts on.
* are changed *while* reading a turn -- "not this model, try that one".
*
* Captions are for what a control costs rather than for what it is. Each control is a labelled noun
* with a switch or a field beside it, and a paragraph under every one of them made the dialog
* longer than the conversation it covers -- so Notifications has none, while Move and Reload do,
* because what those two take away is not visible from here. Failures get their words for the same
* reason: they are what the reader cannot work out by looking.
* Captions are for what a control costs rather than for what it is. A paragraph under every control
* made the dialog longer than the conversation it covers -- so Notifications has none, while Move
* and Reload do, because what those two take away is not visible from here.
*/
@Composable
fun SessionSettingsDialog(
@@ -66,7 +63,7 @@ fun SessionSettingsDialog(
onDismiss: () -> Unit,
/**
* Copies what this session costs to draw. Built by the session screen, because everything it
* measures is that screen's own state -- see `copyRenderReport` there.
* measures is that screen's own state.
*/
onCopyRenderReport: () -> Unit,
) {
@@ -76,16 +73,14 @@ fun SessionSettingsDialog(
var error by remember { mutableStateOf<String?>(null) }
// Null until the server has been asked. The row this dialog was opened over is a snapshot of
// whenever the list was last fetched, so drawing the switch straight from it would show a
// position that may have been changed since -- from here or from another device -- with
// nothing to say so. Until the answer arrives the switch is disabled and a spinner sits beside
// it, which is what not knowing looks like: distinguishable from off, and from a refusal.
// position that may have been changed since. Until the answer arrives the switch is disabled
// and a spinner sits beside it, which is what not knowing looks like.
var notify by remember(sessionId) { mutableStateOf<Boolean?>(null) }
var notifyError by remember { mutableStateOf<String?>(null) }
// Where the session works. Null until the server has been asked, for the same reason the
// switch above is: the row this dialog opened over is a snapshot, and a path drawn from it
// could be one somebody changed from another device. An empty answer is a session that was
// never given a directory, which is not the same as one whose directory is unknown -- the
// field is only enabled once one of those two is settled.
// Where the session works. Null until the server has been asked, for the same reason the switch
// above is. An empty answer is a session that was never given a directory, which is not the
// same as one whose directory is unknown -- the field is only enabled once one of those is
// settled.
var cwd by remember(sessionId) { mutableStateOf<String?>(null) }
var typedCwd by remember(sessionId) { mutableStateOf("") }
var cwdError by remember { mutableStateOf<String?>(null) }
@@ -98,8 +93,8 @@ fun SessionSettingsDialog(
cwd = fresh.cwd.orEmpty()
typedCwd = fresh.cwd.orEmpty()
} catch (e: ApiException) {
// Left unknown rather than falling back to the stale row: the switch stays
// disabled, instead of offering a position nothing confirmed.
// Left unknown rather than falling back to the stale row: the switch stays disabled,
// instead of offering a position nothing confirmed.
notifyError = e.message
notify = null
}
@@ -131,8 +126,8 @@ fun SessionSettingsDialog(
}
// Moved optimistically so the switch answers the finger that moved it, and put back if the
// request is refused -- a switch that waits for a round trip reads as broken on a slow
// tunnel, and one that stays moved after a refusal lies.
// request is refused -- a switch that waits for a round trip reads as broken on a slow tunnel,
// and one that stays moved after a refusal lies.
fun setNotify(wanted: Boolean) {
val was = notify
notify = wanted
@@ -162,7 +157,7 @@ fun SessionSettingsDialog(
onRenamed(chosen)
} catch (e: ApiException) {
// Reported here, where it happened, because this dialog is the only place that
// knows a rename was attempted -- the session behind it shows nothing about it.
// knows a rename was attempted.
error = e.message
saving = false
}
@@ -181,8 +176,8 @@ fun SessionSettingsDialog(
singleLine = true,
enabled = !saving,
modifier = Modifier.fillMaxWidth(),
// The keyboard's own action does what the button does: a one-field form
// where the return key does nothing is a form people press return at anyway.
// The keyboard's own action does what the button does: a one-field form where
// the return key does nothing is a form people press return at anyway.
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { save() }),
)
@@ -207,8 +202,8 @@ fun SessionSettingsDialog(
enabled = notify != null,
)
}
// Beside the switch that failed, not with the rename's error: they are two
// requests and a reader has to be able to tell which one the server refused.
// Beside the switch that failed, not with the rename's error: they are two requests
// and a reader has to be able to tell which one the server refused.
notifyError?.let {
Text(
it,
@@ -225,9 +220,9 @@ fun SessionSettingsDialog(
value = typedCwd,
onValueChange = { typedCwd = it },
label = { Text("Working directory") },
// What the field cannot say by being empty: a session that was never
// given one starts wherever its launcher does, and this names that
// rather than showing a path nobody chose.
// What the field cannot say by being empty: a session that was never given
// one starts wherever its launcher does, and this names that rather than
// showing a path nobody chose.
placeholder = { Text("wherever the session was started") },
singleLine = true,
enabled = cwd != null && !movingCwd,
@@ -247,9 +242,8 @@ fun SessionSettingsDialog(
}
}
// The whole of what pressing Move does, where it is about to be pressed. A
// directory is settled when the process is spawned, so there is no changing one
// under a running session -- it is ended, and the next thing said to the session
// starts it in the new place.
// directory is settled when the process is spawned, so it is ended and the next
// thing said to the session starts it in the new place.
Text(
"Moving stops the session's process. It starts again in the new directory " +
"with the next message, or with Start.",
@@ -269,10 +263,10 @@ fun SessionSettingsDialog(
modifier = Modifier.fillMaxWidth(),
) {
Text("Transcript", modifier = Modifier.weight(1f))
// The size is what the button discards, and the unknown state is drawn
// rather than guessed: a spinner while the directory is being measured, and
// words when there is nothing there, because "nothing cached" and "0 B" read
// as different claims.
// The size is what the button discards, and the unknown state is drawn rather
// than guessed: a spinner while the directory is being measured, and words when
// there is nothing there, because "nothing cached" and "0 B" read as different
// claims.
when {
cachedBytes == null ->
CircularProgressIndicator(
@@ -325,8 +319,8 @@ fun SessionSettingsDialog(
}
}
},
// Disabled rather than absent while there is nothing to save: a button that comes and
// goes makes its own presence the signal, and its absence cannot say why.
// Disabled rather than absent while there is nothing to save: a button that comes and goes
// makes its own presence the signal, and its absence cannot say why.
confirmButton = {
TextButton(onClick = { save() }, enabled = changed && !saving) {
Text(if (saving) "Saving..." else "Save")