omnyshell_web 1.18.0
omnyshell_web: ^1.18.0 copied to clipboard
A browser client for OmnyShell — connect to a Hub, discover nodes, run interactive sessions — and the reusable library behind it: embed a real remote shell terminal, or its UI kit, in any Dart web app.
1.18.0 #
Moves to OmnyShell 1.63.3 (from 1.61.1). Browser sessions pick up the shared
:tunnel and :ide changes from those releases.
Added #
- HTTP tunnels from
:tunnel(OmnyShell 1.62.0).:tunnel <port> --protocol httpopens a tunnel whose Hub adds forwarding headers (X-Forwarded-For,Forwarded,X-Request-Id, …) to every request it relays.:tunnel lsshows such tunnels ashttp://. - Response caching for HTTP tunnels (OmnyShell 1.63.0).
:tunnel … --cachekeeps aCache-Control-aware response cache on the Hub, with--cache-size,--cache-max-entry,--cache-privateand--cache-default-ttl.:tunnel lsshows cache usage and hit counts. - HTTP timeouts for HTTP tunnels (OmnyShell 1.63.0):
--http-response-header-timeout,--http-idle-timeout,--http-client-timeoutand--http-max-duration. - Deep git scan in the
:idefile tree (OmnyShell 1.61.2). Pressinggmarks every folder above a change with its git status.
Changed #
- The
:idefile tree shows dot-files by default (OmnyShell 1.61.2);.hides them. - HTTP tunnels apply default timeouts (OmnyShell 1.63.0). A silent target
now gets the consumer a
504after 60s, and a target the node can't reach a502. - Requires
omnyshell^1.63.3. The lockedomnyhubmoves to 1.9.2 with it, andbuild_web_compilersis refreshed within its constraint.
Fixed #
- Answering
qat the:ideagent's "Abort the AI agent?" prompt now aborts (OmnyShell 1.61.2). - The
:ideterminal no longer garbles non-ASCII output split across chunks (OmnyShell 1.61.2).
1.17.0 #
Moves to OmnyShell 1.61.1 (from 1.56.1). Browser sessions pick up the shared client changes from those releases.
Added #
- The
lshortcut (OmnyShell 1.60.0). Typinglin a session lists the directory with hidden entries and human-readable sizes, translated for the session's shell:ls -alhon POSIX shells,Get-ChildItem -Forceon PowerShell, anddir /aoncmd.exe. Anything typed afterlis passed through.
Fixed #
- Windows sessions no longer show
\ras the prompt's directory (OmnyShell 1.61.0). winpty sometimes ends the marker a node sends after each command with an extra carriage return, and the client took that as the working directory. The prompt was corrupted and TAB completion failed. Carriage returns are now stripped from every marker field.
Changed #
- Requires
omnyshell^1.61.1. The lockedomnyhubmoves to 1.7.0 with it, and the dev tooling (build_runner,build_web_compilers,test) is refreshed within its constraints.
1.16.0 #
The :ai and :ide shell commands, and the AI settings that back them, are now
public API — a sibling dashboard can offer the same terminal commands without
copying code.
Additive and backward-compatible.
Added #
-
Barrel exports for the browser shell commands.
terminal.dartnow exportsregisterAiCommand/resolveAiWiring(:ai) andregisterIdeCommand(:ide);client.dartexportsAiSettingsController. These already shipped in the package — they just were not reachable without importing an internal path. -
aiSettingsSection(AiSettingsController)(exported fromui_kit.dart) — the portable half of the settings dialog: the AI provider/model/key, Hub-default toggle, agent mode and reply-language controls, bound only to a controller and free of anyAppContext. Drop it into any settings modal.
Changed #
- The built-in settings panel now composes
aiSettingsSectionfor its AI block rather than building those controls inline, so the shell app and an embedding app render the same UI from one source.
1.15.0 #
OmnyShell Web is now a package, not only an app. Any Dart web app can embed a real remote shell — PTY sizing, soft-keyboard insets, line editing, history and flow control already solved — instead of rebuilding the hard parts. The first consumer is the OmnyServer fleet dashboard, whose Hub can host an OmnyShell broker on the same port, so a node's shell is one button away.
dependencies:
omnyshell_web: ^1.15.0
dart run omnyshell_web:copy_assets # xterm bundle + stylesheets → your web/
import 'package:omnyshell_web/terminal.dart';
final term = XtermTerminalView(host);
final session = await service.openShell(nodeId: id, cols: 80, rows: 24);
final shell = WebShellHost(
term: term, session: session, principal: 'alice', nodeId: id,
commands: null, // a plain shell: no :ai, no :ide
);
TerminalFitter(term: term, host: host, accessory: bar, scaleTarget: root).attach();
The app itself is unchanged — same screens, same behaviour, same tests, all passing unmodified. What follows is what had to move to make the terminal embeddable.
Added #
- Three public barrels.
terminal.dart(the terminal stack),ui_kit.dart(dom, widgets, toasts, modal) andclient.dart(OmnyShellService,Observable,AsyncState, controllers, storage, router, theme).app/,ui/screens/andui/settings_panel.dartstay app-private — exporting them is exactly what would let the shared tier re-acquireAppContextcoupling. See ARCHITECTURE.md → Public surface. TerminalFitter— the terminal's sizing engine, lifted out ofSessionViewScreen, where it was ~140 private lines. It is the hardest code in the repo (a terminal that grows but never shrinks, renders 0×0, or hides its last line behind a soft keyboard is what you get when a piece of it is wrong), and no consumer should have to copy it. Both modes are preserved: a fixed grid whose font rescales (the backend PTY cannot be resized) and auto-fit, where xterm re-derives cols/rows.bin/copy_assets.dart(dart run omnyshell_web:copy_assets) — installs the xterm bundle,kit.css,terminal.cssandboot.jsinto a consuming app'sweb/. A package ships itsweb/inside the pub archive, but pub never serves it to a consumer, so without this the terminal loads to a blank box and the widgets render unstyled.XtermTheme— the xterm palette, font size and family are now injectable (XtermTerminalView(host, theme: …)), defaulting to OmnyShell's. xterm paints to a canvas and so cannot inherit CSS custom properties; an embedding app has to be able to say what its colours are.example/— a whole terminal app in one file, using only the barrels. It doubles as a check that the public surface is sufficient without deep imports.- LICENSE (Apache-2.0, matching the rest of OmnyGrid) and a
repository:link, both required to publish.
Changed #
- Storage prefixes are parameterized, defaulting to
omnyshell.so nothing changes for this app:SettingsStore(kv, prefix: …),NodeCache(kv, prefix: …),CommandHistory.load(prefix: …).localStorageis per-origin and one Hub can serve two apps, which would otherwise share — and clobber — each other's theme, Hub, token and terminal preferences. styles.cssis split intokit.css(tokens, base, layout, widgets, modal, toasts) andterminal.css(terminal chrome, key bar, fullscreen, keyboard insets), so an app can take the terminal without the whole look, or vice versa. Every selector is preserved; the app links both. The service-worker cache version is bumped accordingly.deviceMetrics()moved fromui/settings_panel.darttoterminal/device_metrics.dart. It is ten lines of purescreenreading, and importing the terminal stack should not drag anAppContext-coupled settings panel along with it. Still re-exported from its old home, so nothing breaks.
1.14.12 #
Changed #
- Bumped the
omnyshelldependency to ^1.56.1. 1.56.0 lets the Hub broker be hosted on a listener OmnyShell does not own (OmnyShellHubService, an omnyhubService), rebuildsOmnyShellHubon omnyhub'sOmnyHub— TLS viaStaticTls/ReloadableFileTls,shelfdropped — and addsNodeConfig.home; 1.56.1 is a dependency-constraint refresh (omnyhub ^1.5.1, omnydrive ^1.12.3). All of it is node/hub-side; the browser barrel is unchanged, so the PWA is unaffected. Also bumpedbuild_runnerto ^2.15.1. Verified: the dart2js release bundle builds and the VM + Chrome test suites pass against 1.56.1.
1.14.11 #
Changed #
- Bumped the
omnyshelldependency to ^1.55.0. In that release OmnyShell's transport moves onto the shared omnyhub stack (FrameConnectionover an omnyhubTypedConnection<OmnyShellFrame>). The change is native/dart:io-side; the browser barrel (WsChannelConnection, the web transport factory) is unchanged, so the PWA is unaffected. Verified: the dart2js release bundle builds and the VM + Chrome test suites pass against 1.55.0.
1.14.6 #
Changed #
- Bumped the
omnyshelldependency to ^1.49.0. That release expands theomnyshell dashboardfull-screen CLI TUI into a four-tab operator console (Nodes, Tunnels, Drive, AI), gives it a blue-free monochrome dark theme, and fixes a stale-sessions flash when opening a node. The changes are node/CLI-side; the browser barrel is unchanged, so this is a routine dependency refresh.
1.14.5 #
Changed #
- Bumped the
omnyshelldependency to ^1.48.0 and adopted its width-fitting shell prompt: the browser prompt now passes the terminal width toformatShellPrompt, so on narrow (phone) terminals it progressively drops the least-important pieces (git status counts →@node→cwdshortened to…/basename→ the whole git segment) to leave room to type, keeping the(⚠ privilege)warning. It re-evaluates on terminal resize/rotation.
1.14.4 #
Changed #
- In the light theme the terminal is inverted (
filter: invert(1) hue-rotate(180deg)) so it reads as a light terminal instead of a dark box on a light page; the card frame is lightened to match so no dark border rings it. The dark theme is unchanged.
1.14.3 #
Changed #
- Bumped the
omnyshelldependency to ^1.47.0. That release adds theomnyshell dashboardfull-screen CLI TUI (which itself ports UX from this web client — session sorting/highlight, soft refresh failures, friendly login errors). The changes are node/CLI-side; the browser barrel is unchanged, so this is a routine dependency refresh.
1.14.2 #
Added #
- Ctrl combinations popup on the terminal key bar. The
Ctrlbutton now opens a menu of common combos (^A ^B ^C ^D ^F ^L ^Q ^S ^N ^P ^W ^Z), a custom single-character entry, and a sticky "Ctrl + next key" modifier. A one-tap quick key repeats the last-used combo (defaults to Ctrl-C); the two read as one segmented control. - Sessions preview on the node info screen. Opening a node shows a card summarizing its
current sessions (count + a compact list) with a
View allbutton, before visiting the list.
Changed #
- Sessions list ordering and highlight. The last-interacted session (clicked from a node's preview, resumed, or freshly created/opened) is highlighted with an accent ring and sorted to the top, followed by sessions running a program, then detached before attached, then newer first. A running program is shown as a green badge beside the attached/detached badge.
- Sessions list layout. The node id is shown big and white (like the node-info title); the
Sessionsheading is slightly smaller; theNewandRefreshbuttons are compact; and the per-session action buttons are smaller and fit on a single line on phones. - Top menu polish. The theme (
System/Light/Dark) andSign outbuttons use smaller text; the settings gear is slightly larger. On the node screen theSessionsbutton was removed andNew shellmoved to the top-right.
1.14.1 #
Fixed #
- Typing after TAB/Arrow-Up no longer staircases a new prompt line per keystroke on a narrow
terminal (iOS Safari). The shared
LineEditorrepainted the input line assuming it fits one row, so once a completed path or recalled command wrapped, every keystroke redrew a fresh prompt.WebShellHostnow feeds the xterm terminal width to the editor (and updates it on resize), and theomnyshelldependency is bumped to ^1.46.0, which repaints across wrapped rows. Reproduced on iOS Safari (narrow terminal); desktop Chrome was wide enough to avoid the wrap.
1.14.0 #
Changed #
- Bumped the
omnyshelldependency to ^1.45.0. That release adds live PTY resize to the node's defaultscriptbackend (no FFI) and makes a resume apply the resuming device's geometry — so, together with the 1.13.2 measure-before-open fix, resuming on a differently-sized device now resizes the shell and reflows a full-screen program. The upstream changes are node/CLI-side; the browser barrel is unchanged, so this is a routine dependency refresh.
1.13.2 #
Fixed #
- Resuming a session now opens at the current device's terminal size instead of briefly at
xterm's 80×24 default. The resume path read the terminal size synchronously, before the xterm
view's deferred fit had run; it now fits to the container first, so the size sent to the node
is correct on the first try (no reflow flash). When the node runs omnyshell 1.45.0+ (which
resizes the resumed PTY to the size the client opens with), resuming on a differently-sized
device reflows the shell / a full-screen program to this device. (No dependency bump — the
client's
omnyshellpackage is unchanged.)
Fixed #
- Resuming a session whose program is in the alternate screen (nano, vim,
claude, …) no longer corrupts it. The web client was always priming the shell on connect — running the init line and a cwd/marker command to draw the prompt — even when resuming into a full-screen program, so those commands were injected into the program. The host now honors the session'sresumedInAltScreenflag (already reported by the node on resume): it starts in passthrough and skips priming, letting the replayed output repaint the program and its queued marker restore the prompt when it exits — matching the CLI'sconnectloop.
1.13.0 #
Changed #
- The terminal now uses omnyshell's shared
LineEditorinstead of a hand-rolled, append-only editor, so the browser behaves identically to the CLI. The visible gain is full mid-line editing: Left/Right, Home/End (and Ctrl-A/Ctrl-E), and Delete now move and edit within the line rather than only appending at the end. History navigation, TAB completion, the:aiconfirmation prompts and the:idefull-screen takeover are all driven through the same editor. - Ctrl-C semantics now match the CLI: at idle it clears the line and interrupts
the remote shell; while the
:aiagent owns the screen it fires the agent's abort and unblocks any pending confirmation; during a:idesession or while a remote program owns the screen it is delivered to that program.
Changed #
- Bumped the
omnyshelldependency to ^1.44.0 and adopted its new shared, browser-safe building blocks, replacing the web client's duplicated copies so the two clients can't drift apart:- the AI default-model map →
defaultModelFor(drops the local_defaultModel); - the
:ideremote-root resolution and shell-family → command syntax →resolveRemoteIdeRoot/ideCommandSyntaxFor(drops the local copies and the directpackage:pathdependency); - the IDE terminal driver's ANSI emission →
XtermTerminalDrivernow extends the sharedAnsiTerminalDriverand only supplies the xterm.js byte sink, size, and input/resize streams; - command history now implements the shared
CommandHistoryStoreinterface.
- the AI default-model map →
- The shell prompt is now formatted by the shared
formatShellPrompt, so it matches the CLI: the working directory is cyan (was blue), the git segment is blue with a red branch and green status counts (was yellow), and the superuser is shown with a bold-red(⚠ root)warning (was a#symbol).
Added #
:ide(alias:edit) — the full-screen terminal IDE in the browser. Typing:ide [path]in a session opens omnyshell's TUI IDE on the connected node, rendered right inside the xterm.js terminal: a file-tree sidebar with git status, tabbed editing with syntax highlighting and a git-change gutter, an integrated terminal, and an AI agent panel.Ctrl-Qreturns to the shell.- The IDE engine (
IdeApp/ScreenBuffer/RemoteWorkspace, exported by omnyshell ^1.43.1) isdart:io-free; this adds the browser glue: anXtermTerminalDriverthat maps the engine's alternate-screen frames to xterm.js (and itsonData/onResizeback to the engine), and a full-screen takeover seam inWebShellHost(the browser counterpart to the CLI'sLineEditor.suspendInput) that diverts every raw keystroke to the IDE while it owns the screen and restores the prompt on exit. - The agent panel routes provider calls through the Hub (same precedence as
:ai: custom key → Hub default → setup help) and gates itsrun_commandtool with the samecommand_shieldthe CLI uses. File operations run on the node over the connected session (RemoteWorkspace).
- The IDE engine (
1.10.1 #
Fixed #
- The release web build (
dart2js) produced nomain.dart.jsunder omnyshell 1.43.0: that release's "web-safe" barrel transitively importeddart:io(viaRemoteWorkspace → local_workspace.dart), so dart2js silently skipped compilingweb/main.dart. Bumped theomnyshelldependency to ^1.43.1, which movesWorkspaceExceptioninto thedart:io-freeWorkspaceport and makes the barrel genuinely browser-compilable again. No web code change.
1.10.0 #
Changed #
- Bumped the
omnyshelldependency to ^1.43.0. The upstream release refactors the:ideengine behind an async,dart:io-freeWorkspaceport so it now compiles to JavaScript for the browser: the web client barrel now exportsIdeApp,Workspace,RemoteWorkspace,TerminalDriver,ScreenBufferand the key decoder, the building blocks for embedding the terminal IDE in a web app (supply aTerminalDriverthat rendersScreenBufferframes into a browser terminal and aRemoteWorkspaceover the connected client). This bump only pulls in those exports; the web client does not yet wire up the IDE, so there is no user-facing change — a routine dependency refresh.
1.9.0 #
Changed #
- Bumped the
omnyshelldependency to ^1.42.0. The upstream release adds the full-screen:ideTUI (a terminal IDE with a file tree, tabs, syntax highlighting, a git-change gutter, an integrated terminal and an AI agent panel) plus an optional starting directory foromnyshell local. All of it is native-only (:ideis browser-excluded because it needsdart:io), so it does not affect the browser client; this is a routine dependency refresh.
1.8.1 #
Changed #
- Bumped the
omnyshelldependency to ^1.41.1. The upstream changes (a nativeomnyshell localCLI mode and README documentation) do not affect the browser client; this is a routine dependency refresh.
Documentation #
- README: added the live PWA link (https://omnygrid.github.io/omnyshell_web/),
documented the in-browser
:aiagent (provider/model/key or Hub default, with the post-run token-usage stats line), and corrected the install instructions — the client now depends on the publishedomnyshellpackage from pub.flutter-io.cn, not a../omnyshellpath override (which is now a local-only dev aid).
1.8.0 #
Changed #
- Bumped the
omnyshelldependency to ^1.40.0, which upgrades the:aiagent's command shield (command_shield^1.4.0) with a correct bash/POSIX file-descriptor redirection parser. The discard/merge idioms the model routinely emits —cmd 2>&1,cmd >/dev/null 2>&1,&>/dev/null— are now read as a single clean command instead of producing a spurious "Redirection without a target" diagnostic and a phantom invocation, and they no longer over-report a filesystem write.
1.7.0 #
Added #
- Bumped the
omnyshelldependency to ^1.39.0, which adds an AI agent token-usage summary to the web client:- After every
:aianswer the agent prints a muted (gray) stats line — shown just before the "chat to continue / Enter to end" prompt so the running totals are visible before the interaction ends — e.g.ai: 12,840 tokens (in 10,210 · out 2,630 · cached 1,024) · 78 tok/s · 4 requests · 14.6s— reporting tokens used (input/output, plus prompt-cache hits), the output generation speed (tok/s), the number of model requests, and the wall-clock duration. Totals accumulate across a multi-turn session and the line also shows on abort or a provider error. - Generation speed stays accurate over the Hub proxy: the Hub reports its real upstream request time, so the browser↔Hub round-trip is excluded from tok/s.
- After every
1.6.0 #
Added #
- Bumped the
omnyshelldependency to ^1.38.0, which improves the:aiagent in the web client:- A magenta divider (
╌) is drawn just before a presented plan, separating it from the preceding investigation output so the "investigating → here is the plan" transition reads at a glance. - After the final answer the agent asks whether to keep chatting or end. Typing a message continues the conversation in the same context (a fresh step budget is granted and the in-flight plan state resets); pressing Enter ends the agent.
- A magenta divider (
1.5.2 #
Fixed #
- The
:aiagent no longer flashes a fresh shell prompt line between its command outputs in the web client. While the agent owns the screen its idle prompt is now suppressed — matching the CLI — and restored once the agent finishes. Interactive confirmation prompts are unaffected.
1.5.1 #
Changed #
- Bumped the
omnyshelldependency to ^1.37.0, which improves the:aiagent: plan mode now continues from the failed step on a re-presented plan (no re-running already-succeeded, possibly non-idempotent commands), and version/help probes (node --version,dart --version, …) are classified as safe investigation instead of mutating commands.
Fixed #
- The
:aiagent now runs its commands in the live PTY session (POSIX shells), matching the CLI, so interactive prompts work — e.g.sudocan ask for a password and the user types it directly in the terminal. Previously the web agent used a one-offexecwith no TTY, sosudofailed with "a terminal is required to read the password". Non-POSIX shells still fall back toexec.
1.5.0 #
Added #
- AI agent in the browser: the
:aicommand now works in the web client. A browser can't call AI provider APIs directly (CORS), so provider HTTPS calls are routed through the Hub; the agent then investigates the node, plans, and runs commands toward a natural-language goal — the same three modes as the CLI (standard,plan,auto). Requires omnyshell ^1.36.0 (Hub AI proxy +HubHttpClient); to use the "Hub default" path the Hub must be started with AI credentials (omnyshell hub start --ai-config <path>, or~/.omnyshell/ai.yaml/*_API_KEYenv), otherwise bring your own key in Settings. - AI settings in the global Settings panel (⚙): use the Hub's default provider/model (the API key stays on the Hub and is injected when proxying) or bring your own provider/model + API key (stored in this browser only, forwarded via the Hub). Also sets the default agent mode and reply language.
- Interactive agent prompts in the terminal — confirmations are read inline, and
Ctrl-C aborts a running
:aiagent.
Changed #
- Bumped the
omnyshelldependency to ^1.36.0.
Fixed #
- The
:aiagent's captured command output no longer "staircases" in the terminal: local-command output now normalizes bare LFs to CRLF (the browser terminal is a pipe with no line discipline, unlike the remote shell's PTY).
1.4.1 #
Fixed #
- The login footer showed the wrong Web Client version (
1.3.0) in the 1.4.0 release: the hardcodedwebClientVersionconstant wasn't bumped alongsidepubspec.yaml. Now reports the correct version.
1.4.0 #
Added #
- Selectable terminal dimensions for new sessions, in a new global Settings panel (⚙ in the header): Auto-fit (the previous behavior), a Standard 80×24, device-aware "Fit landscape" / "Fit portrait" presets computed for the current screen, and a Custom cols×rows entry. The PTY can't be resized after a session starts, so a fixed grid is pinned and the font is scaled to fit it — the terminal tracks the window in both orientations without changing cols/rows.
- Terminal text-size control (Auto / Smaller / Normal / Larger). Auto derives the font from the chosen columns so they fill the width; the on-screen key bar scales with the text, so a smaller font yields smaller keys and more columns on a phone. Dimension choices apply to the next session; text size applies live.
Changed #
- Bumped the
omnyshelldependency to ^1.34.0. - The terminal host is now pinned to a definite height equal to the available space, so it reliably shrinks as well as grows with the window (previously a too-tall canvas — e.g. after exiting fullscreen — could not shrink back).
- Exiting fullscreen forces an xterm redraw and the terminal re-fits across a few frames after mount, fixing a stale height that previously needed a manual reflow.
Fixed #
- "Terminate" on the session screen now reliably ends the session on the node.
It uses the control-plane kill-by-id (the same path the sessions list uses)
instead of an in-channel close, whose
ChannelCloseframe a browser WebSocket could drop on teardown — leaving the node to park the session so it stayed listed.
1.3.0 #
Added #
- Command history in the terminal: Up/Down walk previously entered commands
(prefix-restricted when text has been typed), persisted to
localStorageand scoped per principal+node. This reuses theomnyshellpackage's shared history primitives (CommandHistoryBuffer+HistoryCursor, requiresomnyshell^1.33.0), so it behaves identically to the CLI — only the storage differs (browser storage vs a history file).
Changed #
- The login form panel uses more of the screen width on phones: the outer gutter and the card's inner padding are trimmed on small viewports (respecting safe-area insets), giving the inputs noticeably more room.
1.2.0 #
Added #
- The login screen footer shows the Web Client version and the OmnyShell version
(read from the package's
omnyShellVersion, requiresomnyshell^1.32.0).
1.1.0 #
Added #
- Fullscreen toggle for the terminal: a button expands the terminal to fill the whole window (hiding the app header and toolbar) so mobile devices get the maximum screen area, with a floating exit button to restore the normal layout.
- TAB completion in the terminal — pressing Tab now completes the word under the cursor by running the shell's completion command on the node (the same mechanism the CLI uses), instead of being dropped.
- Local
:commands now work in the web terminal (:help,:tree,:tunnel,:info,:whoami,:ping,:detach,:exit, …). They are handled client-side via the sharedomnyshellregistry and never forwarded to the remote shell. Filesystem commands (:download/:upload/:drive) are intentionally unavailable in the browser.
Fixed #
- The terminal now refits reliably on fullscreen enter/exit (and keyboard /
rotation / resize) via a
ResizeObserver, instead of mis-sizing until the keyboard was toggled. - After exiting fullscreen the terminal no longer overflows the screen on iOS:
the locked terminal screen is anchored to the visible viewport
(
--vvh/100dvh) rather than the (taller) layout viewport, so the bottom row and key bar stay on-screen. - The login Hub and Principal fields opt out of mobile auto-capitalization and
auto-correction (
autocapitalize=none,autocorrect=off,spellcheck=false) so the keyboard no longer capitalizes the first letter.
Changed #
- The terminal floors its height at the available space (between the chrome above it and the key bar reserved below it) so it always uses the full area without overlapping the key bar — except in fullscreen or while the keyboard is open.
- Navigating to another screen (nodes / sessions / …) now resets scroll to the top instead of inheriting the previous screen's scroll position.
- Long key/value entries (e.g. a node UID) truncate with an ellipsis instead of widening the page on mobile.
- Entering/exiting fullscreen now scrolls the terminal to the bottom (latest output / prompt) and re-fits at a few delays (next frame, 120/300/500 ms) to catch the mobile browser chrome animating in/out, so the terminal box and key bar settle to the right size/position.
- On the terminal screen the page no longer scrolls or rubber-bands; the terminal fills the space below the toolbar and only its own content (xterm scrollback) scrolls.
- The terminal now stays usable with the mobile soft keyboard open: the layout
tracks the visual viewport so the on-screen key bar sits just above the
keyboard and the prompt row stays visible (xterm re-fits on keyboard
open/close). Implemented via a
visualViewporttracker exposing--vvh/--kband a.keyboard-openflag. - Added a New Session button to the sessions list so a fresh shell can be opened without going back to the node screen.
- Removed the redundant session title ("New shell" / "Session …") from the terminal toolbar to reclaim space.
- The on-screen accessory key bar now places Home/End/PgUp/PgDn at the end (after Copy/Paste).
- Disabled pinch-to-zoom on mobile (viewport meta +
touch-action+ iOS gesture handlers) so two-finger gestures don't zoom the page; panning/scrolling stays. - The terminal toolbar (Sessions / Fullscreen / Detach / Terminate) uses smaller buttons and wraps instead of overflowing, so the row fits a phone width.
- Rotating the device while in fullscreen now exits fullscreen, since the layout isn't usable across an orientation change.
- Bumped
omnyshellto ^1.31.0 (for the browser-safe local-command layer).
1.0.0 #
- Initial release of the OmnyShell web client.
- Browser-only client over the real
omnyshellprotocol (no custom backend), enabled by a browser-compatible transport seam added to theomnyshellpackage. - Authentication (bearer token) with logout, session persistence, auto-restore, and one-click reconnect after a dropped connection.
- Node discovery: list, detail (platform/capabilities/labels/status), refresh, cache-backed instant paint.
- Session management: list, peek, detach, resume, kill, and open a new shell.
- Interactive xterm.js terminal wired to remote sessions.
- Light / dark / system theming with a persistent selector and no flash on load.
- Comprehensive unit, integration, widget/DOM, and end-to-end tests.