Delete and import sessions in batches, and say which rows are busy
Clearing out imported sessions was one confirmation dialog per row, which is why it was not worth doing. Holding a row on the import screen now selects it and plain taps add more; Delete and Import act on the whole selection from a bar along the bottom. Submitting hands the work over and puts the screen back as it was: the selection clears, the bar goes, and what says the work is happening is the rows it is happening to -- the one in flight marked with its operation, the rest marked "waiting". Both are inert, so a queued row cannot be tapped into starting a second CLI behind the batch already coming for it. Rows leave as each one lands rather than all at the end, because a finished row still sitting there looks exactly like one that was never imported; the rows below it therefore move, so a row that has just moved ignores taps for half a second. That busy appearance is one composable shared with the session list, which had its own dimmed row and its own word for it. It is a word rather than a bare spinner because deleting and importing differ in kind. Deleting a session can now take the machine's own transcript with it, as a switch in the confirmation and only where the driver keeps a record this app's delete cannot otherwise reach. Off by default, since leaving that copy is what makes an ordinary delete recoverable -- and the paragraph is rewritten rather than appended to when it is on, because the sentence promising the conversation is still there to import again is exactly the one the switch makes false. The server removes the machine's copy first, so a machine it cannot reach leaves the session where it was. `app/ui-sandbox.sh` is how all of this was driven: a second server with its own $HOME, invented transcripts and a two-line `claude`. Against the ordinary server, testing delete deletes somebody's conversation and testing import spends a turn on a real account.
This commit is contained in:
1 parent
21d22f89c2
commit
fd2e1d0798
8 files changed
+960
-296
No files matched your search
@@ -203,6 +203,33 @@ first if a remote spawn ever mangles an argument.
|
||||
and lint, the app-side equivalent of the line above. Then `./build-apk.sh`
|
||||
to produce the APK to install on a phone (through Dev Updater), or
|
||||
`./run-android.sh` to build, install, and launch on the emulator.
|
||||
- **A row something is happening to is dimmed, drained of colour, inert,
|
||||
and says which operation in a word** -- `BusyItem`, used by both the
|
||||
session list and the import list so the appearance is learned once. The
|
||||
word rather than a bare spinner because "deleting" and "importing" differ
|
||||
in kind, and the inertness is the overlay consuming pointer events rather
|
||||
than each caller remembering to disable its own click handler.
|
||||
- **The import screen selects in batches: hold to enter, tap to add.** The
|
||||
options that act on a selection appear along the bottom, and are Delete
|
||||
and Import only. Submitting clears the selection immediately and marks
|
||||
every chosen row -- the one in flight as "importing" or "deleting", the
|
||||
rest as "waiting" -- so the bar goes away and the affected set is what
|
||||
says the work is happening. Rows are taken out as each one lands rather
|
||||
than all at the end: a finished row still sitting there looks exactly
|
||||
like one that has not been imported, and tapping it starts a second CLI
|
||||
on the same transcript. What that costs is that the rows below slide up
|
||||
under the reader's finger, so a row that has just moved ignores taps for
|
||||
half a second (`SETTLE_MS`).
|
||||
- **Deleting a session offers to take the machine's own transcript with
|
||||
it.** `DELETE /sessions/{id}?deleteForeign=true`, behind a switch in the
|
||||
confirmation, and only where the driver keeps a record of its own
|
||||
(`keepsOwnTranscript`, which today means Claude Code). Off by default,
|
||||
because leaving that copy is what makes an ordinary delete recoverable --
|
||||
and the dialog's paragraph is rewritten when it is on rather than
|
||||
appended to, since the sentence promising the conversation "should still
|
||||
be there to import again" is exactly the one the switch makes false. The
|
||||
server deletes the machine's copy *first*, so a machine it cannot reach
|
||||
leaves the session where it was instead of half-deleted.
|
||||
- **Android Lint is not optional and is not run by a build.** It found a
|
||||
crash that had been shipping: `java.time` on a minSdk-24 app with
|
||||
desugaring off — and later a permission check that silently dropped every
|
||||
@@ -234,6 +261,17 @@ first if a remote spawn ever mangles an argument.
|
||||
conversation somebody may still be in. **A transcript never goes in this
|
||||
repository**: they hold whatever was said, read and written in that
|
||||
session, and `~/repos` is shared with the host besides.
|
||||
- **`app/ui-sandbox.sh` is the rig for anything that lists or deletes
|
||||
sessions.** It starts a second `ai-server` with its own `$HOME`, config
|
||||
and data directory, holding eight invented Claude Code transcripts and a
|
||||
`claude` that is two lines of shell. That isolation is the point: the
|
||||
import screen lists whatever is in `~/.claude/projects`, which in this VM
|
||||
is real agent transcripts, so exercising *delete* against the ordinary
|
||||
server deletes somebody's conversation and exercising *import* starts a
|
||||
real `--resume` on Bryan's account. Neither is a price worth paying to
|
||||
look at a list. It shares the real TLS certificates, because the
|
||||
installed APK pins that CA, so run it while the ordinary server is down.
|
||||
It passes `--delay` by default for the reason the next entry gives.
|
||||
- **`ai-server --delay MS` holds every response back.** Over the tunnel a
|
||||
phone's requests take tens to hundreds of milliseconds, and several
|
||||
faults live entirely in what the app does *while* one is outstanding. On
|
||||
|
||||
Reference in new issue
Block a user