5b9941cfaa434a427c668ab03029e6b7404ae858
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ff39ef5cf9 |
Say it in icons, and put the whole backend behind four tabs
Six things Bryan asked for, which turned out to be one change: the app had no icon set, so every one of them was blocked on having somewhere for icons to come from. That somewhere is dev-updater's arrangement, ported: a Nerd Fonts subset committed as an asset, drawn as text. `Gear.kt`'s hand-drawn canvas gear argued against icon fonts because a system font may not have the glyph and whoever gets the empty box is never the person who wrote it. The objection is right about *relying* on a system font and the answer is to ship the glyph, so the file is gone and its reasoning is restated in `NerdIcons.kt` rather than deleted -- otherwise the next reader re-derives it. `md-cog` and `md-refresh` are dev-updater's own codepoints, because a cog means the same thing in both apps. The root screen's four words under the title are now four tabs, and the two that act on the whole screen -- settings and refresh -- moved up onto the title row as glyphs. That row's old comment recorded that a fifth word would have had nowhere to go; tabs also say something the words did not, which is that sessions, import, models and setups are four views of one backend rather than four errands. Refresh feeds whichever tab is showing. Import, models and setups lose their headings and their Back buttons, since the tab row is now both. Usage is a dialog. It is checked *against* what you were reading -- "can I start this" is asked with the transcript still on screen -- and it had no navigation of its own, so the only thing its Back could mean was "put this away". The button that opens it is a chart glyph coloured by the worst of the machine's windows, so the row says whether the limits are worth opening before anybody opens them. One `quotaColor` now colours every bar that measures a quota: blue, yellow at 75%, red at 95%. The session bar escalates where it used to sit blue at every level, and the dialog's thresholds moved out of it. A download keeps plain blue at every value -- it has no limit to approach, and colouring it like one would say the opposite of what is happening. States that are not measurements take the ordinary control colour, since blue is the low end of this scale and would read as "checked, and fine" about a machine nobody could reach. Send and stop are the filled paper plane and the filled square. Send keeps the word "Queue" while a turn is in flight, because that is what pressing it then does, and an icon that does two things while looking identical would promise something immediate and do something that waits. Looked at on the emulator: all six glyphs render, the tabs and the system back gesture between them, the dialog over a live session, and the bar bands at 82% and 97% forced through a scratch build, since this account is at 72/31/5 and would only ever have shown blue. |
||
|
|
2a1bc84c1e |
Expand a leading ~, and say what the failing command said
Three things, two of which are the same failure seen from opposite ends. **A working directory of `~/repos/ai-app` never worked.** Everything crossing to the remote side is single-quoted, which is right for paths, model names and prompts alike -- unquoted they would be shell syntax rather than data. It is wrong for exactly one character: `~` means "expand me", and quoting is what stops expansion. So the remote shell was handed the literal four-character directory `~` and correctly said it did not exist, which reads as the path being wrong rather than the quoting. Paths now go through `quote_path`, which emits `"$HOME"` for a leading `~/` and single-quotes the rest. The variable expands, the expansion is not re-split or globbed because it is double-quoted, and nothing after it gains a meaning -- there is a test that pushes a quote-and-semicolon injection through the tilde branch and gets back one absurd path rather than three commands. `$HOME` is set by every shell this can land in, so this does not depend on the remote side being POSIX; verified by running the generated script under both sh and fish, which is what the dev VM actually uses. **The phone could not have told you any of that.** The exit report kept the last line of stderr, and a shell's error message ends with a blank line -- so the last line was empty, the report was a bare exit status, and the seven lines of fish complaining sat in the server's log where nobody holding a phone is looking. It now keeps the last 50 lines in a ring and reports them with blank lines trimmed from both ends. The tests use the real fish `cd` failure as their fixture. **The status bar was unreadable.** `isAppearanceLightStatusBars` was hardcoded to `true` -- dark icons -- which was right against the default light surface and wrong the moment the app wore Mocha. It now asks the scheme's own background for its luminance, so changing the palette cannot reintroduce it. **And the address field takes `user@host:port`.** One field rather than two, because that is how an address is written everywhere else and a port that is nearly always 22 does not deserve its own box on a phone keyboard. Absent means absent rather than 22: the backend already decides that default, and writing it here would be a second answer in a second place. A colon only means "port" when it can -- brackets for IPv6 as ssh writes them, otherwise exactly one colon followed by digits. Looked at on the emulator: the status bar, and the form, whose label I then shortened because it wrapped onto a second line and made that field taller than the two beside it. |
||
|
|
3c144f8070 |
A screen for the machines, and failures a phone can act on
The other half of making setups editable: add, rename, rediscover and remove, with a Test that tries a machine before anything is saved. The screen cannot name a program, which is the point rather than an omission -- providers are what the server found when it asked, so this app has no way to introduce something to run. The dialog says so, because "what it can run is discovered, not typed" is the answer to the question a person will otherwise ask when they look for a command field. Two things running it changed. The card showed "this machine / this machine", because the seeded setup is *called* that and my fallback line for a local setup said the same -- the line now says something the name cannot also be. And the header row absorbed a fifth action without complaint, which is the earlier title-and-actions split paying off exactly as its comment predicted. **Host key verification is the failure that would have made this look broken.** Every machine fails it the first time, because its key is not in known_hosts yet, and ssh's own words -- "Host key verification failed." -- are written for somebody at a terminal on the backend, which is exactly who is not reading a phone. It now says what to do: ssh to it once from the backend and try again. Permission denied gets the same treatment. Deliberately *not* fixed by relaxing StrictHostKeyChecking. Accepting a new key is a decision somebody should make with the key in front of them, not something this app does quietly on their behalf while adding a machine. Verified on the emulator against a running server: the seeded setup renders with what was discovered on it, the add dialog explains itself, and Test against an untrusted machine produces the full explanation rather than ssh's four words. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xn8nHw1tw1R6PtiY1eEtw |