Commit Graph
16 Commits
Author SHA1 Message Date
iris 7d9df5d572 Rename setups and add provider reauthentication 2026-09-12 22:56:43 -04:00
iris 62cb6c91d5 Navigate explorer back toward project 2026-09-12 19:38:18 -04:00
iris 2ff0b13950 Return from files to explorer 2026-09-11 12:40:27 -04:00
iris 22f263ccce Restore directory navigation on Android back 2026-09-11 00:28:55 -04:00
iris e3cca97cdd Open transcript file links in explorer 2026-09-10 18:08:05 -04:00
iris 4c15150338 Return from files to explorer 2026-09-09 22:48:52 -04:00
iris 14dd520719 Fix explorer back and session usage selection 2026-09-09 13:01:27 -04:00
irisandClaude Opus 5 79682f03a7 Condense the documentation and thin the server's comments
The markdown had accumulated a lot that was stale rather than wrong.
PLAN.md still described pi as the llama.cpp harness, a refcounted
LlamaServerManager, and a providers-by-hosts cross-product, all of which
were superseded or never built; it also carried a second copy of the HTTP
table that routes.rs owns. EXPLORER.md and TRANSCRIPT_CACHE.md held
implementation checklists for work that has since landed. AGENTS.md
restated most of PLAN.md's design instead of being the working-notes
layer it says it is. 3225 lines of markdown to 2180, with the stale
sections gone rather than reworded.

On the server, comments explaining what the code already says are out and
the ones recording a constraint, a measurement or an incident are kept but
cut to a few lines each: 5504 comment lines to 4586.

Four doc comments in session/mod.rs, and one each in process.rs and
usage.rs, had drifted onto the item above the one they describe --
functions were reordered without them, so `stop_session`'s doc sat on
`set_session_cwd`, `stat_of`'s on `struct Stat`, and `UsageMonitor`'s on
`type Cached`. Each is back on its own item.

routes.rs's module table also claimed later phases would add `/hosts`,
which setups replaced.

cargo test (127 passed), clippy --all-targets and fmt are clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 15:45:43 -04:00
irisandClaude Opus 5 a401e6a7e3 Draw the line numbers beside the file, not inside it
The stretch is rendered on the box around the list, so everything in that
box bent with it -- the numbers included. `Modifier.overscroll` wraps the
effect's single node, so one effect cannot be rendered in two places and
the numbers cannot be excluded while they live in the rows. They had to
leave.

They now sit beside the scrolling box: the rows leave a spacer where the
numbers go and a `SubcomposeLayout` draws them there. That is the one
arrangement that keeps them level with their lines, which is the thing a
numbered listing may never get wrong. Which numbers exist *and* where each
one goes both come from the list's own `layoutInfo`, read in the measure
block -- and subcomposition happens during measurement, so it composes from
the answer the list has just produced rather than from one it read a frame
ago. A column translated by the scroll position could not do that: the
translation would be a layout read and current while the set of numbers was
a composition behind it, and during a fling the numbers would slide against
their lines.

Checked by sampling the screen at about 1kHz through a fling: 23,520 row
observations over 552 frames, every one with its number at exactly its own
top, no drift at any point. Also that the gutter holds its x while the text
scrolls sideways, and that a short file and an empty one still draw.

A consequence worth having: the numbers are no longer inside the
`SelectionContainer`, so selecting part of a file and copying gives the code
rather than the code with a number in front of every line. That follows from
where they are now rather than from anything asked for, and a copy was not
exercised.

The stretch itself still cannot be seen from this VM, so whether the numbers
now stay flat while the text bends is the thing to look at on the phone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 01:51:47 -04:00
irisandClaude Opus 5 7b08a71e64 Stretch the whole file at the ends, not one line
`Modifier.horizontalScroll` builds its own overscroll effect per node, so
with a node per row only the line under the finger bent when the file was
dragged past either end and the rest sat still beside it -- the same
complaint as the offsets, one layer out.

There is an overload that takes the effect instead of making one, and it
leaves the rendering to the caller. So the viewer makes one effect, hands
it to every row, and renders it once on a box around the list: the file
bends as the block it scrolls as. This only works now that every row is
the same width -- rows that disagreed about where the end was would
disagree about when to stretch.

**Not seen working.** Measured on the emulator here: over-dragging well
past the end and capturing mid-gesture produces a frame with no stretch in
it at all, and the list's own vertical overscroll does not appear either,
so this VM cannot show the effect for any scrollable. Noted in
~/.claude/MACHINE.md so the next session does not spend the same half hour
on it. What was checked here is everything either side: the scroll still
reaches both ends, the position survives scrolling vertically, and nothing
else moved. The stretch itself wants a look on the phone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 01:38:21 -04:00
irisandClaude Opus 5 457907087c Record why the viewer's rows all share one width
EXPLORER.md's decision 8 said "one shared horizontalScroll state", which is
what was built and is not sufficient on its own -- the reason is worth
having beside the decision rather than only in the code that now works.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 00:40:02 -04:00
irisandClaude Opus 5 2c12274285 Measure the explorer, and cap edit mode at what it can carry
Three numbers, taken on the emulator through the app's own render report
and written into EXPLORER.md; the fixture tree the sandbox now builds is
what they were taken against.

The viewer's scan was on the main thread. Decision 8 said off it, and the
first version did it in a `remember` inside the composition, which is not
that -- 460ms of frozen screen on a 1 MiB file, long enough that the
accessibility tree cannot be read, which is exactly what "the app has
stopped" looks like from outside. It runs on Dispatchers.Default now, with
a spinner where the file will be. Reading a megabyte is otherwise fine:
the viewer is a row per line, and it opens and scrolls 28,660 of them.

Edit mode needed a cap, and not the one the plan expected. The cost that
matters is not the highlighting -- 40ms a keystroke at 128 kB, which is
survivable -- it is Compose laying out one enormous text in the field:
2,027ms per frame at 128 kB, with typed characters dropped, and no
response at all at 1 MiB. Switching highlighting off would have saved
nothing, since every arrangement of a single text field pays it. So
EDIT_LIMIT is 32 kB, the largest size actually measured as usable, and
above it the pencil is disabled with the reason in words beside it: a
disabled control teaches what the thing can do but cannot say why it is
off, and a reader who cannot edit a file they can plainly read would
otherwise conclude the app is broken.

`FileLines.of` is timed like everything else here, so the figure lands in
the render report rather than needing a harness to ask for it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 00:16:57 -04:00
irisandClaude Opus 5 9c4d33273b Merge branch 'main' of git.arirex.me:iris/ai-app
The drag-right-to-go-back gesture was removed on the other side while the
file explorer was being built on this one, so the explorer's own use of it
goes with it: back inside the explorer is the arrow and the platform's own
gesture, which is what the rest of the app now has too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 00:00:48 -04:00
irisandClaude Opus 5 db55ed4a8f The file explorer on the phone
The other half of EXPLORER.md: a folder button on the session header opens
the machine's filesystem, starting where the session works.

It draws **over** the session in the same `Box`, so the session under it
stays composed -- its event stream keeps flowing, its draft and scroll
position stay where they were, and coming back from a file costs nothing.
Back steps one level inside it (editor, viewer, directory, parent) and only
closes from where it opened; the platform gesture, the button and the swipe
all go through the one function, so they cannot mean different things.

The viewer is a `LazyColumn` of lines rather than one `Text`, because text
layout is linear in the text and a twenty-thousand-line file in a single
`Text` measures all of it to draw a screenful. Lines do not wrap and share
one horizontal scroll, so a logical line is a visual line and the gutter
cannot come to number the wrong text; the gutter's width is measured from
the digit count of the line count in the style it is drawn in. The editor
is a `BasicTextField` with a `VisualTransformation` carrying the scanner's
spans, which is the one Compose API that colours a field's own text rather
than replacing the field.

`fileLanguage` reads the same table `fenceLanguage` does, so a language
added for fences is a language added for files.

A file that changed on the machine while it was open here refuses to be
overwritten and asks, with what each of the three answers costs. That is
the ordinary case, not the exotic one: an agent editing the file somebody
is reading is what this whole feature is for.

The speedometer moves off the header into the session settings dialog,
where the session's other about-the-session controls are, and the folder
takes a place between the usage chart and the cog -- widest scope to
narrowest, cog at the end, as Iris asked. Both benchmark scripts move onto
`ui-trace`'s new tap-by-label action in the same change, so the render
report is never unavailable and never pressed at a coordinate that has
stopped meaning anything; `app/bench-lib.sh` is what they share, and
`grep -n "tap [0-9]" app/*.sh` is the check.

Exercised on the emulator against the sandbox's new fixture tree, with a
screenshot or a ui-trace for each: the listing (dotfiles, directories
first, a symlink to a directory sorted with them, a name with a tab in it),
a highlighted file, binary, too big, a permission error, editing and
saving, the 409 and its Overwrite, back with unsaved edits, creating a name
that exists, creating one that does not and landing in the editor, an empty
directory, and `..` above the directory the session opened in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 23:58:59 -04:00
irisandClaude Opus 5 8881a40919 Remove the drag-right-to-go-back gesture
The screen no longer follows a horizontal drag. Back is the arrow at the
top left and the platform's own edge gesture, both unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 23:41:58 -04:00
irisandClaude Fable 5.1 32c57a47a5 Plan the file explorer
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 21:07:07 -04:00