The composer decides what a chat is, and the topbar stops trying

The mode select in the topbar posted with hx-post against a route that only
answers PATCH, so every change returned 405 and the mode never moved. htmx
shows nothing when a request fails, so the control looked like it worked: the
select stayed where you put it and the server ignored you. It has never worked.

Two more of the same kind. A mode could not be chosen at all until the chat
existed, so reaching Plan meant sending something in Manual first and letting
the model answer under the wrong rules. And the project directory box was real
and submitted, but unlabelled and squeezed to a few characters by the select
beside it, so it read as broken -- which is how it was reported.

So the kind, the connection, the directory and the mode move out of the strip
above the text and into one toolbar row beneath it, where attach and send
already are. The directory becomes a button that opens a browser over SFTP,
because a path is something you would rather find than spell. `scan_dir` is new
beside `list_dir`: a picker has to tell a directory from a file before it can
draw the row, and `list_dir` backs a tool whose contract is a list of names and
must not change under a model mid-conversation.

Browsing is a person clicking, not a model calling, so it does not pass through
policy.py -- the same argument the terminal panel rests on. It does mean Manual
mode has a second exception now.

Also: .chip was two components with one name, and the attachment card won, so
the Chat/Agent pills silently wore its padding. --radius-md was used twice and
declared nowhere, so both fell back to 0. .btn.is-active has been set by
syncToggles since the terminal landed and styled by nothing. Enter-to-send
ignored isComposing, so committing an IME candidate sent the message. The
terminal had five colours of a sixteen-colour palette, with fallbacks from a
palette that no longer exists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaroslav Beneš
2026-08-02 16:44:57 +02:00
parent cab8025346
commit a7e59a00f8
22 changed files with 1449 additions and 276 deletions
@@ -165,6 +165,48 @@
<path d="M13.5 10.5a3.5 3.5 0 0 0-5 0l-3 3a3.5 3.5 0 0 0 5 5L12 17"/>
</symbol>
<symbol id="i-chevron-left" viewBox="0 0 24 24">
<path d="M14.5 6 8.5 12l6 6"/>
</symbol>
<symbol id="i-chevron-up" viewBox="0 0 24 24">
<path d="M6 14.5 12 8.5l6 6"/>
</symbol>
<!-- @, for a mention. The tail stops short of closing so the ring reads as a
ring at 16px rather than as a filled blob. -->
<symbol id="i-at" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="3.6"/>
<path d="M15.6 8.4v4.9a2.6 2.6 0 0 0 5.2 0V12a8.8 8.8 0 1 0-3.5 7"/>
</symbol>
<!-- The command key, which is what a command menu is. -->
<symbol id="i-command" viewBox="0 0 24 24">
<path d="M9 9h6v6H9z"/>
<path d="M9 9V7.5a2.5 2.5 0 1 0-2.5 2.5H9Zm6 0V7.5a2.5 2.5 0 1 1 2.5 2.5H15ZM9 15v1.5A2.5 2.5 0 1 1 6.5 14H9Zm6 0v1.5a2.5 2.5 0 1 0 2.5-2.5H15Z"/>
</symbol>
<symbol id="i-keyboard" viewBox="0 0 24 24">
<rect x="2.5" y="6" width="19" height="12" rx="2"/>
<path d="M6 9.5h.01M9 9.5h.01M12 9.5h.01M15 9.5h.01M18 9.5h.01M6 12.5h.01M9 12.5h.01M12 12.5h.01M15 12.5h.01M18 12.5h.01M8.5 15.5h7"/>
</symbol>
<symbol id="i-file-text" viewBox="0 0 24 24">
<path d="M13.5 3.5H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V9l-5.5-5.5Z"/>
<path d="M13.5 3.5V9H19M8.5 13h7M8.5 16.5h7"/>
</symbol>
<!-- A drag handle. Dots rather than lines: lines at this size read as a
hamburger, which means something else entirely. -->
<symbol id="i-grip" viewBox="0 0 24 24">
<path d="M10 6h.01M10 12h.01M10 18h.01M14 6h.01M14 12h.01M14 18h.01"/>
</symbol>
<!-- Agent chats. They borrowed `server`, which is the machine rather than
the act of working on one. -->
<symbol id="i-bolt" viewBox="0 0 24 24">
<path d="M13 2.5 4.5 13.5H11l-1 8 8.5-11H12l1-8Z"/>
</symbol>
<symbol id="i-leaf" viewBox="0 0 64 64">
<path d="M20.5 45.5C13.8 31.7 23.8 20.9 45.5 18.5 49.8 35 39.8 45.8 20.5 45.5Z"/>
<path d="M20.5 45.5C28 38 36 29 45.5 18.5"/>