The app's own interface: agent chats first, two explorers, a viewer
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>
This commit is contained in:
20 files changed
+4275
-758
No files matched your search
+105
-61
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang="en" data-theme="moria" data-base="moria">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@@ -7,72 +7,116 @@
|
||||
<title>LLeMbas</title>
|
||||
<link rel="stylesheet" href="tokens.css">
|
||||
<link rel="stylesheet" href="app.css">
|
||||
<script src="theme.js"></script>
|
||||
<script src="i18n.js" defer></script>
|
||||
<script src="app.js" defer></script>
|
||||
<script src="i18n.js"></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<main class="card" aria-labelledby="title">
|
||||
<header class="brand">
|
||||
<img src="logo-mark.svg" alt="" width="40" height="40">
|
||||
<div>
|
||||
<h1 id="title"><b>LL</b>e<b>M</b>bas</h1>
|
||||
<p class="muted">Desktop <span id="version"></span></p>
|
||||
</div>
|
||||
<div class="app">
|
||||
<header class="bar" data-tauri-drag-region>
|
||||
<button class="bar__btn bar__side" id="side-toggle" type="button" aria-label="Chats" title="Chats" aria-expanded="false" aria-controls="side" data-i18n-aria-label data-i18n-title></button>
|
||||
<img class="bar__leaf" src="logo-mark.svg" alt="" width="18" height="18" data-tauri-drag-region>
|
||||
<span class="bar__name" data-tauri-drag-region><b>LL</b>e<b>M</b>bas</span>
|
||||
<span class="bar__host" id="host" data-tauri-drag-region></span>
|
||||
<button class="bar__update" id="update" type="button" hidden>update</button>
|
||||
<button class="bar__agent" id="agent" type="button" title="Agent">
|
||||
<span class="dot" aria-hidden="true"></span><span id="agent-text">agent off</span>
|
||||
</button>
|
||||
<button class="bar__btn" id="menu" type="button" aria-label="Menu" title="Menu" data-i18n-aria-label data-i18n-title></button>
|
||||
<span class="bar__sep" aria-hidden="true"></span>
|
||||
<button class="bar__btn" id="minimize" type="button" aria-label="Minimise" title="Minimise" data-i18n-aria-label data-i18n-title></button>
|
||||
<button class="bar__btn" id="maximize" type="button" aria-label="Maximise" title="Maximise" data-i18n-aria-label data-i18n-title></button>
|
||||
<button class="bar__btn bar__btn--close" id="close" type="button" aria-label="Close" title="Close (LLeMbas stays in the tray)" data-i18n-aria-label data-i18n-title></button>
|
||||
</header>
|
||||
|
||||
<section aria-labelledby="server-h">
|
||||
<h2 id="server-h" data-i18n>Server</h2>
|
||||
<form id="server-form" class="field" novalidate>
|
||||
<label for="address" data-i18n>Address of your LLeMbas server</label>
|
||||
<div class="row">
|
||||
<input id="address" name="address" type="text" inputmode="url" autocomplete="url"
|
||||
placeholder="https://ai.example" spellcheck="false" required>
|
||||
<button type="submit" class="btn btn--primary" data-i18n>Connect</button>
|
||||
</div>
|
||||
<p class="hint" id="server-hint" aria-live="polite" data-i18n>Sign in there as you would in a browser.</p>
|
||||
</form>
|
||||
</section>
|
||||
<div class="setup" id="setup" hidden>
|
||||
<main class="card" aria-labelledby="setup-title">
|
||||
<header class="brand">
|
||||
<img src="logo-mark.svg" alt="" width="40" height="40">
|
||||
<div>
|
||||
<h1 id="setup-title"><b>LL</b>e<b>M</b>bas</h1>
|
||||
<p class="muted">Desktop <span id="setup-version"></span></p>
|
||||
</div>
|
||||
</header>
|
||||
<div class="setup__body" id="setup-body"></div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<section aria-labelledby="agent-h" id="agent-section" hidden>
|
||||
<h2 id="agent-h" data-i18n>Agent</h2>
|
||||
<p class="muted" data-i18n>The agent lets agent chats on your server work in this computer's projects.
|
||||
It is the LLeMbas CLI, built in, running in the background while the app runs.</p>
|
||||
<p class="status" id="agent-status" aria-live="polite"></p>
|
||||
<div class="row row--buttons">
|
||||
<button type="button" class="btn" id="link" data-i18n>Link this computer</button>
|
||||
<button type="button" class="btn" id="toggle" data-i18n>Start the agent</button>
|
||||
<button type="button" class="btn btn--primary" id="open" data-i18n>Open the server</button>
|
||||
</div>
|
||||
</section>
|
||||
<div class="shell" id="shell" hidden data-side="false" data-viewer="false">
|
||||
<nav class="side" id="side" aria-label="Chats" data-i18n-aria-label data-local="true" data-server="false">
|
||||
<div class="switch" role="tablist">
|
||||
<button type="button" role="tab" data-kind="agent" aria-selected="true" data-i18n>Agent</button>
|
||||
<button type="button" role="tab" data-kind="chat" aria-selected="false" data-i18n>Chats</button>
|
||||
</div>
|
||||
<button type="button" class="btn btn--primary side__new" id="new-chat-btn"><span data-i18n>New agent chat</span></button>
|
||||
<ul class="list" id="chat-list"></ul>
|
||||
|
||||
<section aria-labelledby="folders-h" id="folders-section" hidden>
|
||||
<h2 id="folders-h" data-i18n>Project folders</h2>
|
||||
<p class="muted" data-i18n>Agent chats from your server can work in these folders and anything inside
|
||||
them — nowhere else on this computer. Start one in the server's Agents tab, on “Local”.</p>
|
||||
<ul class="folders" id="folders"></ul>
|
||||
<p class="status" id="folders-status" aria-live="polite"></p>
|
||||
<div class="row row--buttons">
|
||||
<button type="button" class="btn btn--primary" id="add-folder" data-i18n>Add folder…</button>
|
||||
</div>
|
||||
<div class="settings-grid">
|
||||
<div class="field">
|
||||
<label for="max-mode" data-i18n>The most an agent chat may do here</label>
|
||||
<select id="max-mode">
|
||||
<option value="manual" data-i18n>Manual — asks first</option>
|
||||
<option value="edit" data-i18n>Edit — asks before commands</option>
|
||||
<option value="auto" data-i18n>Auto — asks nothing</option>
|
||||
<option value="plan" data-i18n>Plan — changes nothing</option>
|
||||
</select>
|
||||
<p class="hint" data-i18n>A chat asking for more is lowered to this.</p>
|
||||
<section class="pane" id="pane-local" data-open="true" aria-labelledby="pane-local-h">
|
||||
<div class="pane__head">
|
||||
<button type="button" class="pane__toggle" aria-expanded="true" id="pane-local-h"><span data-i18n>This computer</span></button>
|
||||
<button type="button" class="pane__btn" id="local-refresh" aria-label="Read again" title="Read again" data-i18n-aria-label data-i18n-title></button>
|
||||
</div>
|
||||
<div class="pane__body">
|
||||
<div class="pane__where" id="local-where"></div>
|
||||
<div class="pane__tree" id="local-tree"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="pane" id="pane-server" data-open="false" aria-labelledby="pane-server-h">
|
||||
<div class="pane__head">
|
||||
<button type="button" class="pane__toggle" aria-expanded="false" id="pane-server-h"><span data-i18n>Server files</span></button>
|
||||
<button type="button" class="pane__btn" id="server-refresh" aria-label="Read again" title="Read again" data-i18n-aria-label data-i18n-title></button>
|
||||
</div>
|
||||
<div class="pane__body">
|
||||
<div class="pane__tree" id="server-tree"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<button type="button" class="side__settings" id="settings-btn"></button>
|
||||
</nav>
|
||||
<div class="scrim" id="scrim" aria-hidden="true"></div>
|
||||
|
||||
<main class="main" id="main" aria-labelledby="chat-title">
|
||||
<header class="head">
|
||||
<h1 class="head__title" id="chat-title"></h1>
|
||||
<div class="head__place" id="chat-place"></div>
|
||||
<div class="head__tools" id="chat-tools"></div>
|
||||
</header>
|
||||
<div class="thread" id="thread">
|
||||
<p class="thread__note is-error" id="thread-note" hidden></p>
|
||||
<div class="new" id="new-chat" hidden></div>
|
||||
<div class="messages" id="messages"></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<span class="label" data-i18n>Terminal</span>
|
||||
<label class="check"><input type="checkbox" id="terminal"> <span data-i18n>Let the server open a terminal here</span></label>
|
||||
<p class="hint" data-i18n>A shell as you, in one of these folders.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<div class="cards" id="cards" hidden></div>
|
||||
<form class="composer" id="composer" hidden data-running="false">
|
||||
<textarea id="composer-text" rows="1" placeholder="Message" aria-label="Message" data-i18n-placeholder data-i18n-aria-label></textarea>
|
||||
<div class="composer__actions">
|
||||
<button type="button" class="btn" id="stop" hidden data-i18n>Stop</button>
|
||||
<button type="submit" class="btn btn--primary" id="send" data-i18n>Send</button>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<section class="settings" id="settings" hidden aria-labelledby="settings-title">
|
||||
<header class="head">
|
||||
<h1 class="head__title" id="settings-title" data-i18n>Settings</h1>
|
||||
<div class="head__place"></div>
|
||||
<div class="head__tools"><button type="button" class="pane__btn" id="settings-close" aria-label="Close" title="Close" data-i18n-aria-label data-i18n-title></button></div>
|
||||
</header>
|
||||
<div class="settings__body" id="settings-body"></div>
|
||||
</section>
|
||||
|
||||
<aside class="viewer" id="viewer" hidden aria-labelledby="viewer-name">
|
||||
<header class="viewer__head">
|
||||
<div class="viewer__id">
|
||||
<h2 class="viewer__name" id="viewer-name"></h2>
|
||||
<p class="viewer__where" id="viewer-where"></p>
|
||||
</div>
|
||||
<div class="viewer__modes" id="viewer-modes"></div>
|
||||
<button type="button" class="pane__btn" id="viewer-close" aria-label="Close" title="Close" data-i18n-aria-label data-i18n-title></button>
|
||||
</header>
|
||||
<div class="viewer__body" id="viewer-body"></div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user