- Sidebar: New chat, search, Scheduled, Files, the chats of both kinds by day (Today, Earlier),
Settings with the account at the foot; folds away (Ctrl+B), a drawer on a narrow window.
- A new chat is the chat page empty: a greeting, Agent or Chat, and the composer.
- The composer is a card: the text, then attach, the chips (folder and mode for an agent chat,
model with its picture, effort as the model offers it, the team's size), and a round Send that
Stop replaces while a reply is written. An open chat's chips change the chat.
- Messages: the person's in a bubble on the right with attached pictures as thumbnails, a reply
full width; thinking and tool calls as compact rows that unfold.
- Activity: a chip above the composer for every open chat, the panel on the right as before.
- The agent: a chip in the title bar opening its state and the one thing to do about it; "This
computer is not linked yet" with Link this computer right above the composer of an agent chat,
and "refused" only with the server's reason.
- Files: a page with the two trees as tabs. Settings: grouped, the groups listed beside them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The events stream is held while it opens, so a reconnect and the window
showing again cannot open two; while the window is hidden in the tray it is
not reopened (the server polls for each), and showing the window opens it
again. The Thinking switch says 'Think before answering' in the header too:
'Thinking' is the catalogues' word for a reply in progress. The chat's header
restacks by the chat column's own width (a container query at --bp-narrow),
so a chat beside the activity panel keeps its title.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every new sentence in the nine languages: 54 more, of which all but four come
from the server's own catalogues (its activity panel, team setting and
Thinking switch use the same words); the four about continuing in a terminal
are the app's own, in all eight.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The activity panel beside a chat, from /api/v2's activity routes: Context
(used share, tokens against the window, a segmented bar and a row per
category), Outputs (the files written, lines added and removed, each opening
in the viewer), Background tasks (a team's members as a tree, helpers and
commands: state, elapsed time counting on between reads, model, latest step,
what it is writing, its whole conversation read-only, Stop -- a member after
a confirmation, as it takes those under it), the team's room (who to whom,
reports marked, the words through the page's own markdown) and the plan.
The chat follows GET /chats/{chat}/activity/events while it is open: the strip
above the message box sums the agents up and opens the panel; a new version
reads the panel again while it is open, the costly context part on opening,
after a reply and at most every 15 s. The stream is reopened when the server
closes it, and more slowly while it fails. Beside the chat on a wide window
(the viewer then goes over the chat), over it below --bp-wide, a full-height
sheet at --bp-narrow. The header's Activity button, the palette and Escape
open and close it.
An agent chat with a device session (device_session_id) can be continued in a
terminal: the chat's menu and a header button show 'cd <folder> && lembas -s
<id>' to copy, with lembas the CLI as it starts here (on PATH, else the app's
own copy by its path). Shown rather than run: no terminal opens the same way
on every desktop.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/api/v2/models now says each model's levels, start level and control. A model
with one level shows no effort control; off and one effort is a Thinking
switch (a checkbox with the switch role); more keep the selector. In the
chat's header the switch and selector save at once; in the new-chat form they
start at the model's start level and redraw when the model changes.
Where a team is offered -- an open chat asks GET /chats/{chat}/team; a new
chat on the server needs a model that calls tools and serves two requests at
once -- the Agents fewest/most fields sit beside it. The header saves the pair
on change (the server refuses a pair outside its bounds and says them; the
fields go back); a new chat sends them only when set, else the person's
default stands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/api/v2/models names each model's picture (image, readable with the app's
token at /api/v2/models/images/<file>). A command reads it in Rust -- one
plain file name on the app's door, one of the four types the server accepts,
at most its 2 MB -- and hands the page a data: URL, which its policy already
allows. The avatar shows it once it arrives; the coloured initial stays for a
model without one and until then.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Attachments from the file dialog, a drop on the window (Rust holds the dropped paths; the page
never names one) or a paste (the bytes as the raw body of the call), sent at once to
/api/v2/attachments as multipart and shown above the composer.
- Edit message (rewind), Regenerate reply on the last reply, Copy on both.
- The chat's menu (header and a right click in the sidebar): rename, open in the web interface,
archive, delete.
- The chat's model and effort in its header; effort for a new chat. Model avatars coloured as
the server's stable_hue colours them (MD5 of the id, checked against Python), mixed into the
theme's surface so no colour is hard-coded.
- Ctrl+K palette over commands and every chat's title; Ctrl+N, Ctrl+,.
- The agent's new states in the page; 34 new sentences in all eight languages, the server's own
words where it has them; a Czech row that was Slovak; two untranslated strings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Desktop said "running" as soon as `lembas service run` was started, while the CLI was still
dialling, waiting for a terminal that holds the link, or refused by the server -- the reason went
only to agent.log. Now the supervisor reads what the CLI itself writes: `service.json` in its
state directory (connecting, linked, waiting + why, stopped + why) for the pid it started, the
line it printed before that, and its last line when it ends. A service the app did not start is
described the same way.
A run the CLI ends with 0 because trying again will not help (a refused token, no login) is no
longer restarted every second: it waits five minutes, or until linking again starts it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The editor's vendored modules come from server v2.0.0-beta.4 with the
process stub @lezer/lr needs, so languages load and code is highlighted
again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The app's device login asks for `app models` and, where discovery says
login.device.agent_scope, `agent_scope=models memory link` in the same
approval. The agent's token goes to the bundled CLI on stdin
(`lembas login --token-stdin --server <url> --json`) and is never kept
here; if the CLI does not take it, it is given up on the server. A
computer linked already keeps its link; a server without agent_scope
gets the old two steps.
- The server pane reads GET /api/v2/files and /files/content (mounts open
like folders; `withheld` shown in the server's words). The "not offered
yet" state is gone.
- A show card's file comes from GET /api/v2/chats/{chat}/show?node=&version=
or ?shown= as plain text (new `api_text` command, 1 MB cap); args.path is
read only for agent chats on this computer, locally.
- The gate is link protocol 3 plus app_api 2 (APP_API = 2), not the
server's version number, which says 1.7.2 on dev until its first beta.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plain HTML, CSS and ES modules in ui/, no build step. The sidebar opens on agent
chats (this computer first), with chats on the server as the second tab; the
transcript draws the /api/v2 steps, follows a reply as it is written, answers
cards, and starts agent chats in one of the agent's folders. Two explorers kept
apart (this computer's, the server's) and a viewer: Markdown drawn by a safe
renderer that never parses HTML, code in read-only CodeMirror with the server's
token colours, HTML in the sealed frame, show calls opened in it. Settings for
the sign-in, the agent and its folders, notifications and updates; no admin
pages. Layout on fixed and shared tracks; the sidebar is a drawer below 48rem,
the viewer goes over the chat below 64rem. All 124 sentences in the server's
nine languages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ui/tokens.css from the server's dev (tokens.lock.json; repin to the beta tag
at release). scripts/fetch-vendor.sh copies the server's vendored CodeMirror and
Lezer modules into ui/vendor/, each checked against the server's own pin first,
with the bare module names rewritten to sibling files (the page has no import
map); vendor.lock.json records both hashes, and the script with no argument
verifies the copy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scripts/gen-i18n.py writes ui/i18n.js from the server's catalogues where the
same sentence exists and from its own table otherwise; the pages pick the
language from the browser and fall back to English.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ui/tokens.css is no longer a hand copy that drifts: scripts/fetch-tokens.sh
takes the server's tokens.css at a git ref and tokens.lock.json pins it, as
fetch-cli.sh does for the CLI. build.rs reads the two themes' --bg and --border
out of it, so no colour is written in Rust. The content view reports the page's
theme by a navigation the app refuses (llembas-theme:<name>), and the window,
the title bar and the first-run page are painted in it and remember it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Settings… lists the folders the agent may work in, with the system's
folder dialog, remove, max mode and terminal, all through
'lembas remote … --json' (CLI 1.2.0). Turning the agent on with no
folder opens it; the title bar says 'agent: no folders' instead of green.
- The content webview's User-Agent carries LLeMbasDesktop/<v> (host=…),
so the server can show this computer's device as Local.
- The title bar menu pops up at the button (popup_menu_at): Wayland gave
the pointer-less popup the middle of the window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Linux: Tauri packs a window's webviews into one GTK box with equal
shares and ignores their bounds, so the title bar took half the window.
The title bar webview now has a fixed height and no share; the box's
border is the resize frame (none when maximized).
- tauri-plugin-updater: checks llembas.eu/desktop/latest.json at start
and every 6 h, an update button in the title bar and menu entries,
.deb via pkexec, AppImage in place, then restart. Packages signed with
the updater's minisign key; requireSignedVersion on.
scripts/publish-update.sh signs a GitHub release and writes the manifest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The window has no system decoration: a local title bar webview (agent
state, a native menu with the tray's items, window buttons) above the
content webview, which stays remote with no IPC. Laid out on resize,
with a frame to resize by unless maximized.
- Icons from the transparent pixel leaf, not the server's tiled icon.
- productName llembas-desktop: package, .desktop file and the window's
app id now match (KWin showed a generic icon); the visible name stays
LLeMbas through a desktop template. Replaces the 0.1.0 package l-le-mbas.
- The bundled CLI is a resource in the app's own directory, not
/usr/bin/lembas.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tauri 2, no Node. A first-run page chooses the server; then the window is
the server's web UI, whose pages get no IPC. The bundled LLeMbas CLI
(fetched and signature-checked by scripts/fetch-cli.sh) links the computer
with 'lembas login --json' and runs as 'lembas service' while the app runs.
A tray menu starts and stops it. Linux packages from GitHub Actions on a tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>