From f49afd3122eaa689b9366035a54d5e77d1dc941b Mon Sep 17 00:00:00 2001 From: emozilla Date: Tue, 21 Apr 2026 02:09:12 -0400 Subject: [PATCH 1/4] feat(web): add /api/pty WebSocket bridge to embed TUI in dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exposes hermes --tui over a PTY-backed WebSocket so the dashboard can embed the real TUI rather than reimplement its surface. The browser attaches xterm.js to the socket; keystrokes flow in, PTY output bytes flow out. Architecture: browser (xterm.js) │ onData ───► ws.send(keystrokes) │ onResize ► ws.send('\x1b[RESIZE:cols;rows]') │ write ◄── ws.onmessage (PTY bytes) ▼ FastAPI /api/pty (token-gated, loopback-only) ▼ PtyBridge (ptyprocess) ── spawns node ui-tui/dist/entry.js ──► tui_gateway + AIAgent Components ---------- hermes_cli/pty_bridge.py Thin wrapper around ptyprocess.PtyProcess: byte-safe read/write on the master fd via os.read/os.write (not PtyProcessUnicode — ANSI is inherently byte-oriented and UTF-8 boundaries may land mid-read), non-blocking select-based reads, TIOCSWINSZ resize, idempotent SIGHUP→SIGTERM→SIGKILL teardown, platform guard (POSIX-only; Windows is WSL-supported only). hermes_cli/web_server.py @app.websocket("/api/pty") endpoint gated by the existing _SESSION_TOKEN (via ?token= query param since browsers can't set Authorization on WS upgrades). Loopback-only enforcement. Reader task uses run_in_executor to pump PTY bytes without blocking the event loop. Writer loop intercepts a custom \x1b[RESIZE:cols;rows] escape before forwarding to the PTY. The endpoint resolves the TUI argv through a _resolve_chat_argv hook so tests can inject fake commands without building the real TUI. Tests ----- tests/hermes_cli/test_pty_bridge.py — 12 unit tests: spawn, stdout, stdin round-trip, EOF, resize (via TIOCSWINSZ + tput readback), close idempotency, cwd, env forwarding, unavailable-platform error. tests/hermes_cli/test_web_server.py — TestPtyWebSocket adds 7 tests: missing/bad token rejection (close code 4401), stdout streaming, stdin round-trip, resize escape forwarding, unavailable-platform ANSI error frame + 1011 close, resume parameter forwarding to argv. 96 tests pass under scripts/run_tests.sh. (cherry picked from commit 29b337bca70fc9efb082a5a852ea2cd5381af1a9) feat(web): add Chat tab with xterm.js terminal + Sessions resume button (cherry picked from commit 3d21aee8 by emozilla, conflicts resolved against current main: BUILTIN_ROUTES table + plugin slot layout) fix(tui): replace OSC 52 jargon in /copy confirmation When the user ran /copy successfully, Ink confirmed with: sent OSC52 copy sequence (terminal support required) That reads like a protocol spec to everyone who isn't a terminal implementer. The caveat was a historical artifact — OSC 52 wasn't universally supported when this message was written, so the TUI honestly couldn't guarantee the copy had landed anywhere. Today every modern terminal (including the dashboard's embedded xterm.js) handles OSC 52 reliably. Say what the user actually wants to know — that it copied, and how much — matching the message the TUI already uses for selection copy: copied 1482 chars (cherry picked from commit a0701b1d5a598dd1d3b94038a7bcbb2a3ab559fc) docs: document the dashboard Chat tab AGENTS.md — new subsection under TUI Architecture explaining that the dashboard embeds the real hermes --tui rather than rewriting it, with pointers to the pty_bridge + WebSocket endpoint and the rule 'never add a parallel chat surface in React.' website/docs/user-guide/features/web-dashboard.md — user-facing Chat section inside the existing Web Dashboard page, covering how it works (WebSocket + PTY + xterm.js), the Sessions-page resume flow, and prerequisites (Node.js, ptyprocess, POSIX kernel / WSL on Windows). (cherry picked from commit 2c2e32cc4519973c77b63016316b065c0f656704) feat(tui-gateway): transport-aware dispatch + WebSocket sidecar Decouples the JSON-RPC dispatcher from its I/O sink so the same handler surface can drive multiple transports concurrently. The PTY chat tab already speaks to the TUI binary as bytes — this adds a structured event channel alongside it for dashboard-side React widgets that need typed events (tool.start/complete, model picker state, slash catalog) that PTY can't surface. - `tui_gateway/transport.py` — `Transport` protocol + `contextvars` binding + module-level `StdioTransport` fallback. The stdio stream resolves through a lambda so existing tests that monkey-patch `_real_stdout` keep passing without modification. - `tui_gateway/ws.py` — WebSocket transport implementation; FastAPI endpoint mounting lives in hermes_cli/web_server.py. - `tui_gateway/server.py`: - `write_json` routes via session transport (for async events) → contextvar transport (for in-request writes) → stdio fallback. - `dispatch(req, transport=None)` binds the transport for the request lifetime and propagates it to pool workers via `contextvars.copy_context` so async handlers don't lose their sink. - `_init_session` and the manual-session create path stash the request's transport so out-of-band events (subagent.complete, etc.) fan out to the right peer. `tui_gateway.entry` (Ink's stdio handshake) is unchanged externally — it falls through every precedence step into the stdio fallback, byte- identical to the previous behaviour. feat(web): ChatSidebar — JSON-RPC sidecar next to xterm.js terminal Composes the two transports into a single Chat tab: ┌─────────────────────────────────────────┬──────────────┐ │ xterm.js / PTY (emozilla #13379) │ ChatSidebar │ │ the literal hermes --tui process │ /api/ws │ └─────────────────────────────────────────┴──────────────┘ terminal bytes structured events The terminal pane stays the canonical chat surface — full TUI fidelity, slash commands, model picker, mouse, skin engine, wide chars all paint inside the terminal. The sidebar opens a parallel JSON-RPC WebSocket to the same gateway and renders metadata that PTY can't surface to React chrome: • model + provider badge with connection state (click → switch) • running tool-call list (driven by tool.start / tool.progress / tool.complete events) • model picker dialog (gateway-driven, reuses ModelPickerDialog) The sidecar is best-effort. If the WS can't connect (older gateway, network hiccup, missing token) the terminal pane keeps working unimpaired — sidebar just shows the connection-state badge in the appropriate tone. - `web/src/components/ChatSidebar.tsx` — new component (~270 lines). Owns its GatewayClient, drives the model picker through `slash.exec`, fans tool events into a capped tool list. - `web/src/pages/ChatPage.tsx` — split layout: terminal pane (`flex-1`) + sidebar (`w-80`, `lg+` only). - `hermes_cli/web_server.py` — mount `/api/ws` (token + loopback guards mirror /api/pty), delegate to `tui_gateway.ws.handle_ws`. Co-authored-by: emozilla refactor(web): /clean pass on ChatSidebar + ChatPage lint debt - ChatSidebar: lift gw out of useRef into a useMemo derived from a reconnect counter. React 19's react-hooks/refs and react-hooks/ set-state-in-effect rules both fire when you touch a ref during render or call setState from inside a useEffect body. The counter-derived gw is the canonical pattern for "external resource that needs to be replaceable on user action" — re-creating the client comes from bumping `version`, the effect just wires + tears down. Drops the imperative `gwRef.current = …` reassign in reconnect, drops the truthy ref guard in JSX. modelLabel + banner inlined as derived locals (one-off useMemo was overkill). - ChatPage: lazy-init the banner state from the missing-token check so the effect body doesn't have to setState on first run. Drops the unused react-hooks/exhaustive-deps eslint-disable. Adds a scoped no-control-regex disable on the SGR mouse parser regex (the \\x1b is intentional for xterm escape sequences). All my-touched files now lint clean. Remaining warnings on web/ belong to pre-existing files this PR doesn't touch. Verified: vitest 249/249, ui-tui eslint clean, web tsc clean, python imports clean. chore: uptick fix(web): drop ChatSidebar tool list — events can't cross PTY/WS boundary The /api/pty endpoint spawns `hermes --tui` as a child process with its own tui_gateway and _sessions dict; /api/ws runs handle_ws in-process in the dashboard server with a separate _sessions dict. Tool events fire on the child's gateway and never reach the WS sidecar, so the sidebar's tool.start/progress/complete listeners always observed an empty list. Drop the misleading list (and the now-orphaned ToolCall primitive), keep model badge + connection state + model picker + error banner — those work because they're sidecar-local concerns. Surfacing tool calls in the sidebar requires cross-process forwarding (PTY child opens a back-WS to the dashboard, gateway tees emits onto stdio + sidecar transport) — proper feature for a follow-up. feat(web): wire ChatSidebar tool list to PTY child via /api/pub broadcast The dashboard's /api/pty spawns hermes --tui as a child process; tool events fire in the python tui_gateway grandchild and never crossed the process boundary into the in-process WS sidecar — so the sidebar tool list was always empty. Cross-process forwarding: - tui_gateway: TeeTransport (transport.py) + WsPublisherTransport (event_publisher.py, sync websockets client). entry.py installs the tee on _stdio_transport when HERMES_TUI_SIDECAR_URL is set, mirroring every dispatcher emit to a back-WS without disturbing Ink's stdio handshake. - hermes_cli/web_server.py: new /api/pub (publisher) + /api/events (subscriber) endpoints with a per-channel registry. /api/pty now accepts ?channel= and propagates the sidecar URL via env. start_server also stashes app.state.bound_port so the URL is constructable. - web/src/pages/ChatPage.tsx: generates a channel UUID per mount, passes it to /api/pty and as a prop to ChatSidebar. - web/src/components/ChatSidebar.tsx: opens /api/events?channel=, fans tool.start/progress/complete back into the ToolCall list. Restores the ToolCall primitive. Tests: 4 new TestPtyWebSocket cases cover channel propagation, broadcast fan-out, and missing-channel rejection (10 PTY tests pass, 120 web_server tests overall). fix(web): address Copilot review on #14890 Five threads, all real: - gatewayClient.ts: register `message`/`close` listeners BEFORE awaiting the open handshake. Server emits `gateway.ready` immediately after accept, so a listener attached after the open promise could race past the initial skin payload and lose it. - ChatSidebar.tsx: wire `error`/`close` on the /api/events subscriber WS into the existing error banner. 4401/4403 (auth/loopback reject) surface as a "reload the page" message; mid-stream drops surface as "events feed disconnected" with the existing reconnect button. Clean unmount closes (1000/1001) stay silent. - web-dashboard.md: install hint was `pip install hermes-agent[web]` but ptyprocess lives in the `pty` extra, not `web`. Switch to `hermes-agent[web,pty]` in both prerequisite blocks. - AGENTS.md: previous "never add a parallel React chat surface" guidance was overbroad and contradicted this PR's sidebar. Tightened to forbid re-implementing the transcript/composer/PTY terminal while explicitly allowing structured supporting widgets (sidebar / model picker / inspectors), matching the actual architecture. - web/package-lock.json: regenerated cleanly so the wterm sibling workspace paths (extraneous machine-local entries) stop polluting CI. Tests: 249/249 vitest, 10/10 PTY/events, web tsc clean. refactor(web): /clean pass on ChatSidebar events handler Spotted in the round-2 review: - Banner flashed on clean unmount: `ws.close()` from the effect cleanup fires `close` with code 1005, opened=true, neither 1000 nor 1001 — hit the "unexpected drop" branch. Track `unmounting` in the effect scope and gate the banner through a `surface()` helper so cleanup closes stay silent. - DRY the duplicated "events feed disconnected" string into a local const used by both the error and close handlers. - Drop the `opened` flag (no longer needed once the unmount guard is the source of truth for "is this an expected close?"). --- AGENTS.md | 13 + hermes_cli/pty_bridge.py | 221 ++++ hermes_cli/web_server.py | 312 ++++- tests/hermes_cli/test_pty_bridge.py | 172 +++ tests/hermes_cli/test_web_server.py | 238 ++++ tui_gateway/entry.py | 23 + tui_gateway/event_publisher.py | 81 ++ tui_gateway/server.py | 85 +- tui_gateway/transport.py | 125 ++ tui_gateway/ws.py | 174 +++ ui-tui/src/app/slash/commands/core.ts | 2 +- web/package-lock.json | 1168 +++++++++-------- web/package.json | 5 + .../fonts-terminal/JetBrainsMono-Bold.woff2 | Bin 0 -> 94628 bytes .../fonts-terminal/JetBrainsMono-Italic.woff2 | Bin 0 -> 96428 bytes .../JetBrainsMono-Regular.woff2 | Bin 0 -> 92380 bytes web/src/App.tsx | 3 + web/src/components/ChatSidebar.tsx | 360 +++++ web/src/components/Markdown.tsx | 128 +- web/src/components/ModelPickerDialog.tsx | 392 ++++++ web/src/components/SlashPopover.tsx | 174 +++ web/src/components/ToolCall.tsx | 228 ++++ web/src/i18n/en.ts | 2 + web/src/i18n/types.ts | 2 + web/src/i18n/zh.ts | 2 + web/src/index.css | 30 + web/src/lib/gatewayClient.ts | 236 ++++ web/src/lib/resolve-page-title.ts | 1 + web/src/lib/slashExec.ts | 163 +++ web/src/pages/ChatPage.tsx | 474 +++++++ web/src/pages/SessionsPage.tsx | 24 +- web/vite.config.ts | 5 +- .../docs/user-guide/features/web-dashboard.md | 28 +- 33 files changed, 4259 insertions(+), 612 deletions(-) create mode 100644 hermes_cli/pty_bridge.py create mode 100644 tests/hermes_cli/test_pty_bridge.py create mode 100644 tui_gateway/event_publisher.py create mode 100644 tui_gateway/transport.py create mode 100644 tui_gateway/ws.py create mode 100644 web/public/fonts-terminal/JetBrainsMono-Bold.woff2 create mode 100644 web/public/fonts-terminal/JetBrainsMono-Italic.woff2 create mode 100644 web/public/fonts-terminal/JetBrainsMono-Regular.woff2 create mode 100644 web/src/components/ChatSidebar.tsx create mode 100644 web/src/components/ModelPickerDialog.tsx create mode 100644 web/src/components/SlashPopover.tsx create mode 100644 web/src/components/ToolCall.tsx create mode 100644 web/src/lib/gatewayClient.ts create mode 100644 web/src/lib/slashExec.ts create mode 100644 web/src/pages/ChatPage.tsx diff --git a/AGENTS.md b/AGENTS.md index ae78e005a..05a6742d4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -240,6 +240,19 @@ npm run fmt # prettier npm test # vitest ``` +### TUI in the Dashboard (`hermes dashboard` → `/chat`) + +The dashboard embeds the real `hermes --tui` — **not** a rewrite. See `hermes_cli/pty_bridge.py` + the `@app.websocket("/api/pty")` endpoint in `hermes_cli/web_server.py`. + +- Browser loads `web/src/pages/ChatPage.tsx`, which mounts xterm.js's `Terminal` with the WebGL renderer, `@xterm/addon-fit` for container-driven resize, and `@xterm/addon-unicode11` for modern wide-character widths. +- `/api/pty?token=…` upgrades to a WebSocket; auth uses the same ephemeral `_SESSION_TOKEN` as REST, via query param (browsers can't set `Authorization` on WS upgrade). +- The server spawns whatever `hermes --tui` would spawn, through `ptyprocess` (POSIX PTY — WSL works, native Windows does not). +- Frames: raw PTY bytes each direction; resize via `\x1b[RESIZE:;]` intercepted on the server and applied with `TIOCSWINSZ`. + +**Do not re-implement the primary chat experience in React.** The main transcript, composer/input flow (including slash-command behavior), and PTY-backed terminal belong to the embedded `hermes --tui` — anything new you add to Ink shows up in the dashboard automatically. If you find yourself rebuilding the transcript or composer for the dashboard, stop and extend Ink instead. + +**Structured React UI around the TUI is allowed when it is not a second chat surface.** Sidebar widgets, inspectors, summaries, status panels, and similar supporting views (e.g. `ChatSidebar`, `ModelPickerDialog`, `ToolCall`) are fine when they complement the embedded TUI rather than replacing the transcript / composer / terminal. Keep their state independent of the PTY child's session and surface their failures non-destructively so the terminal pane keeps working unimpaired. + --- ## Adding New Tools diff --git a/hermes_cli/pty_bridge.py b/hermes_cli/pty_bridge.py new file mode 100644 index 000000000..b32013f7f --- /dev/null +++ b/hermes_cli/pty_bridge.py @@ -0,0 +1,221 @@ +"""PTY bridge for `hermes dashboard` chat tab. + +Wraps a child process behind a pseudo-terminal so its ANSI output can be +streamed to a browser-side terminal emulator (xterm.js) and typed +keystrokes can be fed back in. The only caller today is the +``/api/pty`` WebSocket endpoint in ``hermes_cli.web_server``. + +Design constraints: + +* **POSIX-only.** Hermes Agent supports Windows exclusively via WSL, which + exposes a native POSIX PTY via ``openpty(3)``. Native Windows Python + has no PTY; :class:`PtyUnavailableError` is raised with a user-readable + install/platform message so the dashboard can render a banner instead of + crashing. +* **Zero Node dependency on the server side.** We use :mod:`ptyprocess`, + which is a pure-Python wrapper around the OS calls. The browser talks + to the same ``hermes --tui`` binary it would launch from the CLI, so + every TUI feature (slash popover, model picker, tool rows, markdown, + skin engine, clarify/sudo/approval prompts) ships automatically. +* **Byte-safe I/O.** Reads and writes go through the PTY master fd + directly — we avoid :class:`ptyprocess.PtyProcessUnicode` because + streaming ANSI is inherently byte-oriented and UTF-8 boundaries may land + mid-read. +""" + +from __future__ import annotations + +import errno +import fcntl +import os +import select +import signal +import struct +import sys +import termios +import time +from typing import Optional, Sequence + +try: + import ptyprocess # type: ignore + _PTY_AVAILABLE = not sys.platform.startswith("win") +except ImportError: # pragma: no cover - dev env without ptyprocess + ptyprocess = None # type: ignore + _PTY_AVAILABLE = False + + +__all__ = ["PtyBridge", "PtyUnavailableError"] + + +class PtyUnavailableError(RuntimeError): + """Raised when a PTY cannot be created on this platform. + + Today this means native Windows (no ConPTY bindings) or a dev + environment missing the ``ptyprocess`` dependency. The dashboard + surfaces the message to the user as a chat-tab banner. + """ + + +class PtyBridge: + """Thin wrapper around ``ptyprocess.PtyProcess`` for byte streaming. + + Not thread-safe. A single bridge is owned by the WebSocket handler + that spawned it; the reader runs in an executor thread while writes + happen on the event-loop thread. Both sides are OK because the + kernel PTY is the actual synchronization point — we never call + :mod:`ptyprocess` methods concurrently, we only call ``os.read`` and + ``os.write`` on the master fd, which is safe. + """ + + def __init__(self, proc: "ptyprocess.PtyProcess"): # type: ignore[name-defined] + self._proc = proc + self._fd: int = proc.fd + self._closed = False + + # -- lifecycle -------------------------------------------------------- + + @classmethod + def is_available(cls) -> bool: + """True if a PTY can be spawned on this platform.""" + return bool(_PTY_AVAILABLE) + + @classmethod + def spawn( + cls, + argv: Sequence[str], + *, + cwd: Optional[str] = None, + env: Optional[dict] = None, + cols: int = 80, + rows: int = 24, + ) -> "PtyBridge": + """Spawn ``argv`` behind a new PTY and return a bridge. + + Raises :class:`PtyUnavailableError` if the platform can't host a + PTY. Raises :class:`FileNotFoundError` or :class:`OSError` for + ordinary exec failures (missing binary, bad cwd, etc.). + """ + if not _PTY_AVAILABLE: + raise PtyUnavailableError( + "Pseudo-terminals are unavailable on this platform. " + "Hermes Agent supports Windows only via WSL." + ) + # Let caller-supplied env fully override inheritance; if they pass + # None we inherit the server's env (same semantics as subprocess). + spawn_env = os.environ.copy() if env is None else env + proc = ptyprocess.PtyProcess.spawn( # type: ignore[union-attr] + list(argv), + cwd=cwd, + env=spawn_env, + dimensions=(rows, cols), + ) + return cls(proc) + + @property + def pid(self) -> int: + return int(self._proc.pid) + + def is_alive(self) -> bool: + if self._closed: + return False + try: + return bool(self._proc.isalive()) + except Exception: + return False + + # -- I/O -------------------------------------------------------------- + + def read(self, timeout: float = 0.2) -> Optional[bytes]: + """Read up to 64 KiB of raw bytes from the PTY master. + + Returns: + * bytes — zero or more bytes of child output + * empty bytes (``b""``) — no data available within ``timeout`` + * None — child has exited and the master fd is at EOF + + Never blocks longer than ``timeout`` seconds. Safe to call after + :meth:`close`; returns ``None`` in that case. + """ + if self._closed: + return None + try: + readable, _, _ = select.select([self._fd], [], [], timeout) + except (OSError, ValueError): + return None + if not readable: + return b"" + try: + data = os.read(self._fd, 65536) + except OSError as exc: + # EIO on Linux = slave side closed. EBADF = already closed. + if exc.errno in (errno.EIO, errno.EBADF): + return None + raise + if not data: + return None + return data + + def write(self, data: bytes) -> None: + """Write raw bytes to the PTY master (i.e. the child's stdin).""" + if self._closed or not data: + return + # os.write can return a short write under load; loop until drained. + view = memoryview(data) + while view: + try: + n = os.write(self._fd, view) + except OSError as exc: + if exc.errno in (errno.EIO, errno.EBADF, errno.EPIPE): + return + raise + if n <= 0: + return + view = view[n:] + + def resize(self, cols: int, rows: int) -> None: + """Forward a terminal resize to the child via ``TIOCSWINSZ``.""" + if self._closed: + return + # struct winsize: rows, cols, xpixel, ypixel (all unsigned short) + winsize = struct.pack("HHHH", max(1, rows), max(1, cols), 0, 0) + try: + fcntl.ioctl(self._fd, termios.TIOCSWINSZ, winsize) + except OSError: + pass + + # -- teardown --------------------------------------------------------- + + def close(self) -> None: + """Terminate the child (SIGTERM → 0.5s grace → SIGKILL) and close fds. + + Idempotent. Reaping the child is important so we don't leak + zombies across the lifetime of the dashboard process. + """ + if self._closed: + return + self._closed = True + + # SIGHUP is the conventional "your terminal went away" signal. + # We escalate if the child ignores it. + for sig in (signal.SIGHUP, signal.SIGTERM, signal.SIGKILL): + if not self._proc.isalive(): + break + try: + self._proc.kill(sig) + except Exception: + pass + deadline = time.monotonic() + 0.5 + while self._proc.isalive() and time.monotonic() < deadline: + time.sleep(0.02) + + try: + self._proc.close(force=True) + except Exception: + pass + + # Context-manager sugar — handy in tests and ad-hoc scripts. + def __enter__(self) -> "PtyBridge": + return self + + def __exit__(self, *_exc) -> None: + self.close() diff --git a/hermes_cli/web_server.py b/hermes_cli/web_server.py index 083e0714f..e20bd6289 100644 --- a/hermes_cli/web_server.py +++ b/hermes_cli/web_server.py @@ -49,7 +49,7 @@ from hermes_cli.config import ( from gateway.status import get_running_pid, read_runtime_status try: - from fastapi import FastAPI, HTTPException, Request + from fastapi import FastAPI, HTTPException, Request, WebSocket, WebSocketDisconnect from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse, HTMLResponse, JSONResponse from fastapi.staticfiles import StaticFiles @@ -2263,6 +2263,313 @@ async def get_usage_analytics(days: int = 30): db.close() +# --------------------------------------------------------------------------- +# /api/pty — PTY-over-WebSocket bridge for the dashboard "Chat" tab. +# +# The endpoint spawns the same ``hermes --tui`` binary the CLI uses, behind +# a POSIX pseudo-terminal, and forwards bytes + resize escapes across a +# WebSocket. The browser renders the ANSI through xterm.js (see +# web/src/pages/ChatPage.tsx). +# +# Auth: ``?token=`` query param (browsers can't set +# Authorization on the WS upgrade). Same ephemeral ``_SESSION_TOKEN`` as +# REST. Localhost-only — we defensively reject non-loopback clients even +# though uvicorn binds to 127.0.0.1. +# --------------------------------------------------------------------------- + +import re +import asyncio + +from hermes_cli.pty_bridge import PtyBridge, PtyUnavailableError + +_RESIZE_RE = re.compile(rb"\x1b\[RESIZE:(\d+);(\d+)\]") +_PTY_READ_CHUNK_TIMEOUT = 0.2 +_VALID_CHANNEL_RE = re.compile(r"^[A-Za-z0-9._-]{1,128}$") +# Starlette's TestClient reports the peer as "testclient"; treat it as +# loopback so tests don't need to rewrite request scope. +_LOOPBACK_HOSTS = frozenset({"127.0.0.1", "::1", "localhost", "testclient"}) + +# Per-channel subscriber registry used by /api/pub (PTY-side gateway → dashboard) +# and /api/events (dashboard → browser sidebar). Keyed by an opaque channel id +# the chat tab generates on mount; entries auto-evict when the last subscriber +# drops AND the publisher has disconnected. +_event_channels: dict[str, set] = {} +_event_lock = asyncio.Lock() + + +def _resolve_chat_argv( + resume: Optional[str] = None, + sidecar_url: Optional[str] = None, +) -> tuple[list[str], Optional[str], Optional[dict]]: + """Resolve the argv + cwd + env for the chat PTY. + + Default: whatever ``hermes --tui`` would run. Tests monkeypatch this + function to inject a tiny fake command (``cat``, ``sh -c 'printf …'``) + so nothing has to build Node or the TUI bundle. + + Session resume is propagated via the ``HERMES_TUI_RESUME`` env var — + matching what ``hermes_cli.main._launch_tui`` does for the CLI path. + Appending ``--resume `` to argv doesn't work because ``ui-tui`` does + not parse its argv. + + `sidecar_url` (when set) is forwarded as ``HERMES_TUI_SIDECAR_URL`` so + the spawned ``tui_gateway.entry`` can mirror dispatcher emits to the + dashboard's ``/api/pub`` endpoint (see :func:`pub_ws`). + """ + from hermes_cli.main import PROJECT_ROOT, _make_tui_argv + + argv, cwd = _make_tui_argv(PROJECT_ROOT / "ui-tui", tui_dev=False) + env: Optional[dict] = None + + if resume or sidecar_url: + env = os.environ.copy() + + if resume: + env["HERMES_TUI_RESUME"] = resume + + if sidecar_url: + env["HERMES_TUI_SIDECAR_URL"] = sidecar_url + + return list(argv), str(cwd) if cwd else None, env + + +def _build_sidecar_url(channel: str) -> Optional[str]: + """ws:// URL the PTY child should publish events to, or None when unbound.""" + host = getattr(app.state, "bound_host", None) + port = getattr(app.state, "bound_port", None) + + if not host or not port: + return None + + netloc = f"[{host}]:{port}" if ":" in host and not host.startswith("[") else f"{host}:{port}" + qs = urllib.parse.urlencode({"token": _SESSION_TOKEN, "channel": channel}) + + return f"ws://{netloc}/api/pub?{qs}" + + +async def _broadcast_event(channel: str, payload: str) -> None: + """Fan out one publisher frame to every subscriber on `channel`.""" + async with _event_lock: + subs = list(_event_channels.get(channel, ())) + + for sub in subs: + try: + await sub.send_text(payload) + except Exception: + # Subscriber went away mid-send; the /api/events finally clause + # will remove it from the registry on its next iteration. + pass + + +def _channel_or_close_code(ws: WebSocket) -> Optional[str]: + """Return the channel id from the query string or None if invalid.""" + channel = ws.query_params.get("channel", "") + + return channel if _VALID_CHANNEL_RE.match(channel) else None + + +@app.websocket("/api/pty") +async def pty_ws(ws: WebSocket) -> None: + # --- auth + loopback check (before accept so we can close cleanly) --- + token = ws.query_params.get("token", "") + expected = _SESSION_TOKEN + if not hmac.compare_digest(token.encode(), expected.encode()): + await ws.close(code=4401) + return + + client_host = ws.client.host if ws.client else "" + if client_host and client_host not in _LOOPBACK_HOSTS: + await ws.close(code=4403) + return + + await ws.accept() + + # --- spawn PTY ------------------------------------------------------ + resume = ws.query_params.get("resume") or None + channel = _channel_or_close_code(ws) + sidecar_url = _build_sidecar_url(channel) if channel else None + + try: + argv, cwd, env = _resolve_chat_argv(resume=resume, sidecar_url=sidecar_url) + except SystemExit as exc: + # _make_tui_argv calls sys.exit(1) when node/npm is missing. + await ws.send_text(f"\r\n\x1b[31mChat unavailable: {exc}\x1b[0m\r\n") + await ws.close(code=1011) + return + + + try: + bridge = PtyBridge.spawn(argv, cwd=cwd, env=env) + except PtyUnavailableError as exc: + await ws.send_text(f"\r\n\x1b[31mChat unavailable: {exc}\x1b[0m\r\n") + await ws.close(code=1011) + return + except (FileNotFoundError, OSError) as exc: + await ws.send_text(f"\r\n\x1b[31mChat failed to start: {exc}\x1b[0m\r\n") + await ws.close(code=1011) + return + + loop = asyncio.get_running_loop() + + # --- reader task: PTY master → WebSocket ---------------------------- + async def pump_pty_to_ws() -> None: + while True: + chunk = await loop.run_in_executor( + None, bridge.read, _PTY_READ_CHUNK_TIMEOUT + ) + if chunk is None: # EOF + return + if not chunk: # no data this tick; yield control and retry + await asyncio.sleep(0) + continue + try: + await ws.send_bytes(chunk) + except Exception: + return + + reader_task = asyncio.create_task(pump_pty_to_ws()) + + # --- writer loop: WebSocket → PTY master ---------------------------- + try: + while True: + msg = await ws.receive() + msg_type = msg.get("type") + if msg_type == "websocket.disconnect": + break + raw = msg.get("bytes") + if raw is None: + text = msg.get("text") + raw = text.encode("utf-8") if isinstance(text, str) else b"" + if not raw: + continue + + # Resize escape is consumed locally, never written to the PTY. + match = _RESIZE_RE.match(raw) + if match and match.end() == len(raw): + cols = int(match.group(1)) + rows = int(match.group(2)) + bridge.resize(cols=cols, rows=rows) + continue + + bridge.write(raw) + except WebSocketDisconnect: + pass + finally: + reader_task.cancel() + try: + await reader_task + except (asyncio.CancelledError, Exception): + pass + bridge.close() + + +# --------------------------------------------------------------------------- +# /api/ws — JSON-RPC WebSocket sidecar for the dashboard "Chat" tab. +# +# Drives the same `tui_gateway.dispatch` surface Ink uses over stdio, so the +# dashboard can render structured metadata (model badge, tool-call sidebar, +# slash launcher, session info) alongside the xterm.js terminal that PTY +# already paints. Both transports bind to the same session id when one is +# active, so a tool.start emitted by the agent fans out to both sinks. +# --------------------------------------------------------------------------- + + +@app.websocket("/api/ws") +async def gateway_ws(ws: WebSocket) -> None: + token = ws.query_params.get("token", "") + if not hmac.compare_digest(token.encode(), _SESSION_TOKEN.encode()): + await ws.close(code=4401) + return + + client_host = ws.client.host if ws.client else "" + if client_host and client_host not in _LOOPBACK_HOSTS: + await ws.close(code=4403) + return + + from tui_gateway.ws import handle_ws + + await handle_ws(ws) + + +# --------------------------------------------------------------------------- +# /api/pub + /api/events — chat-tab event broadcast. +# +# The PTY-side ``tui_gateway.entry`` opens /api/pub at startup (driven by +# HERMES_TUI_SIDECAR_URL set in /api/pty's PTY env) and writes every +# dispatcher emit through it. The dashboard fans those frames out to any +# subscriber that opened /api/events on the same channel id. This is what +# gives the React sidebar its tool-call feed without breaking the PTY +# child's stdio handshake with Ink. +# --------------------------------------------------------------------------- + + +@app.websocket("/api/pub") +async def pub_ws(ws: WebSocket) -> None: + token = ws.query_params.get("token", "") + if not hmac.compare_digest(token.encode(), _SESSION_TOKEN.encode()): + await ws.close(code=4401) + return + + client_host = ws.client.host if ws.client else "" + if client_host and client_host not in _LOOPBACK_HOSTS: + await ws.close(code=4403) + return + + channel = _channel_or_close_code(ws) + if not channel: + await ws.close(code=4400) + return + + await ws.accept() + + try: + while True: + await _broadcast_event(channel, await ws.receive_text()) + except WebSocketDisconnect: + pass + + +@app.websocket("/api/events") +async def events_ws(ws: WebSocket) -> None: + token = ws.query_params.get("token", "") + if not hmac.compare_digest(token.encode(), _SESSION_TOKEN.encode()): + await ws.close(code=4401) + return + + client_host = ws.client.host if ws.client else "" + if client_host and client_host not in _LOOPBACK_HOSTS: + await ws.close(code=4403) + return + + channel = _channel_or_close_code(ws) + if not channel: + await ws.close(code=4400) + return + + await ws.accept() + + async with _event_lock: + _event_channels.setdefault(channel, set()).add(ws) + + try: + while True: + # Subscribers don't speak — the receive() just blocks until + # disconnect so the connection stays open as long as the + # browser holds it. + await ws.receive_text() + except WebSocketDisconnect: + pass + finally: + async with _event_lock: + subs = _event_channels.get(channel) + + if subs is not None: + subs.discard(ws) + + if not subs: + _event_channels.pop(channel, None) + + def mount_spa(application: FastAPI): """Mount the built SPA. Falls back to index.html for client-side routing. @@ -2817,7 +3124,10 @@ def start_server( # Record the bound host so host_header_middleware can validate incoming # Host headers against it. Defends against DNS rebinding (GHSA-ppp5-vxwm-4cf7). + # bound_port is also stashed so /api/pty can build the back-WS URL the + # PTY child uses to publish events to the dashboard sidebar. app.state.bound_host = host + app.state.bound_port = port if open_browser: import webbrowser diff --git a/tests/hermes_cli/test_pty_bridge.py b/tests/hermes_cli/test_pty_bridge.py new file mode 100644 index 000000000..cd6983b90 --- /dev/null +++ b/tests/hermes_cli/test_pty_bridge.py @@ -0,0 +1,172 @@ +"""Unit tests for hermes_cli.pty_bridge — PTY spawning + byte forwarding. + +These tests drive the bridge with minimal POSIX processes (echo, env, sleep, +printf) to verify it behaves like a PTY you can read/write/resize/close. +""" + +from __future__ import annotations + +import os +import sys +import time + +import pytest + +pytest.importorskip("ptyprocess", reason="ptyprocess not installed") + +from hermes_cli.pty_bridge import PtyBridge, PtyUnavailableError + + +skip_on_windows = pytest.mark.skipif( + sys.platform.startswith("win"), reason="PTY bridge is POSIX-only" +) + + +def _read_until(bridge: PtyBridge, needle: bytes, timeout: float = 5.0) -> bytes: + """Accumulate PTY output until we see `needle` or time out.""" + deadline = time.monotonic() + timeout + buf = bytearray() + while time.monotonic() < deadline: + chunk = bridge.read(timeout=0.2) + if chunk is None: + break + buf.extend(chunk) + if needle in buf: + return bytes(buf) + return bytes(buf) + + +@skip_on_windows +class TestPtyBridgeSpawn: + def test_is_available_on_posix(self): + assert PtyBridge.is_available() is True + + def test_spawn_returns_bridge_with_pid(self): + bridge = PtyBridge.spawn(["true"]) + try: + assert bridge.pid > 0 + finally: + bridge.close() + + def test_spawn_raises_on_missing_argv0(self, tmp_path): + with pytest.raises((FileNotFoundError, OSError)): + PtyBridge.spawn([str(tmp_path / "definitely-not-a-real-binary")]) + + +@skip_on_windows +class TestPtyBridgeIO: + def test_reads_child_stdout(self): + bridge = PtyBridge.spawn(["/bin/sh", "-c", "printf hermes-ok"]) + try: + output = _read_until(bridge, b"hermes-ok") + assert b"hermes-ok" in output + finally: + bridge.close() + + def test_write_sends_to_child_stdin(self): + # `cat` with no args echoes stdin back to stdout. We write a line, + # read it back, then signal EOF to let cat exit cleanly. + bridge = PtyBridge.spawn(["/bin/cat"]) + try: + bridge.write(b"hello-pty\n") + output = _read_until(bridge, b"hello-pty") + assert b"hello-pty" in output + finally: + bridge.close() + + def test_read_returns_none_after_child_exits(self): + bridge = PtyBridge.spawn(["/bin/sh", "-c", "printf done"]) + try: + _read_until(bridge, b"done") + # Give the child a beat to exit cleanly, then drain until EOF. + deadline = time.monotonic() + 3.0 + while bridge.is_alive() and time.monotonic() < deadline: + bridge.read(timeout=0.1) + # Next reads after exit should return None (EOF), not raise. + got_none = False + for _ in range(10): + if bridge.read(timeout=0.1) is None: + got_none = True + break + assert got_none, "PtyBridge.read did not return None after child EOF" + finally: + bridge.close() + + +@skip_on_windows +class TestPtyBridgeResize: + def test_resize_updates_child_winsize(self): + # tput reads COLUMNS/LINES from the TTY ioctl (TIOCGWINSZ). + # Spawn a shell, resize, then ask tput for the dimensions. + bridge = PtyBridge.spawn( + ["/bin/sh", "-c", "sleep 0.1; tput cols; tput lines"], + cols=80, + rows=24, + ) + try: + bridge.resize(cols=123, rows=45) + output = _read_until(bridge, b"45", timeout=5.0) + # tput prints just the numbers, one per line + assert b"123" in output + assert b"45" in output + finally: + bridge.close() + + +@skip_on_windows +class TestPtyBridgeClose: + def test_close_is_idempotent(self): + bridge = PtyBridge.spawn(["/bin/sh", "-c", "sleep 30"]) + bridge.close() + bridge.close() # must not raise + assert not bridge.is_alive() + + def test_close_terminates_long_running_child(self): + bridge = PtyBridge.spawn(["/bin/sh", "-c", "sleep 30"]) + pid = bridge.pid + bridge.close() + # Give the kernel a moment to reap + deadline = time.monotonic() + 3.0 + reaped = False + while time.monotonic() < deadline: + try: + os.kill(pid, 0) + time.sleep(0.05) + except ProcessLookupError: + reaped = True + break + assert reaped, f"pid {pid} still running after close()" + + +@skip_on_windows +class TestPtyBridgeEnv: + def test_cwd_is_respected(self, tmp_path): + bridge = PtyBridge.spawn( + ["/bin/sh", "-c", "pwd"], + cwd=str(tmp_path), + ) + try: + output = _read_until(bridge, str(tmp_path).encode()) + assert str(tmp_path).encode() in output + finally: + bridge.close() + + def test_env_is_forwarded(self): + bridge = PtyBridge.spawn( + ["/bin/sh", "-c", "printf %s \"$HERMES_PTY_TEST\""], + env={**os.environ, "HERMES_PTY_TEST": "pty-env-works"}, + ) + try: + output = _read_until(bridge, b"pty-env-works") + assert b"pty-env-works" in output + finally: + bridge.close() + + +class TestPtyBridgeUnavailable: + """Platform fallback semantics — PtyUnavailableError is importable and + carries a user-readable message.""" + + def test_error_carries_user_message(self): + err = PtyUnavailableError("platform not supported") + assert "platform" in str(err) diff --git a/tests/hermes_cli/test_web_server.py b/tests/hermes_cli/test_web_server.py index a92f0c8d1..8ff9285e4 100644 --- a/tests/hermes_cli/test_web_server.py +++ b/tests/hermes_cli/test_web_server.py @@ -1677,3 +1677,241 @@ class TestDashboardPluginManifestExtensions: plugins = web_server._get_dashboard_plugins(force_rescan=True) entry = next(p for p in plugins if p["name"] == "mixed-slots") assert entry["slots"] == ["sidebar", "header-right"] + + +# --------------------------------------------------------------------------- +# /api/pty WebSocket — terminal bridge for the dashboard "Chat" tab. +# +# These tests drive the endpoint with a tiny fake command (typically ``cat`` +# or ``sh -c 'printf …'``) instead of the real ``hermes --tui`` binary. The +# endpoint resolves its argv through ``_resolve_chat_argv``, so tests +# monkeypatch that hook. +# --------------------------------------------------------------------------- + +import sys + + +skip_on_windows = pytest.mark.skipif( + sys.platform.startswith("win"), reason="PTY bridge is POSIX-only" +) + + +@skip_on_windows +class TestPtyWebSocket: + @pytest.fixture(autouse=True) + def _setup(self, monkeypatch, _isolate_hermes_home): + from starlette.testclient import TestClient + + import hermes_cli.web_server as ws + + # Avoid exec'ing the actual TUI in tests: every test below installs + # its own fake argv via ``ws._resolve_chat_argv``. + self.ws_module = ws + self.token = ws._SESSION_TOKEN + self.client = TestClient(ws.app) + + def _url(self, token: str | None = None, **params: str) -> str: + tok = token if token is not None else self.token + # TestClient.websocket_connect takes the path; it reconstructs the + # query string, so we pass it inline. + from urllib.parse import urlencode + + q = {"token": tok, **params} + return f"/api/pty?{urlencode(q)}" + + def test_rejects_missing_token(self, monkeypatch): + monkeypatch.setattr( + self.ws_module, + "_resolve_chat_argv", + lambda resume=None, sidecar_url=None: (["/bin/cat"], None, None), + ) + from starlette.websockets import WebSocketDisconnect + + with pytest.raises(WebSocketDisconnect) as exc: + with self.client.websocket_connect("/api/pty"): + pass + assert exc.value.code == 4401 + + def test_rejects_bad_token(self, monkeypatch): + monkeypatch.setattr( + self.ws_module, + "_resolve_chat_argv", + lambda resume=None, sidecar_url=None: (["/bin/cat"], None, None), + ) + from starlette.websockets import WebSocketDisconnect + + with pytest.raises(WebSocketDisconnect) as exc: + with self.client.websocket_connect(self._url(token="wrong")): + pass + assert exc.value.code == 4401 + + def test_streams_child_stdout_to_client(self, monkeypatch): + monkeypatch.setattr( + self.ws_module, + "_resolve_chat_argv", + lambda resume=None, sidecar_url=None: ( + ["/bin/sh", "-c", "printf hermes-ws-ok"], + None, + None, + ), + ) + with self.client.websocket_connect(self._url()) as conn: + # Drain frames until we see the needle or time out. TestClient's + # recv_bytes blocks; loop until we have the signal byte string. + buf = b"" + import time + + deadline = time.monotonic() + 5.0 + while time.monotonic() < deadline: + try: + frame = conn.receive_bytes() + except Exception: + break + if frame: + buf += frame + if b"hermes-ws-ok" in buf: + break + assert b"hermes-ws-ok" in buf + + def test_client_input_reaches_child_stdin(self, monkeypatch): + # ``cat`` echoes stdin back, so a write → read round-trip proves + # the full duplex path. + monkeypatch.setattr( + self.ws_module, + "_resolve_chat_argv", + lambda resume=None, sidecar_url=None: (["/bin/cat"], None, None), + ) + with self.client.websocket_connect(self._url()) as conn: + conn.send_bytes(b"round-trip-payload\n") + buf = b"" + import time + + deadline = time.monotonic() + 5.0 + while time.monotonic() < deadline: + frame = conn.receive_bytes() + if frame: + buf += frame + if b"round-trip-payload" in buf: + break + assert b"round-trip-payload" in buf + + def test_resize_escape_is_forwarded(self, monkeypatch): + # Resize escape gets intercepted and applied via TIOCSWINSZ, + # then ``tput cols/lines`` reports the new dimensions back. + monkeypatch.setattr( + self.ws_module, + "_resolve_chat_argv", + # sleep gives the test time to push the resize before tput runs + lambda resume=None, sidecar_url=None: ( + ["/bin/sh", "-c", "sleep 0.15; tput cols; tput lines"], + None, + None, + ), + ) + with self.client.websocket_connect(self._url()) as conn: + conn.send_text("\x1b[RESIZE:99;41]") + buf = b"" + import time + + deadline = time.monotonic() + 5.0 + while time.monotonic() < deadline: + frame = conn.receive_bytes() + if frame: + buf += frame + if b"99" in buf and b"41" in buf: + break + assert b"99" in buf and b"41" in buf + + def test_unavailable_platform_closes_with_message(self, monkeypatch): + from hermes_cli.pty_bridge import PtyUnavailableError + + def _raise(argv, **kwargs): + raise PtyUnavailableError("pty missing for tests") + + monkeypatch.setattr( + self.ws_module, + "_resolve_chat_argv", + lambda resume=None, sidecar_url=None: (["/bin/cat"], None, None), + ) + # Patch PtyBridge.spawn at the web_server module's binding. + import hermes_cli.web_server as ws_mod + + monkeypatch.setattr(ws_mod.PtyBridge, "spawn", classmethod(lambda cls, *a, **k: _raise(*a, **k))) + + with self.client.websocket_connect(self._url()) as conn: + # Expect a final text frame with the error message, then close. + msg = conn.receive_text() + assert "pty missing" in msg or "unavailable" in msg.lower() or "pty" in msg.lower() + + def test_resume_parameter_is_forwarded_to_argv(self, monkeypatch): + captured: dict = {} + + def fake_resolve(resume=None, sidecar_url=None): + captured["resume"] = resume + return (["/bin/sh", "-c", "printf resume-arg-ok"], None, None) + + monkeypatch.setattr(self.ws_module, "_resolve_chat_argv", fake_resolve) + + with self.client.websocket_connect(self._url(resume="sess-42")) as conn: + # Drain briefly so the handler actually invokes the resolver. + try: + conn.receive_bytes() + except Exception: + pass + assert captured.get("resume") == "sess-42" + + def test_channel_param_propagates_sidecar_url(self, monkeypatch): + """When /api/pty is opened with ?channel=, the PTY child gets a + HERMES_TUI_SIDECAR_URL env var pointing back at /api/pub on the + same channel — which is how tool events reach the dashboard sidebar.""" + captured: dict = {} + + def fake_resolve(resume=None, sidecar_url=None): + captured["sidecar_url"] = sidecar_url + return (["/bin/sh", "-c", "printf sidecar-ok"], None, None) + + monkeypatch.setattr(self.ws_module, "_resolve_chat_argv", fake_resolve) + monkeypatch.setattr( + self.ws_module.app.state, "bound_host", "127.0.0.1", raising=False + ) + monkeypatch.setattr( + self.ws_module.app.state, "bound_port", 9119, raising=False + ) + + with self.client.websocket_connect(self._url(channel="abc-123")) as conn: + try: + conn.receive_bytes() + except Exception: + pass + + url = captured.get("sidecar_url") or "" + assert url.startswith("ws://127.0.0.1:9119/api/pub?") + assert "channel=abc-123" in url + assert "token=" in url + + def test_pub_broadcasts_to_events_subscribers(self, monkeypatch): + """Frame written to /api/pub is rebroadcast verbatim to every + /api/events subscriber on the same channel.""" + from urllib.parse import urlencode + + qs = urlencode({"token": self.token, "channel": "broadcast-test"}) + pub_path = f"/api/pub?{qs}" + sub_path = f"/api/events?{qs}" + + with self.client.websocket_connect(sub_path) as sub: + with self.client.websocket_connect(pub_path) as pub: + pub.send_text('{"type":"tool.start","payload":{"tool_id":"t1"}}') + received = sub.receive_text() + + assert "tool.start" in received + assert '"tool_id":"t1"' in received + + def test_events_rejects_missing_channel(self): + from starlette.websockets import WebSocketDisconnect + + with pytest.raises(WebSocketDisconnect) as exc: + with self.client.websocket_connect( + f"/api/events?token={self.token}" + ): + pass + assert exc.value.code == 4400 diff --git a/tui_gateway/entry.py b/tui_gateway/entry.py index 7eac6057e..4e03224ee 100644 --- a/tui_gateway/entry.py +++ b/tui_gateway/entry.py @@ -5,7 +5,28 @@ import sys import time import traceback +from tui_gateway import server from tui_gateway.server import _CRASH_LOG, dispatch, resolve_skin, write_json +from tui_gateway.transport import TeeTransport + + +def _install_sidecar_publisher() -> None: + """Mirror every dispatcher emit to the dashboard sidebar via WS. + + Activated by `HERMES_TUI_SIDECAR_URL`, set by the dashboard's + ``/api/pty`` endpoint when a chat tab passes a ``channel`` query param. + Best-effort: connect failure or runtime drop falls back to stdio-only. + """ + url = os.environ.get("HERMES_TUI_SIDECAR_URL") + + if not url: + return + + from tui_gateway.event_publisher import WsPublisherTransport + + server._stdio_transport = TeeTransport( + server._stdio_transport, WsPublisherTransport(url) + ) def _log_signal(signum: int, frame) -> None: @@ -82,6 +103,8 @@ def _log_exit(reason: str) -> None: def main(): + _install_sidecar_publisher() + if not write_json({ "jsonrpc": "2.0", "method": "event", diff --git a/tui_gateway/event_publisher.py b/tui_gateway/event_publisher.py new file mode 100644 index 000000000..5e618bc21 --- /dev/null +++ b/tui_gateway/event_publisher.py @@ -0,0 +1,81 @@ +"""Best-effort WebSocket publisher transport for the PTY-side gateway. + +The dashboard's `/api/pty` spawns `hermes --tui` as a child process, which +spawns its own ``tui_gateway.entry``. Tool/reasoning/status events fire on +*that* gateway's transport — three processes removed from the dashboard +server itself. To surface them in the dashboard sidebar (`/api/events`), +the PTY-side gateway opens a back-WS to the dashboard at startup and +mirrors every emit through this transport. + +Wire protocol: newline-framed JSON dicts (the same shape the dispatcher +already passes to ``write``). No JSON-RPC envelope here — the dashboard's +``/api/pub`` endpoint just rebroadcasts the bytes verbatim to subscribers. + +Failure mode: silent. The agent loop must never block waiting for the +sidecar to drain. A dead WS short-circuits all subsequent writes. +""" + +from __future__ import annotations + +import json +import logging +import threading +from typing import Optional + +try: + from websockets.sync.client import connect as ws_connect +except ImportError: # pragma: no cover - websockets is a required install path + ws_connect = None # type: ignore[assignment] + +_log = logging.getLogger(__name__) + + +class WsPublisherTransport: + __slots__ = ("_url", "_lock", "_ws", "_dead") + + def __init__(self, url: str, *, connect_timeout: float = 2.0) -> None: + self._url = url + self._lock = threading.Lock() + self._ws: Optional[object] = None + self._dead = False + + if ws_connect is None: + self._dead = True + + return + + try: + self._ws = ws_connect(url, open_timeout=connect_timeout, max_size=None) + except Exception as exc: + _log.debug("event publisher connect failed: %s", exc) + self._dead = True + self._ws = None + + def write(self, obj: dict) -> bool: + if self._dead or self._ws is None: + return False + + try: + with self._lock: + self._ws.send(json.dumps(obj, ensure_ascii=False)) # type: ignore[union-attr] + + return True + except Exception as exc: + _log.debug("event publisher write failed: %s", exc) + self._dead = True + self._ws = None + + return False + + def close(self) -> None: + self._dead = True + + if self._ws is None: + return + + try: + self._ws.close() # type: ignore[union-attr] + except Exception: + pass + + self._ws = None diff --git a/tui_gateway/server.py b/tui_gateway/server.py index eea4ebf35..cc2d7b08d 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -1,5 +1,6 @@ import atexit import concurrent.futures +import contextvars import copy import json import logging @@ -12,9 +13,17 @@ import time import uuid from datetime import datetime from pathlib import Path +from typing import Optional from hermes_constants import get_hermes_home from hermes_cli.env_loader import load_hermes_dotenv +from tui_gateway.transport import ( + StdioTransport, + Transport, + bind_transport, + current_transport, + reset_transport, +) logger = logging.getLogger(__name__) @@ -147,6 +156,11 @@ atexit.register(lambda: _pool.shutdown(wait=False, cancel_futures=True)) _real_stdout = sys.stdout sys.stdout = sys.stderr +# Module-level stdio transport — fallback sink when no transport is bound via +# contextvar or session. Stream resolved through a lambda so runtime monkey- +# patches of `_real_stdout` (used extensively in tests) still land correctly. +_stdio_transport = StdioTransport(lambda: _real_stdout, _stdout_lock) + class _SlashWorker: """Persistent HermesCLI subprocess for slash commands.""" @@ -266,14 +280,24 @@ def _db_unavailable_error(rid, *, code: int): def write_json(obj: dict) -> bool: - line = json.dumps(obj, ensure_ascii=False) + "\n" - try: - with _stdout_lock: - _real_stdout.write(line) - _real_stdout.flush() - return True - except BrokenPipeError: - return False + """Emit one JSON frame. Routes via the most-specific transport available. + + Precedence: + + 1. Event frames with a session id → the transport stored on that session, + so async events land with the client that owns the session even if + the emitting thread has no contextvar binding. + 2. Otherwise the transport bound on the current context (set by + :func:`dispatch` for the lifetime of a request). + 3. Otherwise the module-level stdio transport, matching the historical + behaviour and keeping tests that monkey-patch ``_real_stdout`` green. + """ + if obj.get("method") == "event": + sid = ((obj.get("params") or {}).get("session_id")) or "" + if sid and (t := (_sessions.get(sid) or {}).get("transport")) is not None: + return t.write(obj) + + return (current_transport() or _stdio_transport).write(obj) def _emit(event: str, sid: str, payload: dict | None = None): @@ -343,27 +367,40 @@ def handle_request(req: dict) -> dict | None: return fn(req.get("id"), req.get("params", {})) -def dispatch(req: dict) -> dict | None: +def dispatch(req: dict, transport: Optional[Transport] = None) -> dict | None: """Route inbound RPCs — long handlers to the pool, everything else inline. Returns a response dict when handled inline. Returns None when the - handler was scheduled on the pool; the worker writes its own - response via write_json when done. + handler was scheduled on the pool; the worker writes its own response + via the bound transport when done. + + *transport* (optional): pins every write produced by this request — + including any events emitted by the handler — to the given transport. + Omitting it falls back to the module-level stdio transport, preserving + the original behaviour for ``tui_gateway.entry``. """ - if req.get("method") not in _LONG_HANDLERS: - return handle_request(req) + t = transport or _stdio_transport + token = bind_transport(t) + try: + if req.get("method") not in _LONG_HANDLERS: + return handle_request(req) - def run(): - try: - resp = handle_request(req) - except Exception as exc: - resp = _err(req.get("id"), -32000, f"handler error: {exc}") - if resp is not None: - write_json(resp) + # Snapshot the context so the pool worker sees the bound transport. + ctx = contextvars.copy_context() - _pool.submit(run) + def run(): + try: + resp = handle_request(req) + except Exception as exc: + resp = _err(req.get("id"), -32000, f"handler error: {exc}") + if resp is not None: + t.write(resp) - return None + _pool.submit(lambda: ctx.run(run)) + + return None + finally: + reset_transport(token) def _wait_agent(session: dict, rid: str, timeout: float = 30.0) -> dict | None: @@ -1262,6 +1299,9 @@ def _init_session(sid: str, key: str, agent, history: list, cols: int = 80): "tool_progress_mode": _load_tool_progress_mode(), "edit_snapshots": {}, "tool_started_at": {}, + # Pin async event emissions to whichever transport created the + # session (stdio for Ink, JSON-RPC WS for the dashboard sidebar). + "transport": current_transport() or _stdio_transport, } try: _sessions[sid]["slash_worker"] = _SlashWorker( @@ -1404,6 +1444,7 @@ def _(rid, params: dict) -> dict: "slash_worker": None, "tool_progress_mode": _load_tool_progress_mode(), "tool_started_at": {}, + "transport": current_transport() or _stdio_transport, } def _build() -> None: diff --git a/tui_gateway/transport.py b/tui_gateway/transport.py new file mode 100644 index 000000000..f9c71f961 --- /dev/null +++ b/tui_gateway/transport.py @@ -0,0 +1,125 @@ +"""Transport abstraction for the tui_gateway JSON-RPC server. + +Historically the gateway wrote every JSON frame directly to real stdout. This +module decouples the I/O sink from the handler logic so the same dispatcher +can be driven over stdio (``tui_gateway.entry``) or WebSocket +(``tui_gateway.ws``) without duplicating code. + +A :class:`Transport` is anything that can accept a JSON-serialisable dict and +forward it to its peer. The active transport for the current request is +tracked in a :class:`contextvars.ContextVar` so handlers — including those +dispatched onto the worker pool — route their writes to the right peer. + +Backward compatibility +---------------------- +``tui_gateway.server.write_json`` still works without any transport bound. +When nothing is on the contextvar and no session-level transport is found, +it falls back to the module-level :class:`StdioTransport`, which wraps the +original ``_real_stdout`` + ``_stdout_lock`` pair. Tests that monkey-patch +``server._real_stdout`` continue to work because the stdio transport resolves +the stream lazily through a callback. +""" + +from __future__ import annotations + +import contextvars +import json +import threading +from typing import Any, Callable, Optional, Protocol, runtime_checkable + + +@runtime_checkable +class Transport(Protocol): + """Minimal interface every transport implements.""" + + def write(self, obj: dict) -> bool: + """Emit one JSON frame. Return ``False`` when the peer is gone.""" + + def close(self) -> None: + """Release any resources owned by this transport.""" + + +_current_transport: contextvars.ContextVar[Optional[Transport]] = ( + contextvars.ContextVar( + "hermes_gateway_transport", + default=None, + ) +) + + +def current_transport() -> Optional[Transport]: + """Return the transport bound for the current request, if any.""" + return _current_transport.get() + + +def bind_transport(transport: Optional[Transport]): + """Bind *transport* for the current context. Returns a token for :func:`reset_transport`.""" + return _current_transport.set(transport) + + +def reset_transport(token) -> None: + """Restore the transport binding captured by :func:`bind_transport`.""" + _current_transport.reset(token) + + +class StdioTransport: + """Writes JSON frames to a stream (usually ``sys.stdout``). + + The stream is resolved via a callable so runtime monkey-patches of the + underlying stream continue to work — this preserves the behaviour the + existing test suite relies on (``monkeypatch.setattr(server, "_real_stdout", ...)``). + """ + + __slots__ = ("_stream_getter", "_lock") + + def __init__(self, stream_getter: Callable[[], Any], lock: threading.Lock) -> None: + self._stream_getter = stream_getter + self._lock = lock + + def write(self, obj: dict) -> bool: + line = json.dumps(obj, ensure_ascii=False) + "\n" + try: + with self._lock: + stream = self._stream_getter() + stream.write(line) + stream.flush() + return True + except BrokenPipeError: + return False + + def close(self) -> None: + return None + + +class TeeTransport: + """Mirrors writes to one primary plus N best-effort secondaries. + + The primary's return value (and exceptions) determine the result — + secondaries swallow failures so a wedged sidecar never stalls the + main IO path. Used by the PTY child so every dispatcher emit lands + on stdio (Ink) AND on a back-WS feeding the dashboard sidebar. + """ + + __slots__ = ("_primary", "_secondaries") + + def __init__(self, primary: "Transport", *secondaries: "Transport") -> None: + self._primary = primary + self._secondaries = secondaries + + def write(self, obj: dict) -> bool: + for sec in self._secondaries: + try: + sec.write(obj) + except Exception: + pass + return self._primary.write(obj) + + def close(self) -> None: + try: + self._primary.close() + finally: + for sec in self._secondaries: + try: + sec.close() + except Exception: + pass diff --git a/tui_gateway/ws.py b/tui_gateway/ws.py new file mode 100644 index 000000000..1661811db --- /dev/null +++ b/tui_gateway/ws.py @@ -0,0 +1,174 @@ +"""WebSocket transport for the tui_gateway JSON-RPC server. + +Reuses :func:`tui_gateway.server.dispatch` verbatim so every RPC method, every +slash command, every approval/clarify/sudo flow, and every agent event flows +through the same handlers whether the client is Ink over stdio or an iOS / +web client over WebSocket. + +Wire protocol +------------- +Identical to stdio: newline-delimited JSON-RPC in both directions. The server +emits a ``gateway.ready`` event immediately after connection accept, then +echoes responses/events for inbound requests. No framing differences. + +Mounting +-------- + from fastapi import WebSocket + from tui_gateway.ws import handle_ws + + @app.websocket("/api/ws") + async def ws(ws: WebSocket): + await handle_ws(ws) +""" + +from __future__ import annotations + +import asyncio +import json +import logging +from typing import Any + +from tui_gateway import server + +_log = logging.getLogger(__name__) + +# Max seconds a pool-dispatched handler will block waiting for the event loop +# to flush a WS frame before we mark the transport dead. Protects handler +# threads from a wedged socket. +_WS_WRITE_TIMEOUT_S = 10.0 + +# Keep starlette optional at import time; handle_ws uses the real class when +# it's available and falls back to a generic Exception sentinel otherwise. +try: + from starlette.websockets import WebSocketDisconnect as _WebSocketDisconnect +except ImportError: # pragma: no cover - starlette is a required install path + _WebSocketDisconnect = Exception # type: ignore[assignment] + + +class WSTransport: + """Per-connection WS transport. + + ``write`` is safe to call from any thread *other than* the event loop + thread that owns the socket. Pool workers (the only real caller) run in + their own threads, so marshalling onto the loop via + :func:`asyncio.run_coroutine_threadsafe` + ``future.result()`` is correct + and deadlock-free there. + + When called from the loop thread itself (e.g. by ``handle_ws`` for an + inline response) the same call would deadlock: we'd schedule work onto + the loop we're currently blocking. We detect that case and fire-and- + forget instead. Callers that need to know when the bytes are on the wire + should use :meth:`write_async` from the loop thread. + """ + + def __init__(self, ws: Any, loop: asyncio.AbstractEventLoop) -> None: + self._ws = ws + self._loop = loop + self._closed = False + + def write(self, obj: dict) -> bool: + if self._closed: + return False + + line = json.dumps(obj, ensure_ascii=False) + + try: + on_loop = asyncio.get_running_loop() is self._loop + except RuntimeError: + on_loop = False + + if on_loop: + # Fire-and-forget — don't block the loop waiting on itself. + self._loop.create_task(self._safe_send(line)) + return True + + try: + fut = asyncio.run_coroutine_threadsafe(self._safe_send(line), self._loop) + fut.result(timeout=_WS_WRITE_TIMEOUT_S) + return not self._closed + except Exception as exc: + self._closed = True + _log.debug("ws write failed: %s", exc) + return False + + async def write_async(self, obj: dict) -> bool: + """Send from the owning event loop. Awaits until the frame is on the wire.""" + if self._closed: + return False + await self._safe_send(json.dumps(obj, ensure_ascii=False)) + return not self._closed + + async def _safe_send(self, line: str) -> None: + try: + await self._ws.send_text(line) + except Exception as exc: + self._closed = True + _log.debug("ws send failed: %s", exc) + + def close(self) -> None: + self._closed = True + + +async def handle_ws(ws: Any) -> None: + """Run one WebSocket session. Wire-compatible with ``tui_gateway.entry``.""" + await ws.accept() + + transport = WSTransport(ws, asyncio.get_running_loop()) + + await transport.write_async( + { + "jsonrpc": "2.0", + "method": "event", + "params": { + "type": "gateway.ready", + "payload": {"skin": server.resolve_skin()}, + }, + } + ) + + try: + while True: + try: + raw = await ws.receive_text() + except _WebSocketDisconnect: + break + + line = raw.strip() + if not line: + continue + + try: + req = json.loads(line) + except json.JSONDecodeError: + ok = await transport.write_async( + { + "jsonrpc": "2.0", + "error": {"code": -32700, "message": "parse error"}, + "id": None, + } + ) + if not ok: + break + continue + + # dispatch() may schedule long handlers on the pool; it returns + # None in that case and the worker writes the response itself via + # the transport we pass in (a separate thread, so transport.write + # is the safe path there). For inline handlers it returns the + # response dict, which we write here from the loop. + resp = await asyncio.to_thread(server.dispatch, req, transport) + if resp is not None and not await transport.write_async(resp): + break + finally: + transport.close() + + # Detach the transport from any sessions it owned so later emits + # fall back to stdio instead of crashing into a closed socket. + for _, sess in list(server._sessions.items()): + if sess.get("transport") is transport: + sess["transport"] = server._stdio_transport + + try: + await ws.close() + except Exception: + pass diff --git a/ui-tui/src/app/slash/commands/core.ts b/ui-tui/src/app/slash/commands/core.ts index efea1c112..870e2000c 100644 --- a/ui-tui/src/app/slash/commands/core.ts +++ b/ui-tui/src/app/slash/commands/core.ts @@ -246,7 +246,7 @@ export const coreCommands: SlashCommand[] = [ } writeOsc52Clipboard(target.text) - sys('sent OSC52 copy sequence (terminal support required)') + sys(`copied ${target.text.length} chars`) } }, diff --git a/web/package-lock.json b/web/package-lock.json index bc806a371..436b17bb7 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -12,6 +12,11 @@ "@observablehq/plot": "^0.6.17", "@react-three/fiber": "^9.6.0", "@tailwindcss/vite": "^4.2.1", + "@xterm/addon-fit": "^0.11.0", + "@xterm/addon-unicode11": "^0.9.0", + "@xterm/addon-web-links": "^0.12.0", + "@xterm/addon-webgl": "^0.19.0", + "@xterm/xterm": "^6.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "gsap": "^3.15.0", @@ -213,23 +218,23 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", - "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, "license": "MIT", "dependencies": { @@ -332,9 +337,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", - "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], @@ -348,9 +353,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", - "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -364,9 +369,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", - "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], @@ -380,9 +385,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", - "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], @@ -396,9 +401,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", - "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], @@ -412,9 +417,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", - "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], @@ -428,9 +433,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", - "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], @@ -444,9 +449,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", - "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], @@ -460,9 +465,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", - "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], @@ -476,9 +481,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", - "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -492,9 +497,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", - "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], @@ -508,9 +513,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", - "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -524,9 +529,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", - "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], @@ -540,9 +545,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", - "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], @@ -556,9 +561,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", - "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], @@ -572,9 +577,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", - "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -588,9 +593,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", - "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "cpu": [ "x64" ], @@ -604,9 +609,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", - "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "cpu": [ "arm64" ], @@ -620,9 +625,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", - "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], @@ -636,9 +641,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", - "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "cpu": [ "arm64" ], @@ -652,9 +657,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", - "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], @@ -668,9 +673,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", - "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "cpu": [ "arm64" ], @@ -684,9 +689,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", - "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], @@ -700,9 +705,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", - "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], @@ -716,9 +721,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", - "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], @@ -732,9 +737,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", - "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], @@ -943,29 +948,43 @@ "license": "MIT" }, "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.1", + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1801,35 +1820,6 @@ } } }, - "node_modules/@react-three/fiber/node_modules/zustand": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", - "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.3", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", @@ -1838,9 +1828,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", "cpu": [ "arm" ], @@ -1851,9 +1841,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", "cpu": [ "arm64" ], @@ -1864,9 +1854,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", "cpu": [ "arm64" ], @@ -1877,9 +1867,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", "cpu": [ "x64" ], @@ -1890,9 +1880,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", "cpu": [ "arm64" ], @@ -1903,9 +1893,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", "cpu": [ "x64" ], @@ -1916,9 +1906,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", "cpu": [ "arm" ], @@ -1929,9 +1919,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", "cpu": [ "arm" ], @@ -1942,9 +1932,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", "cpu": [ "arm64" ], @@ -1955,9 +1945,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", "cpu": [ "arm64" ], @@ -1968,9 +1958,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", "cpu": [ "loong64" ], @@ -1981,9 +1971,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", "cpu": [ "loong64" ], @@ -1994,9 +1984,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", "cpu": [ "ppc64" ], @@ -2007,9 +1997,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", "cpu": [ "ppc64" ], @@ -2020,9 +2010,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", "cpu": [ "riscv64" ], @@ -2033,9 +2023,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", "cpu": [ "riscv64" ], @@ -2046,9 +2036,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", "cpu": [ "s390x" ], @@ -2059,9 +2049,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", "cpu": [ "x64" ], @@ -2072,9 +2062,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", "cpu": [ "x64" ], @@ -2085,9 +2075,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", "cpu": [ "x64" ], @@ -2098,9 +2088,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", "cpu": [ "arm64" ], @@ -2111,9 +2101,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", "cpu": [ "arm64" ], @@ -2124,9 +2114,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", "cpu": [ "ia32" ], @@ -2137,9 +2127,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", "cpu": [ "x64" ], @@ -2150,9 +2140,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", "cpu": [ "x64" ], @@ -2172,47 +2162,47 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz", + "integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.31.1", + "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" + "tailwindcss": "4.2.4" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz", + "integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==", "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + "@tailwindcss/oxide-android-arm64": "4.2.4", + "@tailwindcss/oxide-darwin-arm64": "4.2.4", + "@tailwindcss/oxide-darwin-x64": "4.2.4", + "@tailwindcss/oxide-freebsd-x64": "4.2.4", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.4", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.4", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.4", + "@tailwindcss/oxide-linux-x64-musl": "4.2.4", + "@tailwindcss/oxide-wasm32-wasi": "4.2.4", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.4", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.4" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz", + "integrity": "sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==", "cpu": [ "arm64" ], @@ -2226,9 +2216,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz", + "integrity": "sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==", "cpu": [ "arm64" ], @@ -2242,9 +2232,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.4.tgz", + "integrity": "sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==", "cpu": [ "x64" ], @@ -2258,9 +2248,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.4.tgz", + "integrity": "sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==", "cpu": [ "x64" ], @@ -2274,9 +2264,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.4.tgz", + "integrity": "sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==", "cpu": [ "arm" ], @@ -2290,9 +2280,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.4.tgz", + "integrity": "sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==", "cpu": [ "arm64" ], @@ -2306,9 +2296,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.4.tgz", + "integrity": "sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==", "cpu": [ "arm64" ], @@ -2322,9 +2312,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.4.tgz", + "integrity": "sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==", "cpu": [ "x64" ], @@ -2338,9 +2328,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.4.tgz", + "integrity": "sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==", "cpu": [ "x64" ], @@ -2354,9 +2344,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.4.tgz", + "integrity": "sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -2383,9 +2373,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.4.tgz", + "integrity": "sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==", "cpu": [ "arm64" ], @@ -2399,9 +2389,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.4.tgz", + "integrity": "sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==", "cpu": [ "x64" ], @@ -2415,17 +2405,17 @@ } }, "node_modules/@tailwindcss/vite": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.4.tgz", + "integrity": "sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==", "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "tailwindcss": "4.2.1" + "@tailwindcss/node": "4.2.4", + "@tailwindcss/oxide": "4.2.4", + "tailwindcss": "4.2.4" }, "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "node_modules/@types/babel__core": { @@ -2487,9 +2477,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.0.tgz", - "integrity": "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==", + "version": "24.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", + "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==", "devOptional": true, "license": "MIT", "peer": true, @@ -2534,20 +2524,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz", - "integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.0.tgz", + "integrity": "sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/type-utils": "8.57.0", - "@typescript-eslint/utils": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", + "@typescript-eslint/scope-manager": "8.59.0", + "@typescript-eslint/type-utils": "8.59.0", + "@typescript-eslint/utils": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2557,9 +2547,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.0", + "@typescript-eslint/parser": "^8.59.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -2573,17 +2563,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz", - "integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.0.tgz", + "integrity": "sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", + "@typescript-eslint/scope-manager": "8.59.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0", "debug": "^4.4.3" }, "engines": { @@ -2595,18 +2585,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz", - "integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.0.tgz", + "integrity": "sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.0", - "@typescript-eslint/types": "^8.57.0", + "@typescript-eslint/tsconfig-utils": "^8.59.0", + "@typescript-eslint/types": "^8.59.0", "debug": "^4.4.3" }, "engines": { @@ -2617,18 +2607,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz", - "integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.0.tgz", + "integrity": "sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0" + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2639,9 +2629,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz", - "integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.0.tgz", + "integrity": "sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==", "dev": true, "license": "MIT", "engines": { @@ -2652,21 +2642,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz", - "integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.0.tgz", + "integrity": "sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/utils": "8.57.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0", + "@typescript-eslint/utils": "8.59.0", "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2677,13 +2667,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz", - "integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.0.tgz", + "integrity": "sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==", "dev": true, "license": "MIT", "engines": { @@ -2695,21 +2685,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz", - "integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.0.tgz", + "integrity": "sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.0", - "@typescript-eslint/tsconfig-utils": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/visitor-keys": "8.57.0", + "@typescript-eslint/project-service": "8.59.0", + "@typescript-eslint/tsconfig-utils": "8.59.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/visitor-keys": "8.59.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2719,7 +2709,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { @@ -2733,9 +2723,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2746,13 +2736,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -2775,16 +2765,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz", - "integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.0.tgz", + "integrity": "sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.0", - "@typescript-eslint/types": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0" + "@typescript-eslint/scope-manager": "8.59.0", + "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2795,17 +2785,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz", - "integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.0.tgz", + "integrity": "sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.0", + "@typescript-eslint/types": "8.59.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2868,6 +2858,39 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/@xterm/addon-fit": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.11.0.tgz", + "integrity": "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g==", + "license": "MIT" + }, + "node_modules/@xterm/addon-unicode11": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0.tgz", + "integrity": "sha512-FxDnYcyuXhNl+XSqGZL/t0U9eiNb/q3EWT5rYkQT/zuig8Gz/VagnQANKHdDWFM2lTMk9ly0EFQxxxtZUoRetw==", + "license": "MIT" + }, + "node_modules/@xterm/addon-web-links": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-web-links/-/addon-web-links-0.12.0.tgz", + "integrity": "sha512-4Smom3RPyVp7ZMYOYDoC/9eGJJJqYhnPLGGqJ6wOBfB8VxPViJNSKdgRYb8NpaM6YSelEKbA2SStD7lGyqaobw==", + "license": "MIT" + }, + "node_modules/@xterm/addon-webgl": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0.tgz", + "integrity": "sha512-b3fMOsyLVuCeNJWxolACEUED0vm7qC0cy4wRvf3oURSzDTYVQiGPhTnhWZwIHdvC48Y+oLhvYXnY4XDXPoJo6A==", + "license": "MIT" + }, + "node_modules/@xterm/xterm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-6.0.0.tgz", + "integrity": "sha512-TQwDdQGtwwDt+2cgKDLn0IRaSxYu1tSUjgKarSDkUM0ZNiSRXFpjxEsvc/Zgc5kq5omJ+V0a8/kIM2WD3sMOYg==", + "license": "MIT", + "workspaces": [ + "addons/*" + ] + }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -2893,9 +2916,9 @@ } }, "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -2978,9 +3001,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.10.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.7.tgz", - "integrity": "sha512-1ghYO3HnxGec0TCGBXiDLVns4eCSx4zJpxnHrlqFQajmhfKMQBzUGDdkMK7fUW7PTHTeLf+j87aTuKuuwWzMGw==", + "version": "2.10.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.21.tgz", + "integrity": "sha512-Q+rUQ7Uz8AHM7DEaNdwvfFCTq7a43lNTzuS94eiWqwyxfV/wJv+oUivef51T91mmRY4d4A1u9rcSvkeufCVXlA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2997,9 +3020,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -3008,9 +3031,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -3029,11 +3052,11 @@ "license": "MIT", "peer": true, "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -3077,9 +3100,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001778", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001778.tgz", - "integrity": "sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==", + "version": "1.0.30001790", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001790.tgz", + "integrity": "sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==", "dev": true, "funding": [ { @@ -3749,20 +3772,20 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.313", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz", - "integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==", + "version": "1.5.344", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.344.tgz", + "integrity": "sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==", "dev": true, "license": "ISC" }, "node_modules/enhanced-resolve": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", - "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz", + "integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" + "tapable": "^2.3.3" }, "engines": { "node": ">=10.13.0" @@ -3781,9 +3804,9 @@ } }, "node_modules/esbuild": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", - "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -3793,32 +3816,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.4", - "@esbuild/android-arm": "0.27.4", - "@esbuild/android-arm64": "0.27.4", - "@esbuild/android-x64": "0.27.4", - "@esbuild/darwin-arm64": "0.27.4", - "@esbuild/darwin-x64": "0.27.4", - "@esbuild/freebsd-arm64": "0.27.4", - "@esbuild/freebsd-x64": "0.27.4", - "@esbuild/linux-arm": "0.27.4", - "@esbuild/linux-arm64": "0.27.4", - "@esbuild/linux-ia32": "0.27.4", - "@esbuild/linux-loong64": "0.27.4", - "@esbuild/linux-mips64el": "0.27.4", - "@esbuild/linux-ppc64": "0.27.4", - "@esbuild/linux-riscv64": "0.27.4", - "@esbuild/linux-s390x": "0.27.4", - "@esbuild/linux-x64": "0.27.4", - "@esbuild/netbsd-arm64": "0.27.4", - "@esbuild/netbsd-x64": "0.27.4", - "@esbuild/openbsd-arm64": "0.27.4", - "@esbuild/openbsd-x64": "0.27.4", - "@esbuild/openharmony-arm64": "0.27.4", - "@esbuild/sunos-x64": "0.27.4", - "@esbuild/win32-arm64": "0.27.4", - "@esbuild/win32-ia32": "0.27.4", - "@esbuild/win32-x64": "0.27.4" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" } }, "node_modules/escalade": { @@ -3905,9 +3928,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", - "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", "dev": true, "license": "MIT", "dependencies": { @@ -3921,7 +3944,7 @@ "node": ">=18" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" } }, "node_modules/eslint-plugin-react-refresh": { @@ -4144,9 +4167,9 @@ } }, "node_modules/flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -4206,9 +4229,9 @@ } }, "node_modules/globals": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", - "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", + "version": "17.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.5.0.tgz", + "integrity": "sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==", "dev": true, "license": "MIT", "engines": { @@ -4376,18 +4399,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-extendable/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4412,10 +4423,13 @@ } }, "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, "engines": { "node": ">=0.10.0" } @@ -4563,6 +4577,23 @@ "react-dom": "^18.0.0 || ^19.0.0" } }, + "node_modules/leva/node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4578,9 +4609,9 @@ } }, "node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -4593,23 +4624,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, - "node_modules/lightningcss/node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], @@ -4626,10 +4657,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -4646,10 +4677,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], @@ -4666,10 +4697,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], @@ -4686,10 +4717,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], @@ -4706,10 +4737,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], @@ -4726,10 +4757,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], @@ -4746,10 +4777,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", "cpu": [ "x64" ], @@ -4766,10 +4797,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], @@ -4786,10 +4817,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], @@ -4806,10 +4837,10 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], @@ -4979,9 +5010,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.36", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", - "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", "dev": true, "license": "MIT" }, @@ -5090,9 +5121,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "peer": true, "engines": { @@ -5103,9 +5134,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "funding": [ { "type": "opencollective", @@ -5162,9 +5193,9 @@ } }, "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", "license": "MIT", "peer": true, "engines": { @@ -5182,16 +5213,16 @@ } }, "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", + "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", "license": "MIT", "peer": true, "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.4" + "react": "^19.2.5" } }, "node_modules/react-dropzone": { @@ -5228,9 +5259,9 @@ } }, "node_modules/react-router": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.1.tgz", - "integrity": "sha512-5BCvFskyAAVumqhEKh/iPhLOIkfxcEUz8WqFIARCkMg8hZZzDYX9CtwxXA0e+qT8zAxmMC0x3Ckb9iMONwc5jg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.2.tgz", + "integrity": "sha512-yCqNne6I8IB6rVCH7XUvlBK7/QKyqypBFGv+8dj4QBFJiiRX+FG7/nkdAvGElyvVZ/HQP5N19wzteuTARXi5Gw==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -5250,12 +5281,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.1.tgz", - "integrity": "sha512-ZkrQuwwhGibjQLqH1eCdyiZyLWglPxzxdl5tgwgKEyCSGC76vmAjleGocRe3J/MLfzMUIKwaFJWpFVJhK3d2xA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.2.tgz", + "integrity": "sha512-YZcM5ES8jJSM+KrJ9BdvHHqlnGTg5tH3sC5ChFRj4inosKctdyzBDhOyyHdGk597q2OT6NTrCA1OvB/YDwfekQ==", "license": "MIT", "dependencies": { - "react-router": "7.14.1" + "react-router": "7.14.2" }, "engines": { "node": ">=20.0.0" @@ -5297,9 +5328,9 @@ "license": "Unlicense" }, "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -5312,31 +5343,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", "fsevents": "~2.3.2" } }, @@ -5366,6 +5397,15 @@ "postcss": "^8.3.11" } }, + "node_modules/sanitize-html/node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -5412,18 +5452,6 @@ "node": ">=0.10.0" } }, - "node_modules/set-value/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -5527,15 +5555,15 @@ } }, "node_modules/tailwindcss": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", - "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz", + "integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==", "license": "MIT" }, "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "license": "MIT", "engines": { "node": ">=6" @@ -5553,13 +5581,13 @@ "peer": true }, "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -5569,9 +5597,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -5625,16 +5653,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.0.tgz", - "integrity": "sha512-W8GcigEMEeB07xEZol8oJ26rigm3+bfPHxHvwbYUlu1fUDsGuQ7Hiskx5xGW/xM4USc9Ephe3jtv7ZYPQntHeA==", + "version": "8.59.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.0.tgz", + "integrity": "sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.57.0", - "@typescript-eslint/parser": "8.57.0", - "@typescript-eslint/typescript-estree": "8.57.0", - "@typescript-eslint/utils": "8.57.0" + "@typescript-eslint/eslint-plugin": "8.59.0", + "@typescript-eslint/parser": "8.59.0", + "@typescript-eslint/typescript-estree": "8.59.0", + "@typescript-eslint/utils": "8.59.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5645,7 +5673,7 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/undici-types": { @@ -5713,9 +5741,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", - "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "license": "MIT", "peer": true, "dependencies": { @@ -5858,19 +5886,31 @@ } }, "node_modules/zustand": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", - "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", + "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", "license": "MIT", "engines": { - "node": ">=12.7.0" + "node": ">=12.20.0" }, "peerDependencies": { - "react": ">=16.8" + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, "react": { "optional": true + }, + "use-sync-external-store": { + "optional": true } } } diff --git a/web/package.json b/web/package.json index 5ca2288ef..8dfac7866 100644 --- a/web/package.json +++ b/web/package.json @@ -17,6 +17,11 @@ "@observablehq/plot": "^0.6.17", "@react-three/fiber": "^9.6.0", "@tailwindcss/vite": "^4.2.1", + "@xterm/addon-fit": "^0.11.0", + "@xterm/addon-unicode11": "^0.9.0", + "@xterm/addon-web-links": "^0.12.0", + "@xterm/addon-webgl": "^0.19.0", + "@xterm/xterm": "^6.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "gsap": "^3.15.0", diff --git a/web/public/fonts-terminal/JetBrainsMono-Bold.woff2 b/web/public/fonts-terminal/JetBrainsMono-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..81c5a219dca74dfdc032d91bfd8328aa0350db2f GIT binary patch literal 94628 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%0DH|mQfl+0iMe@A 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%0Anu8 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 z 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

P>xbtSQ;#ONFb3&n~Y5f01Pu?0WQGI?Mhm% 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 = { "/": RootRedirect, + "/chat": ChatPage, "/sessions": SessionsPage, "/analytics": AnalyticsPage, "/logs": LogsPage, @@ -83,6 +85,7 @@ const BUILTIN_ROUTES: Record = { }; const BUILTIN_NAV: NavItem[] = [ + { path: "/chat", labelKey: "chat", label: "Chat", icon: Terminal }, { path: "/sessions", labelKey: "sessions", diff --git a/web/src/components/ChatSidebar.tsx b/web/src/components/ChatSidebar.tsx new file mode 100644 index 000000000..924edc0e2 --- /dev/null +++ b/web/src/components/ChatSidebar.tsx @@ -0,0 +1,360 @@ +/** + * ChatSidebar — structured-events panel that sits next to the xterm.js + * terminal in the dashboard Chat tab. + * + * Two WebSockets, one per concern: + * + * 1. **JSON-RPC sidecar** (`GatewayClient` → /api/ws) — drives the + * sidebar's own slot of the dashboard's in-process gateway. Owns + * the model badge / picker / connection state / error banner. + * Independent of the PTY pane's session by design — those are the + * pieces the sidebar needs to be able to drive directly (model + * switch via slash.exec, etc.). + * + * 2. **Event subscriber** (/api/events?channel=…) — passive, receives + * every dispatcher emit from the PTY-side `tui_gateway.entry` that + * the dashboard fanned out. This is how `tool.start/progress/ + * complete` from the agent loop reach the sidebar even though the + * PTY child runs three processes deep from us. The `channel` id + * ties this listener to the same chat tab's PTY child — see + * `ChatPage.tsx` for where the id is generated. + * + * Best-effort throughout: WS failures show in the badge / banner, the + * terminal pane keeps working unimpaired. + */ + +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; + +import { ModelPickerDialog } from "@/components/ModelPickerDialog"; +import { ToolCall, type ToolEntry } from "@/components/ToolCall"; +import { GatewayClient, type ConnectionState } from "@/lib/gatewayClient"; + +import { AlertCircle, ChevronDown, RefreshCw } from "lucide-react"; +import { useCallback, useEffect, useMemo, useState } from "react"; + +interface SessionInfo { + cwd?: string; + model?: string; + provider?: string; + credential_warning?: string; +} + +interface RpcEnvelope { + method?: string; + params?: { type?: string; payload?: unknown }; +} + +const TOOL_LIMIT = 20; + +const STATE_LABEL: Record = { + idle: "idle", + connecting: "connecting", + open: "live", + closed: "closed", + error: "error", +}; + +const STATE_TONE: Record = { + idle: "bg-muted text-muted-foreground", + connecting: "bg-primary/10 text-primary", + open: "bg-emerald-500/10 text-emerald-500 dark:text-emerald-400", + closed: "bg-muted text-muted-foreground", + error: "bg-destructive/10 text-destructive", +}; + +interface ChatSidebarProps { + channel: string; +} + +export function ChatSidebar({ channel }: ChatSidebarProps) { + // `version` bumps on reconnect; gw is derived so we never call setState + // for it inside an effect (React 19's set-state-in-effect rule). The + // counter is the dependency on purpose — it's not read in the memo body, + // it's the signal that says "rebuild the client". + const [version, setVersion] = useState(0); + // eslint-disable-next-line react-hooks/exhaustive-deps + const gw = useMemo(() => new GatewayClient(), [version]); + + const [state, setState] = useState("idle"); + const [sessionId, setSessionId] = useState(null); + const [info, setInfo] = useState({}); + const [tools, setTools] = useState([]); + const [modelOpen, setModelOpen] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + const offState = gw.onState(setState); + + const offSessionInfo = gw.on("session.info", (ev) => { + if (ev.session_id) { + setSessionId(ev.session_id); + } + + if (ev.payload) { + setInfo((prev) => ({ ...prev, ...ev.payload })); + } + }); + + const offError = gw.on<{ message?: string }>("error", (ev) => { + const message = ev.payload?.message; + + if (message) { + setError(message); + } + }); + + // Adopt whichever session the gateway hands us. session.create on the + // sidecar is independent of the PTY pane's session by design — we + // only need a sid to drive the model picker's slash.exec calls. + gw.connect() + .then(() => gw.request<{ session_id: string }>("session.create", {})) + .then((created) => { + if (created?.session_id) { + setSessionId(created.session_id); + } + }) + .catch((e: Error) => setError(e.message)); + + return () => { + offState(); + offSessionInfo(); + offError(); + gw.close(); + }; + }, [gw]); + + // Event subscriber WebSocket — receives the rebroadcast of every + // dispatcher emit from the PTY child's gateway. See /api/pub + + // /api/events in hermes_cli/web_server.py for the broadcast hop. + // + // Failures (auth/loopback rejection, server too old to expose the + // endpoint, transient drops) surface in the same banner as the + // JSON-RPC sidecar so the sidebar matches its documented best-effort + // UX and the user always has a reconnect affordance. + useEffect(() => { + const token = window.__HERMES_SESSION_TOKEN__; + + if (!token || !channel) { + return; + } + + const proto = window.location.protocol === "https:" ? "wss:" : "ws:"; + const qs = new URLSearchParams({ token, channel }); + const ws = new WebSocket( + `${proto}//${window.location.host}/api/events?${qs.toString()}`, + ); + + // `unmounting` suppresses the banner during cleanup — `ws.close()` + // from the effect's return fires a close event with code 1005 that + // would otherwise look like an unexpected drop. + const DISCONNECTED = "events feed disconnected — tool calls may not appear"; + let unmounting = false; + const surface = (msg: string) => !unmounting && setError(msg); + + ws.addEventListener("error", () => surface(DISCONNECTED)); + + ws.addEventListener("close", (ev) => { + if (ev.code === 4401 || ev.code === 4403) { + surface(`events feed rejected (${ev.code}) — reload the page`); + } else if (ev.code !== 1000) { + surface(DISCONNECTED); + } + }); + + ws.addEventListener("message", (ev) => { + let frame: RpcEnvelope; + + try { + frame = JSON.parse(ev.data); + } catch { + return; + } + + if (frame.method !== "event" || !frame.params) { + return; + } + + const { type, payload } = frame.params; + + if (type === "tool.start") { + const p = payload as + | { tool_id?: string; name?: string; context?: string } + | undefined; + const toolId = p?.tool_id; + + if (!toolId) { + return; + } + + setTools((prev) => + [ + ...prev, + { + kind: "tool" as const, + id: `tool-${toolId}-${prev.length}`, + tool_id: toolId, + name: p?.name ?? "tool", + context: p?.context, + status: "running" as const, + startedAt: Date.now(), + }, + ].slice(-TOOL_LIMIT), + ); + } else if (type === "tool.progress") { + const p = payload as + | { name?: string; preview?: string } + | undefined; + + if (!p?.name || !p.preview) { + return; + } + + setTools((prev) => + prev.map((t) => + t.status === "running" && t.name === p.name + ? { ...t, preview: p.preview } + : t, + ), + ); + } else if (type === "tool.complete") { + const p = payload as + | { + tool_id?: string; + summary?: string; + error?: string; + inline_diff?: string; + } + | undefined; + + if (!p?.tool_id) { + return; + } + + setTools((prev) => + prev.map((t) => + t.tool_id === p.tool_id + ? { + ...t, + status: p.error ? "error" : "done", + summary: p.summary, + error: p.error, + inline_diff: p.inline_diff, + completedAt: Date.now(), + } + : t, + ), + ); + } + }); + + return () => { + unmounting = true; + ws.close(); + }; + }, [channel, version]); + + const reconnect = useCallback(() => { + setError(null); + setTools([]); + setVersion((v) => v + 1); + }, []); + + // Picker hands us a fully-formed slash command (e.g. "/model anthropic/..."). + // Fire-and-forget through `slash.exec`; the TUI pane will render the result + // via PTY, so the sidebar doesn't need to surface output of its own. + const onModelSubmit = useCallback( + (slashCommand: string) => { + if (!sessionId) { + return; + } + + void gw.request("slash.exec", { + session_id: sessionId, + command: slashCommand, + }); + setModelOpen(false); + }, + [gw, sessionId], + ); + + const canPickModel = state === "open" && !!sessionId; + const modelLabel = (info.model ?? "—").split("/").slice(-1)[0] ?? "—"; + const banner = error ?? info.credential_warning ?? null; + + return ( +

+ ); +} diff --git a/web/src/components/Markdown.tsx b/web/src/components/Markdown.tsx index b796ff0a7..bef0804e7 100644 --- a/web/src/components/Markdown.tsx +++ b/web/src/components/Markdown.tsx @@ -1,22 +1,50 @@ -import { useMemo } from "react"; +import { useMemo, type ReactNode } from "react"; /** * Lightweight markdown renderer for LLM output. * Handles: code blocks, inline code, bold, italic, headers, links, lists, horizontal rules. * NOT a full CommonMark parser — optimized for typical assistant message patterns. + * + * `streaming` renders a blinking caret at the tail of the last block so it + * appears to hug the final character instead of wrapping onto a new line + * after a block element (paragraph/list/code/…). */ -export function Markdown({ content, highlightTerms }: { content: string; highlightTerms?: string[] }) { +export function Markdown({ + content, + highlightTerms, + streaming, +}: { + content: string; + highlightTerms?: string[]; + streaming?: boolean; +}) { const blocks = useMemo(() => parseBlocks(content), [content]); + const caret = streaming ? : null; return (
{blocks.map((block, i) => ( - + ))} + {blocks.length === 0 && caret}
); } +function StreamingCaret() { + return ( + + ); +} + /* ------------------------------------------------------------------ */ /* Types */ /* ------------------------------------------------------------------ */ @@ -58,7 +86,11 @@ function parseBlocks(text: string): BlockNode[] { // Heading const headingMatch = line.match(/^(#{1,4})\s+(.+)/); if (headingMatch) { - blocks.push({ type: "heading", level: headingMatch[1].length, content: headingMatch[2] }); + blocks.push({ + type: "heading", + level: headingMatch[1].length, + content: headingMatch[2], + }); i++; continue; } @@ -124,12 +156,23 @@ function parseBlocks(text: string): BlockNode[] { /* Block renderer */ /* ------------------------------------------------------------------ */ -function Block({ block, highlightTerms }: { block: BlockNode; highlightTerms?: string[] }) { +function Block({ + block, + highlightTerms, + caret, +}: { + block: BlockNode; + highlightTerms?: string[]; + caret?: ReactNode; +}) { switch (block.type) { case "code": return (
-          {block.content}
+          
+            {block.content}
+            {caret}
+          
         
); @@ -141,25 +184,46 @@ function Block({ block, highlightTerms }: { block: BlockNode; highlightTerms?: s h3: "text-sm font-semibold", h4: "text-sm font-medium", }; - return ; + return ( + + + {caret} + + ); } case "hr": - return
; + return ( + <> +
+ {caret} + + ); case "list": { const Tag = block.ordered ? "ol" : "ul"; + const last = block.items.length - 1; return ( - + {block.items.map((item, i) => ( -
  • +
  • + + {i === last ? caret : null} +
  • ))}
    ); } case "paragraph": - return

    ; + return ( +

    + + {caret} +

    + ); } } @@ -178,7 +242,8 @@ type InlineNode = function parseInline(text: string): InlineNode[] { const nodes: InlineNode[] = []; // Pattern priority: code > link > bold > italic > bare URL > line break - const pattern = /(`[^`]+`)|(\[([^\]]+)\]\(([^)]+)\))|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)|(\bhttps?:\/\/[^\s<>)\]]+)|(\n)/g; + const pattern = + /(`[^`]+`)|(\[([^\]]+)\]\(([^)]+)\))|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)|(\bhttps?:\/\/[^\s<>)\]]+)|(\n)/g; let lastIndex = 0; let match: RegExpExecArray | null; @@ -217,7 +282,13 @@ function parseInline(text: string): InlineNode[] { return nodes; } -function InlineContent({ text, highlightTerms }: { text: string; highlightTerms?: string[] }) { +function InlineContent({ + text, + highlightTerms, +}: { + text: string; + highlightTerms?: string[]; +}) { const nodes = useMemo(() => parseInline(text), [text]); return ( @@ -225,17 +296,34 @@ function InlineContent({ text, highlightTerms }: { text: string; highlightTerms? {nodes.map((node, i) => { switch (node.type) { case "text": - return ; + return ( + + ); case "code": return ( - + {node.content} ); case "bold": - return ; + return ( + + + + ); case "italic": - return ; + return ( + + + + ); case "link": return (
    {parts.map((part, i) => regex.test(part) ? ( - {part} + + {part} + ) : ( {part} - ) + ), )} ); diff --git a/web/src/components/ModelPickerDialog.tsx b/web/src/components/ModelPickerDialog.tsx new file mode 100644 index 000000000..13a7268ac --- /dev/null +++ b/web/src/components/ModelPickerDialog.tsx @@ -0,0 +1,392 @@ +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import type { GatewayClient } from "@/lib/gatewayClient"; +import { Check, Loader2, Search, X } from "lucide-react"; +import { useEffect, useMemo, useRef, useState } from "react"; + +/** + * Two-stage model picker modal. + * + * Mirrors ui-tui/src/components/modelPicker.tsx: + * Stage 1: pick provider (authenticated providers only) + * Stage 2: pick model within that provider + * + * On confirm, emits `/model --provider [--global]` through + * the parent callback so ChatPage can dispatch it via the existing slash + * pipeline. That keeps persistence + actual switch logic in one place. + */ + +interface ModelOptionProvider { + name: string; + slug: string; + models?: string[]; + total_models?: number; + is_current?: boolean; + warning?: string; +} + +interface ModelOptionsResponse { + model?: string; + provider?: string; + providers?: ModelOptionProvider[]; +} + +interface Props { + gw: GatewayClient; + sessionId: string; + onClose(): void; + /** Parent runs the resulting slash command through slashExec. */ + onSubmit(slashCommand: string): void; +} + +export function ModelPickerDialog({ gw, sessionId, onClose, onSubmit }: Props) { + const [providers, setProviders] = useState([]); + const [currentModel, setCurrentModel] = useState(""); + const [currentProviderSlug, setCurrentProviderSlug] = useState(""); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [selectedSlug, setSelectedSlug] = useState(""); + const [selectedModel, setSelectedModel] = useState(""); + const [query, setQuery] = useState(""); + const [persistGlobal, setPersistGlobal] = useState(false); + const closedRef = useRef(false); + + // Load providers + models on open. + useEffect(() => { + closedRef.current = false; + + gw.request( + "model.options", + sessionId ? { session_id: sessionId } : {}, + ) + .then((r) => { + if (closedRef.current) return; + const next = r?.providers ?? []; + setProviders(next); + setCurrentModel(String(r?.model ?? "")); + setCurrentProviderSlug(String(r?.provider ?? "")); + setSelectedSlug( + (next.find((p) => p.is_current) ?? next[0])?.slug ?? "", + ); + setSelectedModel(""); + setLoading(false); + }) + .catch((e) => { + if (closedRef.current) return; + setError(e instanceof Error ? e.message : String(e)); + setLoading(false); + }); + + return () => { + closedRef.current = true; + }; + }, [gw, sessionId]); + + // Esc closes. + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") { + e.preventDefault(); + onClose(); + } + }; + window.addEventListener("keydown", onKey); + return () => window.removeEventListener("keydown", onKey); + }, [onClose]); + + const selectedProvider = useMemo( + () => providers.find((p) => p.slug === selectedSlug) ?? null, + [providers, selectedSlug], + ); + + const models = useMemo( + () => selectedProvider?.models ?? [], + [selectedProvider], + ); + + const needle = query.trim().toLowerCase(); + + const filteredProviders = useMemo( + () => + !needle + ? providers + : providers.filter( + (p) => + p.name.toLowerCase().includes(needle) || + p.slug.toLowerCase().includes(needle) || + (p.models ?? []).some((m) => m.toLowerCase().includes(needle)), + ), + [providers, needle], + ); + + const filteredModels = useMemo( + () => + !needle ? models : models.filter((m) => m.toLowerCase().includes(needle)), + [models, needle], + ); + + const canConfirm = !!selectedProvider && !!selectedModel; + + const confirm = () => { + if (!canConfirm) return; + const global = persistGlobal ? " --global" : ""; + onSubmit( + `/model ${selectedModel} --provider ${selectedProvider.slug}${global}`, + ); + onClose(); + }; + + return ( +
    e.target === e.currentTarget && onClose()} + role="dialog" + aria-modal="true" + aria-labelledby="model-picker-title" + > +
    + + +
    +

    + Switch Model +

    +

    + current: {currentModel || "(unknown)"} + {currentProviderSlug && ` · ${currentProviderSlug}`} +

    +
    + +
    +
    + + setQuery(e.target.value)} + className="pl-7 h-8 text-sm" + /> +
    +
    + +
    + { + setSelectedSlug(slug); + setSelectedModel(""); + }} + /> + + { + setSelectedModel(m); + // Confirm on next tick so state settles. + window.setTimeout(confirm, 0); + }} + /> +
    + +
    + + +
    + + +
    +
    +
    +
    + ); +} + +/* ------------------------------------------------------------------ */ +/* Provider column */ +/* ------------------------------------------------------------------ */ + +function ProviderColumn({ + loading, + error, + providers, + total, + selectedSlug, + query, + onSelect, +}: { + loading: boolean; + error: string | null; + providers: ModelOptionProvider[]; + total: number; + selectedSlug: string; + query: string; + onSelect(slug: string): void; +}) { + return ( +
    + {loading && ( +
    + loading… +
    + )} + + {error &&
    {error}
    } + + {!loading && !error && providers.length === 0 && ( +
    + {query + ? "no matches" + : total === 0 + ? "no authenticated providers" + : "no matches"} +
    + )} + + {providers.map((p) => { + const active = p.slug === selectedSlug; + return ( + + ); + })} +
    + ); +} + +/* ------------------------------------------------------------------ */ +/* Model column */ +/* ------------------------------------------------------------------ */ + +function ModelColumn({ + provider, + models, + allModels, + selectedModel, + currentModel, + currentProviderSlug, + onSelect, + onConfirm, +}: { + provider: ModelOptionProvider | null; + models: string[]; + allModels: string[]; + selectedModel: string; + currentModel: string; + currentProviderSlug: string; + onSelect(model: string): void; + onConfirm(model: string): void; +}) { + if (!provider) { + return ( +
    +
    + pick a provider → +
    +
    + ); + } + + return ( +
    + {provider.warning && ( +
    + {provider.warning} +
    + )} + + {models.length === 0 ? ( +
    + {allModels.length + ? "no models match your filter" + : "no models listed for this provider"} +
    + ) : ( + models.map((m) => { + const active = m === selectedModel; + const isCurrent = + m === currentModel && provider.slug === currentProviderSlug; + + return ( + + ); + }) + )} +
    + ); +} + +function CurrentTag() { + return ( + + current + + ); +} diff --git a/web/src/components/SlashPopover.tsx b/web/src/components/SlashPopover.tsx new file mode 100644 index 000000000..1c4b273b3 --- /dev/null +++ b/web/src/components/SlashPopover.tsx @@ -0,0 +1,174 @@ +import type { GatewayClient } from "@/lib/gatewayClient"; +import { ChevronRight } from "lucide-react"; +import { + forwardRef, + useCallback, + useEffect, + useImperativeHandle, + useRef, + useState, +} from "react"; + +/** + * Slash-command autocomplete popover, rendered above the composer in ChatPage. + * Mirrors the completion UX of the Ink TUI — type `/`, see matching commands, + * arrow keys or click to select, Tab to apply, Enter to submit. + * + * The parent owns all keyboard handling via `ref.handleKey`, which returns + * true when the popover consumed the event, so the composer's Enter/arrow + * logic stays in one place. + */ + +export interface CompletionItem { + display: string; + text: string; + meta?: string; +} + +export interface SlashPopoverHandle { + /** Returns true if the key was consumed by the popover. */ + handleKey(e: React.KeyboardEvent): boolean; +} + +interface Props { + input: string; + gw: GatewayClient | null; + onApply(nextInput: string): void; +} + +interface CompletionResponse { + items?: CompletionItem[]; + replace_from?: number; +} + +const DEBOUNCE_MS = 60; + +export const SlashPopover = forwardRef( + function SlashPopover({ input, gw, onApply }, ref) { + const [items, setItems] = useState([]); + const [selected, setSelected] = useState(0); + const [replaceFrom, setReplaceFrom] = useState(1); + const lastInputRef = useRef(""); + + // Debounced completion fetch. We never clear `items` in the effect body + // (doing so would flag react-hooks/set-state-in-effect); instead the + // render guard below hides stale items once the input stops matching. + useEffect(() => { + const trimmed = input ?? ""; + + if (!gw || !trimmed.startsWith("/") || trimmed === lastInputRef.current) { + if (!trimmed.startsWith("/")) lastInputRef.current = ""; + return; + } + lastInputRef.current = trimmed; + + const timer = window.setTimeout(async () => { + if (lastInputRef.current !== trimmed) return; + try { + const r = await gw.request("complete.slash", { + text: trimmed, + }); + if (lastInputRef.current !== trimmed) return; + setItems(r?.items ?? []); + setReplaceFrom(r?.replace_from ?? 1); + setSelected(0); + } catch { + if (lastInputRef.current === trimmed) setItems([]); + } + }, DEBOUNCE_MS); + + return () => window.clearTimeout(timer); + }, [input, gw]); + + const apply = useCallback( + (item: CompletionItem) => { + onApply(input.slice(0, replaceFrom) + item.text); + }, + [input, replaceFrom, onApply], + ); + + // Only consume keys when the popover is actually visible. Stale items from + // a previous slash prefix are ignored once the user deletes the "/". + const visible = items.length > 0 && input.startsWith("/"); + + useImperativeHandle( + ref, + () => ({ + handleKey: (e) => { + if (!visible) return false; + + switch (e.key) { + case "ArrowDown": + e.preventDefault(); + setSelected((s) => (s + 1) % items.length); + return true; + + case "ArrowUp": + e.preventDefault(); + setSelected((s) => (s - 1 + items.length) % items.length); + return true; + + case "Tab": { + e.preventDefault(); + const item = items[selected]; + if (item) apply(item); + return true; + } + + case "Escape": + e.preventDefault(); + setItems([]); + return true; + + default: + return false; + } + }, + }), + [visible, items, selected, apply], + ); + + if (!visible) return null; + + return ( +
    + {items.map((it, i) => { + const active = i === selected; + + return ( + + ); + })} +
    + ); + }, +); diff --git a/web/src/components/ToolCall.tsx b/web/src/components/ToolCall.tsx new file mode 100644 index 000000000..8ac1ebce6 --- /dev/null +++ b/web/src/components/ToolCall.tsx @@ -0,0 +1,228 @@ +import { + AlertCircle, + Check, + ChevronDown, + ChevronRight, + Zap, +} from "lucide-react"; +import { useEffect, useState } from "react"; + +/** + * Expandable tool call row — the web equivalent of Ink's ToolTrail node. + * + * Renders one `tool.start` + `tool.complete` pair (plus any `tool.progress` + * in between) as a single collapsible item in the transcript: + * + * ▸ ● read_file(path=/foo) 2.3s + * + * Click the header to reveal a preformatted body with context (args), the + * streaming preview (while running), and the final summary or error. Error + * rows auto-expand so failures aren't silently collapsed. + */ + +export interface ToolEntry { + kind: "tool"; + id: string; + tool_id: string; + name: string; + context?: string; + preview?: string; + summary?: string; + error?: string; + inline_diff?: string; + status: "running" | "done" | "error"; + startedAt: number; + completedAt?: number; +} + +const STATUS_TONE: Record = { + running: "border-primary/40 bg-primary/[0.04]", + done: "border-border bg-muted/20", + error: "border-destructive/50 bg-destructive/[0.04]", +}; + +const BULLET_TONE: Record = { + running: "text-primary", + done: "text-primary/80", + error: "text-destructive", +}; + +const TICK_MS = 500; + +export function ToolCall({ tool }: { tool: ToolEntry }) { + // `open` is derived: errors default-expanded, everything else collapsed. + // `null` means "follow the default"; any explicit bool is the user's override. + // This lets a running tool flip to expanded automatically when it errors, + // without mirroring state in an effect. + const [userOverride, setUserOverride] = useState(null); + const open = userOverride ?? tool.status === "error"; + + // Tick `now` while the tool is running so the elapsed label updates live. + const [now, setNow] = useState(() => Date.now()); + useEffect(() => { + if (tool.status !== "running") return; + const id = window.setInterval(() => setNow(() => Date.now()), TICK_MS); + return () => window.clearInterval(id); + }, [tool.status]); + + // Historical tools (hydrated from session.resume) signal missing timestamps + // with `startedAt === 0`; we hide the elapsed badge for those rather than + // rendering a misleading "0ms". + const hasTimestamps = tool.startedAt > 0; + const elapsed = hasTimestamps + ? fmtElapsed((tool.completedAt ?? now) - tool.startedAt) + : null; + + const hasBody = !!( + tool.context || + tool.preview || + tool.summary || + tool.error || + tool.inline_diff + ); + + const Chevron = open ? ChevronDown : ChevronRight; + + return ( +
    + + + {open && hasBody && ( +
    + {tool.context &&
    {tool.context}
    } + + {tool.preview && tool.status === "running" && ( +
    + {tool.preview} + +
    + )} + + {tool.inline_diff && ( +
    +
    +                {colorizeDiff(tool.inline_diff)}
    +              
    +
    + )} + + {tool.summary && ( +
    + + {tool.summary} + +
    + )} + + {tool.error && ( +
    + + {tool.error} + +
    + )} +
    + )} +
    + ); +} + +function Section({ + label, + children, + tone, +}: { + label: string; + children: React.ReactNode; + tone?: "error"; +}) { + return ( +
    + + {label} + + +
    {children}
    +
    + ); +} + +function fmtElapsed(ms: number): string { + const sec = Math.max(0, ms) / 1000; + if (sec < 1) return `${Math.round(ms)}ms`; + if (sec < 10) return `${sec.toFixed(1)}s`; + if (sec < 60) return `${Math.round(sec)}s`; + + const m = Math.floor(sec / 60); + const s = Math.round(sec % 60); + return s ? `${m}m ${s}s` : `${m}m`; +} + +/** Colorize unified-diff lines for the inline diff section. */ +function colorizeDiff(diff: string): React.ReactNode { + return diff.split("\n").map((line, i) => ( +
    + {line || "\u00A0"} +
    + )); +} + +function diffLineClass(line: string): string { + if (line.startsWith("+") && !line.startsWith("+++")) + return "text-emerald-500 dark:text-emerald-400"; + if (line.startsWith("-") && !line.startsWith("---")) + return "text-destructive"; + if (line.startsWith("@@")) return "text-primary"; + return "text-muted-foreground/80"; +} diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 352f6d730..c587bfc85 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -67,6 +67,7 @@ export const en: Translations = { }, nav: { analytics: "Analytics", + chat: "Chat", config: "Config", cron: "Cron", documentation: "Documentation", @@ -131,6 +132,7 @@ export const en: Translations = { "This permanently removes the conversation and all of its messages. This cannot be undone.", sessionDeleted: "Session deleted", failedToDelete: "Failed to delete session", + resumeInChat: "Resume in Chat", previousPage: "Previous page", nextPage: "Next page", roles: { diff --git a/web/src/i18n/types.ts b/web/src/i18n/types.ts index 45da160af..9fe254115 100644 --- a/web/src/i18n/types.ts +++ b/web/src/i18n/types.ts @@ -67,6 +67,7 @@ export interface Translations { }; nav: { analytics: string; + chat: string; config: string; cron: string; documentation: string; @@ -132,6 +133,7 @@ export interface Translations { confirmDeleteMessage: string; sessionDeleted: string; failedToDelete: string; + resumeInChat: string; previousPage: string; nextPage: string; roles: { diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index b7df4e24a..58953ffb4 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -66,6 +66,7 @@ export const zh: Translations = { }, nav: { analytics: "分析", + chat: "对话", config: "配置", cron: "定时任务", documentation: "文档", @@ -129,6 +130,7 @@ export const zh: Translations = { confirmDeleteMessage: "此操作将永久删除对话及其所有消息,无法恢复。", sessionDeleted: "会话已删除", failedToDelete: "删除会话失败", + resumeInChat: "在对话中继续", previousPage: "上一页", nextPage: "下一页", roles: { diff --git a/web/src/index.css b/web/src/index.css index 1e5e9cb9e..e9818174e 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -5,6 +5,36 @@ Tailwind's JIT purge. */ @source '../node_modules/@nous-research/ui/dist'; +/* ------------------------------------------------------------------ */ +/* JetBrains Mono — bundled for the embedded TUI (/chat tab). */ +/* Gives the terminal a proper monospace font even on systems where */ +/* the user doesn't have one installed locally; xterm.js picks it up */ +/* via ChatPage's `fontFamily` option. */ +/* Apache-2.0. */ +/* ------------------------------------------------------------------ */ + +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url('/fonts-terminal/JetBrainsMono-Regular.woff2') format('woff2'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url('/fonts-terminal/JetBrainsMono-Bold.woff2') format('woff2'); +} +@font-face { + font-family: 'JetBrains Mono'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url('/fonts-terminal/JetBrainsMono-Italic.woff2') format('woff2'); +} + /* ------------------------------------------------------------------ */ /* Hermes Agent — Nous DS with the LENS_0 (Hermes teal) lens applied */ /* statically. Mirrors nousnet-web/(hermes-agent)/layout.tsx so the */ diff --git a/web/src/lib/gatewayClient.ts b/web/src/lib/gatewayClient.ts new file mode 100644 index 000000000..012482b71 --- /dev/null +++ b/web/src/lib/gatewayClient.ts @@ -0,0 +1,236 @@ +/** + * Browser WebSocket client for the tui_gateway JSON-RPC protocol. + * + * Speaks the exact same newline-delimited JSON-RPC dialect that the Ink TUI + * drives over stdio. The server-side transport abstraction + * (tui_gateway/transport.py + ws.py) routes the same dispatcher's writes + * onto either stdout or a WebSocket depending on how the client connected. + * + * const gw = new GatewayClient() + * await gw.connect() + * const { session_id } = await gw.request<{ session_id: string }>("session.create") + * gw.on("message.delta", (ev) => console.log(ev.payload?.text)) + * await gw.request("prompt.submit", { session_id, text: "hi" }) + */ + +export type GatewayEventName = + | "gateway.ready" + | "session.info" + | "message.start" + | "message.delta" + | "message.complete" + | "thinking.delta" + | "reasoning.delta" + | "reasoning.available" + | "status.update" + | "tool.start" + | "tool.progress" + | "tool.complete" + | "tool.generating" + | "clarify.request" + | "approval.request" + | "sudo.request" + | "secret.request" + | "background.complete" + | "btw.complete" + | "error" + | "skin.changed" + | (string & {}); + +export interface GatewayEvent

    { + type: GatewayEventName; + session_id?: string; + payload?: P; +} + +export type ConnectionState = + | "idle" + | "connecting" + | "open" + | "closed" + | "error"; + +interface Pending { + resolve: (v: unknown) => void; + reject: (e: Error) => void; + timer: ReturnType; +} + +const DEFAULT_REQUEST_TIMEOUT_MS = 120_000; + +/** Wildcard listener key: subscribe to every event regardless of type. */ +const ANY = "*"; + +export class GatewayClient { + private ws: WebSocket | null = null; + private reqId = 0; + private pending = new Map(); + private listeners = new Map void>>(); + private _state: ConnectionState = "idle"; + private stateListeners = new Set<(s: ConnectionState) => void>(); + + get state(): ConnectionState { + return this._state; + } + + private setState(s: ConnectionState) { + if (this._state === s) return; + this._state = s; + for (const cb of this.stateListeners) cb(s); + } + + onState(cb: (s: ConnectionState) => void): () => void { + this.stateListeners.add(cb); + cb(this._state); + return () => this.stateListeners.delete(cb); + } + + /** Subscribe to a specific event type. Returns an unsubscribe function. */ + on

    ( + type: GatewayEventName, + cb: (ev: GatewayEvent

    ) => void, + ): () => void { + let set = this.listeners.get(type); + if (!set) { + set = new Set(); + this.listeners.set(type, set); + } + set.add(cb as (ev: GatewayEvent) => void); + return () => set!.delete(cb as (ev: GatewayEvent) => void); + } + + /** Subscribe to every event (fires after type-specific listeners). */ + onAny(cb: (ev: GatewayEvent) => void): () => void { + return this.on(ANY as GatewayEventName, cb); + } + + async connect(token?: string): Promise { + if (this._state === "open" || this._state === "connecting") return; + this.setState("connecting"); + + const resolved = token ?? window.__HERMES_SESSION_TOKEN__ ?? ""; + if (!resolved) { + this.setState("error"); + throw new Error( + "Session token not available — page must be served by the Hermes dashboard", + ); + } + + const scheme = location.protocol === "https:" ? "wss:" : "ws:"; + const ws = new WebSocket( + `${scheme}//${location.host}/api/ws?token=${encodeURIComponent(resolved)}`, + ); + this.ws = ws; + + // Register message + close BEFORE awaiting open — the server emits + // `gateway.ready` immediately after accept, so a listener attached + // after the open promise resolves can race past it and drop the + // initial skin payload. + ws.addEventListener("message", (ev) => { + try { + this.dispatch(JSON.parse(ev.data)); + } catch { + /* malformed frame — ignore */ + } + }); + + ws.addEventListener("close", () => { + this.setState("closed"); + this.rejectAllPending(new Error("WebSocket closed")); + }); + + await new Promise((resolve, reject) => { + const onOpen = () => { + ws.removeEventListener("error", onError); + this.setState("open"); + resolve(); + }; + const onError = () => { + ws.removeEventListener("open", onOpen); + this.setState("error"); + reject(new Error("WebSocket connection failed")); + }; + ws.addEventListener("open", onOpen, { once: true }); + ws.addEventListener("error", onError, { once: true }); + }); + } + + close() { + this.ws?.close(); + this.ws = null; + } + + private dispatch(msg: Record) { + const id = msg.id as string | undefined; + + if (id !== undefined && this.pending.has(id)) { + const p = this.pending.get(id)!; + this.pending.delete(id); + clearTimeout(p.timer); + + const err = msg.error as { message?: string } | undefined; + if (err) p.reject(new Error(err.message ?? "request failed")); + else p.resolve(msg.result); + return; + } + + if (msg.method !== "event") return; + + const params = (msg.params ?? {}) as GatewayEvent; + if (typeof params.type !== "string") return; + + for (const cb of this.listeners.get(params.type) ?? []) cb(params); + for (const cb of this.listeners.get(ANY) ?? []) cb(params); + } + + private rejectAllPending(err: Error) { + for (const p of this.pending.values()) { + clearTimeout(p.timer); + p.reject(err); + } + this.pending.clear(); + } + + /** Send a JSON-RPC request. Rejects on error response or timeout. */ + request( + method: string, + params: Record = {}, + timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS, + ): Promise { + if (!this.ws || this._state !== "open") { + return Promise.reject( + new Error(`gateway not connected (state=${this._state})`), + ); + } + + const id = `w${++this.reqId}`; + + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + if (this.pending.delete(id)) { + reject(new Error(`request timed out: ${method}`)); + } + }, timeoutMs); + + this.pending.set(id, { + resolve: (v) => resolve(v as T), + reject, + timer, + }); + + try { + this.ws!.send(JSON.stringify({ jsonrpc: "2.0", id, method, params })); + } catch (e) { + clearTimeout(timer); + this.pending.delete(id); + reject(e instanceof Error ? e : new Error(String(e))); + } + }); + } +} + +declare global { + interface Window { + __HERMES_SESSION_TOKEN__?: string; + } +} diff --git a/web/src/lib/resolve-page-title.ts b/web/src/lib/resolve-page-title.ts index 7d8cfd1ba..00d2d1e6e 100644 --- a/web/src/lib/resolve-page-title.ts +++ b/web/src/lib/resolve-page-title.ts @@ -1,6 +1,7 @@ import type { Translations } from "@/i18n/types"; const BUILTIN: Record = { + "/chat": "chat", "/sessions": "sessions", "/analytics": "analytics", "/logs": "logs", diff --git a/web/src/lib/slashExec.ts b/web/src/lib/slashExec.ts new file mode 100644 index 000000000..c232f2aa4 --- /dev/null +++ b/web/src/lib/slashExec.ts @@ -0,0 +1,163 @@ +/** + * Slash command execution pipeline for the web chat. + * + * Mirrors the Ink TUI's createSlashHandler.ts: + * + * 1. Parse the command into `name` + `arg`. + * 2. Try `slash.exec` — covers every registry-backed command the terminal + * UI knows about (/help, /resume, /compact, /model, …). Output is + * rendered into the transcript. + * 3. If `slash.exec` errors (command rejected, unknown, or needs client + * behaviour), fall back to `command.dispatch` which returns a typed + * directive: `exec` | `plugin` | `alias` | `skill` | `send`. + * 4. Each directive is dispatched to the appropriate callback. + * + * Keeping the pipeline here (instead of inline in ChatPage) lets future + * clients (SwiftUI, Android) implement the same logic by reading the same + * contract. + */ + +import type { GatewayClient } from "@/lib/gatewayClient"; + +export interface SlashExecResponse { + output?: string; + warning?: string; +} + +export type CommandDispatchResponse = + | { type: "exec" | "plugin"; output?: string } + | { type: "alias"; target: string } + | { type: "skill"; name: string; message?: string } + | { type: "send"; message: string }; + +export interface SlashExecCallbacks { + /** Render a transcript system message. */ + sys(text: string): void; + /** Submit a user message to the agent (prompt.submit). */ + send(message: string): Promise | void; +} + +export interface SlashExecOptions { + /** Raw command including the leading slash (e.g. "/model opus-4.6"). */ + command: string; + /** Session id. If empty the call is still issued — some commands are session-less. */ + sessionId: string; + gw: GatewayClient; + callbacks: SlashExecCallbacks; +} + +export type SlashExecResult = "done" | "sent" | "error"; + +/** + * Run a slash command. Returns the terminal state so callers can decide + * whether to clear the composer, queue retries, etc. + */ +export async function executeSlash({ + command, + sessionId, + gw, + callbacks: { sys, send }, +}: SlashExecOptions): Promise { + const { name, arg } = parseSlash(command); + + if (!name) { + sys("empty slash command"); + return "error"; + } + + // Primary dispatcher. + try { + const r = await gw.request("slash.exec", { + command: command.replace(/^\/+/, ""), + session_id: sessionId, + }); + const body = r?.output || `/${name}: no output`; + sys(r?.warning ? `warning: ${r.warning}\n${body}` : body); + return "done"; + } catch { + /* fall through to command.dispatch */ + } + + try { + const d = parseCommandDispatch( + await gw.request("command.dispatch", { + name, + arg, + session_id: sessionId, + }), + ); + + if (!d) { + sys("error: invalid response: command.dispatch"); + return "error"; + } + + switch (d.type) { + case "exec": + case "plugin": + sys(d.output ?? "(no output)"); + return "done"; + + case "alias": + return executeSlash({ + command: `/${d.target}${arg ? ` ${arg}` : ""}`, + sessionId, + gw, + callbacks: { sys, send }, + }); + + case "skill": + case "send": { + const msg = d.message?.trim() ?? ""; + if (!msg) { + sys( + `/${name}: ${d.type === "skill" ? "skill payload missing message" : "empty message"}`, + ); + return "error"; + } + if (d.type === "skill") sys(`⚡ loading skill: ${d.name}`); + await send(msg); + return "sent"; + } + } + } catch (err) { + sys(`error: ${err instanceof Error ? err.message : String(err)}`); + return "error"; + } +} + +export function parseSlash(command: string): { name: string; arg: string } { + const m = command.replace(/^\/+/, "").match(/^(\S+)\s*(.*)$/); + return m ? { name: m[1], arg: m[2].trim() } : { name: "", arg: "" }; +} + +function parseCommandDispatch(raw: unknown): CommandDispatchResponse | null { + if (!raw || typeof raw !== "object") return null; + + const r = raw as Record; + const str = (v: unknown) => (typeof v === "string" ? v : undefined); + + switch (r.type) { + case "exec": + case "plugin": + return { type: r.type, output: str(r.output) }; + + case "alias": + return typeof r.target === "string" + ? { type: "alias", target: r.target } + : null; + + case "skill": + return typeof r.name === "string" + ? { type: "skill", name: r.name, message: str(r.message) } + : null; + + case "send": + return typeof r.message === "string" + ? { type: "send", message: r.message } + : null; + + default: + return null; + } +} diff --git a/web/src/pages/ChatPage.tsx b/web/src/pages/ChatPage.tsx new file mode 100644 index 000000000..32c780b3e --- /dev/null +++ b/web/src/pages/ChatPage.tsx @@ -0,0 +1,474 @@ +/** + * ChatPage — embeds `hermes --tui` inside the dashboard. + * + *

    (dashboard chrome) . + * └─
    (rounded, dark bg, padded — the "terminal window" . + * look that gives the page a distinct visual identity) . + * └─ @xterm/xterm Terminal (WebGL renderer, Unicode 11 widths) . + * │ onData keystrokes → WebSocket → PTY master . + * │ onResize terminal resize → `\x1b[RESIZE:cols;rows]` . + * │ write(data) PTY output bytes → VT100 parser . + * ▼ . + * WebSocket /api/pty?token= . + * ▼ . + * FastAPI pty_ws (hermes_cli/web_server.py) . + * ▼ . + * POSIX PTY → `node ui-tui/dist/entry.js` → tui_gateway + AIAgent . + */ + +import { FitAddon } from "@xterm/addon-fit"; +import { Unicode11Addon } from "@xterm/addon-unicode11"; +import { WebLinksAddon } from "@xterm/addon-web-links"; +import { WebglAddon } from "@xterm/addon-webgl"; +import { Terminal } from "@xterm/xterm"; +import "@xterm/xterm/css/xterm.css"; +import { Copy } from "lucide-react"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { useSearchParams } from "react-router-dom"; + +import { ChatSidebar } from "@/components/ChatSidebar"; + +function buildWsUrl( + token: string, + resume: string | null, + channel: string, +): string { + const proto = window.location.protocol === "https:" ? "wss:" : "ws:"; + const qs = new URLSearchParams({ token, channel }); + if (resume) qs.set("resume", resume); + return `${proto}//${window.location.host}/api/pty?${qs.toString()}`; +} + +// Channel id ties this chat tab's PTY child (publisher) to its sidebar +// (subscriber). Generated once per mount so a tab refresh starts a fresh +// channel — the previous PTY child terminates with the old WS, and its +// channel auto-evicts when no subscribers remain. +function generateChannelId(): string { + if (typeof crypto !== "undefined" && "randomUUID" in crypto) { + return crypto.randomUUID(); + } + return `chat-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`; +} + +// Colors for the terminal body. Matches the dashboard's dark teal canvas +// with cream foreground — we intentionally don't pick monokai or a loud +// theme, because the TUI's skin engine already paints the content; the +// terminal chrome just needs to sit quietly inside the dashboard. +const TERMINAL_THEME = { + background: "#0d2626", + foreground: "#f0e6d2", + cursor: "#f0e6d2", + cursorAccent: "#0d2626", + selectionBackground: "#f0e6d244", +}; + +export default function ChatPage() { + const hostRef = useRef(null); + const termRef = useRef(null); + const fitRef = useRef(null); + const wsRef = useRef(null); + const [searchParams] = useSearchParams(); + // Lazy-init: the missing-token check happens at construction so the effect + // body doesn't have to setState (React 19's set-state-in-effect rule). + const [banner, setBanner] = useState(() => + typeof window !== "undefined" && !window.__HERMES_SESSION_TOKEN__ + ? "Session token unavailable. Open this page through `hermes dashboard`, not directly." + : null, + ); + const [copyState, setCopyState] = useState<"idle" | "copied">("idle"); + const copyResetRef = useRef | null>(null); + + const resumeRef = useRef(searchParams.get("resume")); + const channel = useMemo(() => generateChannelId(), []); + + const handleCopyLast = () => { + const ws = wsRef.current; + if (!ws || ws.readyState !== WebSocket.OPEN) return; + // Send the slash as a burst, wait long enough for Ink's tokenizer to + // emit a keypress event for each character (not coalesce them into a + // paste), then send Return as its own event. The timing here is + // empirical — 100ms is safely past Node's default stdin coalescing + // window and well inside UI responsiveness. + ws.send("/copy"); + setTimeout(() => { + const s = wsRef.current; + if (s && s.readyState === WebSocket.OPEN) s.send("\r"); + }, 100); + setCopyState("copied"); + if (copyResetRef.current) clearTimeout(copyResetRef.current); + copyResetRef.current = setTimeout(() => setCopyState("idle"), 1500); + termRef.current?.focus(); + }; + + useEffect(() => { + const host = hostRef.current; + if (!host) return; + + const token = window.__HERMES_SESSION_TOKEN__; + // Banner already initialised above; just bail before wiring xterm/WS. + if (!token) { + return; + } + + const term = new Terminal({ + allowProposedApi: true, + cursorBlink: true, + fontFamily: + "'JetBrains Mono', 'Cascadia Mono', 'Fira Code', 'MesloLGS NF', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace", + fontSize: 14, + lineHeight: 1.2, + macOptionIsMeta: true, + scrollback: 0, + theme: TERMINAL_THEME, + }); + termRef.current = term; + + // --- Clipboard integration --------------------------------------- + // + // Three independent paths all route to the system clipboard: + // + // 1. **Selection → Ctrl+C (or Cmd+C on macOS).** Ink's own handler + // in useInputHandlers.ts turns Ctrl+C into a copy when the + // terminal has a selection, then emits an OSC 52 escape. Our + // OSC 52 handler below decodes that escape and writes to the + // browser clipboard — so the flow works just like it does in + // `hermes --tui`. + // + // 2. **Ctrl/Cmd+Shift+C.** Belt-and-suspenders shortcut that + // operates directly on xterm's selection, useful if the TUI + // ever stops listening (e.g. overlays / pickers) or if the user + // has selected with the mouse outside of Ink's selection model. + // + // 3. **Ctrl/Cmd+Shift+V.** Reads the system clipboard and feeds + // it to the terminal as keyboard input. xterm's paste() wraps + // it with bracketed-paste if the host has that mode enabled. + // + // OSC 52 reads (terminal asking to read the clipboard) are not + // supported — that would let any content the TUI renders exfiltrate + // the user's clipboard. + term.parser.registerOscHandler(52, (data) => { + // Format: ";" + const semi = data.indexOf(";"); + if (semi < 0) return false; + const payload = data.slice(semi + 1); + if (payload === "?" || payload === "") return false; // read/clear — ignore + try { + // atob returns a binary string (one byte per char); we need UTF-8 + // decode so multi-byte codepoints (≥, →, emoji, CJK) round-trip + // correctly. Without this step, the three UTF-8 bytes of `≥` + // would land in the clipboard as the three separate Latin-1 + // characters `≥`. + const binary = atob(payload); + const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0)); + const text = new TextDecoder("utf-8").decode(bytes); + navigator.clipboard.writeText(text).catch(() => {}); + } catch { + // Malformed base64 — silently drop. + } + return true; + }); + + const isMac = + typeof navigator !== "undefined" && /Mac/i.test(navigator.platform); + + term.attachCustomKeyEventHandler((ev) => { + if (ev.type !== "keydown") return true; + + const copyModifier = isMac ? ev.metaKey : ev.ctrlKey && ev.shiftKey; + const pasteModifier = isMac ? ev.metaKey : ev.ctrlKey && ev.shiftKey; + + if (copyModifier && ev.key.toLowerCase() === "c") { + const sel = term.getSelection(); + if (sel) { + navigator.clipboard.writeText(sel).catch(() => {}); + ev.preventDefault(); + return false; + } + } + + if (pasteModifier && ev.key.toLowerCase() === "v") { + navigator.clipboard + .readText() + .then((text) => { + if (text) term.paste(text); + }) + .catch(() => {}); + ev.preventDefault(); + return false; + } + + return true; + }); + + const fit = new FitAddon(); + fitRef.current = fit; + term.loadAddon(fit); + + const unicode11 = new Unicode11Addon(); + term.loadAddon(unicode11); + term.unicode.activeVersion = "11"; + + term.loadAddon(new WebLinksAddon()); + + term.open(host); + + // WebGL renderer: rasterizes glyphs to a GPU texture atlas, paints + // each cell at an integer-pixel position. Box-drawing glyphs connect + // cleanly between rows (no DOM baseline / line-height math). Falls + // back to the default DOM renderer if WebGL is unavailable. + try { + const webgl = new WebglAddon(); + webgl.onContextLoss(() => webgl.dispose()); + term.loadAddon(webgl); + } catch (err) { + console.warn( + "[hermes-chat] WebGL renderer unavailable; falling back to default", + err, + ); + } + + // Initial fit + resize observer. fit.fit() reads the container's + // current bounding box and resizes the terminal grid to match. + // + // The subtle bit: the dashboard has CSS transitions on the container + // (backdrop fade-in, rounded corners settling as fonts load). If we + // call fit() at mount time, the bounding box we measure is often 1-2 + // cell widths off from the final size. ResizeObserver *does* fire + // when the container settles, but if the pixel delta happens to be + // smaller than one cell's width, fit() computes the same integer + // (cols, rows) as before and doesn't emit onResize — so the PTY + // never learns the final size. Users see truncated long lines until + // they resize the browser window. + // + // We force one extra fit + explicit RESIZE send after two animation + // frames. rAF→rAF guarantees one layout commit between the two + // callbacks, giving CSS transitions and font metrics time to finalize + // before we take the authoritative measurement. + let rafId = 0; + const scheduleFit = () => { + if (rafId) return; + rafId = requestAnimationFrame(() => { + rafId = 0; + try { + fit.fit(); + } catch { + // Element was removed mid-resize; cleanup will handle it. + } + }); + }; + fit.fit(); + const ro = new ResizeObserver(scheduleFit); + ro.observe(host); + + // Double-rAF authoritative fit. On the second frame the layout has + // committed at least once since mount; fit.fit() then reads the + // stable container size. We always send a RESIZE escape afterwards + // (even if fit's cols/rows didn't change, so the PTY has the same + // dims registered as our JS state — prevents a drift where Ink + // thinks the terminal is one col bigger than what's on screen). + let settleRaf1 = 0; + let settleRaf2 = 0; + settleRaf1 = requestAnimationFrame(() => { + settleRaf1 = 0; + settleRaf2 = requestAnimationFrame(() => { + settleRaf2 = 0; + try { + fit.fit(); + } catch { + return; + } + const sock = wsRef.current; + if (sock && sock.readyState === WebSocket.OPEN) { + sock.send(`\x1b[RESIZE:${term.cols};${term.rows}]`); + } + }); + }); + + // WebSocket + const url = buildWsUrl(token, resumeRef.current, channel); + const ws = new WebSocket(url); + ws.binaryType = "arraybuffer"; + wsRef.current = ws; + + ws.onopen = () => { + setBanner(null); + // Send the initial RESIZE immediately so Ink has *a* size to lay + // out against on its first paint. The double-rAF block above will + // follow up with the authoritative measurement — at worst Ink + // reflows once after the PTY boots, which is imperceptible. + ws.send(`\x1b[RESIZE:${term.cols};${term.rows}]`); + }; + + ws.onmessage = (ev) => { + if (typeof ev.data === "string") { + term.write(ev.data); + } else { + term.write(new Uint8Array(ev.data as ArrayBuffer)); + } + }; + + ws.onclose = (ev) => { + wsRef.current = null; + if (ev.code === 4401) { + setBanner("Auth failed. Reload the page to refresh the session token."); + return; + } + if (ev.code === 4403) { + setBanner("Chat is only reachable from localhost."); + return; + } + if (ev.code === 1011) { + // Server already wrote an ANSI error frame. + return; + } + term.write("\r\n\x1b[90m[session ended]\x1b[0m\r\n"); + }; + + // Keystrokes + mouse events → PTY, with cell-level dedup for motion. + // + // Ink enables `\x1b[?1003h` (any-motion tracking), which asks the + // terminal to report every mouse-move as an SGR mouse event even with + // no button held. xterm.js happily emits one report per pixel of + // mouse motion; without deduping, a casual mouse-over floods Ink with + // hundreds of redraw-triggering reports and the UI goes laggy + // (scrolling stutters, clicks land on stale positions by the time + // Ink finishes processing the motion backlog). + // + // We keep track of the last cell we reported a motion for. Press, + // release, and wheel events always pass through; motion events only + // pass through if the cell changed. Parsing is cheap — SGR reports + // are short literal strings. + // eslint-disable-next-line no-control-regex -- intentional ESC byte in xterm SGR mouse report parser + const SGR_MOUSE_RE = /^\x1b\[<(\d+);(\d+);(\d+)([Mm])$/; + let lastMotionCell = { col: -1, row: -1 }; + let lastMotionCb = -1; + const onDataDisposable = term.onData((data) => { + if (ws.readyState !== WebSocket.OPEN) return; + + const m = SGR_MOUSE_RE.exec(data); + if (m) { + const cb = parseInt(m[1], 10); + const col = parseInt(m[2], 10); + const row = parseInt(m[3], 10); + const released = m[4] === "m"; + // Motion events have bit 0x20 (32) set in the button code. + // Wheel events have bit 0x40 (64); always forward wheel. + const isMotion = (cb & 0x20) !== 0 && (cb & 0x40) === 0; + const isWheel = (cb & 0x40) !== 0; + if (isMotion && !isWheel && !released) { + if ( + col === lastMotionCell.col && + row === lastMotionCell.row && + cb === lastMotionCb + ) { + return; // same cell + same button state; skip redundant report + } + lastMotionCell = { col, row }; + lastMotionCb = cb; + } else { + // Non-motion event (press, release, wheel) — reset dedup state + // so the next motion after this always reports. + lastMotionCell = { col: -1, row: -1 }; + lastMotionCb = -1; + } + } + + ws.send(data); + }); + + const onResizeDisposable = term.onResize(({ cols, rows }) => { + if (ws.readyState === WebSocket.OPEN) { + ws.send(`\x1b[RESIZE:${cols};${rows}]`); + } + }); + + term.focus(); + + return () => { + onDataDisposable.dispose(); + onResizeDisposable.dispose(); + ro.disconnect(); + if (rafId) cancelAnimationFrame(rafId); + if (settleRaf1) cancelAnimationFrame(settleRaf1); + if (settleRaf2) cancelAnimationFrame(settleRaf2); + ws.close(); + wsRef.current = null; + term.dispose(); + termRef.current = null; + fitRef.current = null; + if (copyResetRef.current) { + clearTimeout(copyResetRef.current); + copyResetRef.current = null; + } + }; + }, [channel]); + + // Layout: + // outer flex column — sits inside the dashboard's content area + // row split — terminal pane (flex-1) + sidebar (fixed width, lg+) + // terminal wrapper — rounded, dark, padded — the "terminal window" + // floating copy button — bottom-right corner, transparent with a + // subtle border; stays out of the way until hovered. Sends + // `/copy\n` to Ink, which emits OSC 52 → our clipboard handler. + // sidebar — ChatSidebar opens its own JSON-RPC sidecar; renders + // model badge, tool-call list, model picker. Best-effort: if the + // sidecar fails to connect the terminal pane keeps working. + // + // `normal-case` opts out of the dashboard's global `uppercase` rule on + // the root `
    ` in App.tsx — terminal output must preserve case. + return ( +
    + {banner && ( +
    + {banner} +
    + )} +
    +
    +
    + + +
    + +
    + +
    +
    +
    + ); +} + +declare global { + interface Window { + __HERMES_SESSION_TOKEN__?: string; + } +} diff --git a/web/src/pages/SessionsPage.tsx b/web/src/pages/SessionsPage.tsx index ad6bb74ce..6e93b2583 100644 --- a/web/src/pages/SessionsPage.tsx +++ b/web/src/pages/SessionsPage.tsx @@ -1,4 +1,11 @@ -import { useEffect, useLayoutEffect, useState, useCallback, useRef } from "react"; +import { + useEffect, + useLayoutEffect, + useState, + useCallback, + useRef, +} from "react"; +import { useNavigate } from "react-router-dom"; import { AlertTriangle, CheckCircle2, @@ -16,6 +23,7 @@ import { MessageCircle, Hash, X, + Play, } from "lucide-react"; import { api } from "@/lib/api"; import type { @@ -262,6 +270,7 @@ function SessionRow({ const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const { t } = useI18n(); + const navigate = useNavigate(); useEffect(() => { if (isExpanded && messages === null && !loading) { @@ -341,6 +350,19 @@ function SessionRow({ {session.source ?? "local"} + , + ); + return () => setEnd(null); + }, [narrow, mobilePanelOpen, modelToolsLabel, setEnd]); + const handleCopyLast = () => { const ws = wsRef.current; if (!ws || ws.readyState !== WebSocket.OPEN) return; @@ -110,13 +221,17 @@ export default function ChatPage() { return; } + const tierW0 = terminalTierWidthPx(host); const term = new Terminal({ allowProposedApi: true, cursorBlink: true, fontFamily: "'JetBrains Mono', 'Cascadia Mono', 'Fira Code', 'MesloLGS NF', 'Source Code Pro', Menlo, Consolas, 'DejaVu Sans Mono', monospace", - fontSize: 14, - lineHeight: 1.2, + fontSize: terminalFontSizeForWidth(tierW0), + lineHeight: terminalLineHeightForWidth(tierW0), + letterSpacing: 0, + fontWeight: "400", + fontWeightBold: "700", macOptionIsMeta: true, scrollback: 0, theme: TERMINAL_THEME, @@ -212,19 +327,23 @@ export default function ChatPage() { term.open(host); - // WebGL renderer: rasterizes glyphs to a GPU texture atlas, paints - // each cell at an integer-pixel position. Box-drawing glyphs connect - // cleanly between rows (no DOM baseline / line-height math). Falls - // back to the default DOM renderer if WebGL is unavailable. - try { - const webgl = new WebglAddon(); - webgl.onContextLoss(() => webgl.dispose()); - term.loadAddon(webgl); - } catch (err) { - console.warn( - "[hermes-chat] WebGL renderer unavailable; falling back to default", - err, - ); + // WebGL draws from a texture atlas sized with device pixels. On phones and + // in DevTools device mode that often produces *visually* much larger cells + // than `fontSize` suggests — users see "huge" text even at 7–9px settings. + // The canvas/DOM renderer tracks `fontSize` faithfully; use it for narrow + // hosts. Wide layouts still get WebGL for crisp box-drawing. + const useWebgl = terminalTierWidthPx(host) >= 768; + if (useWebgl) { + try { + const webgl = new WebglAddon(); + webgl.onContextLoss(() => webgl.dispose()); + term.loadAddon(webgl); + } catch (err) { + console.warn( + "[hermes-chat] WebGL renderer unavailable; falling back to default", + err, + ); + } } // Initial fit + resize observer. fit.fit() reads the container's @@ -244,22 +363,65 @@ export default function ChatPage() { // frames. rAF→rAF guarantees one layout commit between the two // callbacks, giving CSS transitions and font metrics time to finalize // before we take the authoritative measurement. - let rafId = 0; - const scheduleFit = () => { - if (rafId) return; - rafId = requestAnimationFrame(() => { - rafId = 0; - try { - fit.fit(); - } catch { - // Element was removed mid-resize; cleanup will handle it. - } + let hostSyncRaf = 0; + const scheduleHostSync = () => { + if (hostSyncRaf) return; + hostSyncRaf = requestAnimationFrame(() => { + hostSyncRaf = 0; + syncTerminalMetrics(); }); }; - fit.fit(); - const ro = new ResizeObserver(scheduleFit); + + let metricsDebounce: ReturnType | null = null; + const syncTerminalMetrics = () => { + const w = terminalTierWidthPx(host); + const nextSize = terminalFontSizeForWidth(w); + const nextLh = terminalLineHeightForWidth(w); + const fontChanged = + term.options.fontSize !== nextSize || + term.options.lineHeight !== nextLh; + if (fontChanged) { + term.options.fontSize = nextSize; + term.options.lineHeight = nextLh; + } + try { + fit.fit(); + } catch { + return; + } + if (fontChanged && term.rows > 0) { + try { + term.refresh(0, term.rows - 1); + } catch { + /* ignore */ + } + } + if ( + fontChanged && + wsRef.current && + wsRef.current.readyState === WebSocket.OPEN + ) { + wsRef.current.send(`\x1b[RESIZE:${term.cols};${term.rows}]`); + } + }; + + const scheduleSyncTerminalMetrics = () => { + if (metricsDebounce) clearTimeout(metricsDebounce); + metricsDebounce = setTimeout(() => { + metricsDebounce = null; + syncTerminalMetrics(); + }, 60); + }; + + const ro = new ResizeObserver(() => scheduleHostSync()); ro.observe(host); + window.addEventListener("resize", scheduleSyncTerminalMetrics); + window.visualViewport?.addEventListener("resize", scheduleSyncTerminalMetrics); + window.visualViewport?.addEventListener("scroll", scheduleSyncTerminalMetrics); + scheduleHostSync(); + requestAnimationFrame(() => scheduleHostSync()); + // Double-rAF authoritative fit. On the second frame the layout has // committed at least once since mount; fit.fit() then reads the // stable container size. We always send a RESIZE escape afterwards @@ -272,15 +434,7 @@ export default function ChatPage() { settleRaf1 = 0; settleRaf2 = requestAnimationFrame(() => { settleRaf2 = 0; - try { - fit.fit(); - } catch { - return; - } - const sock = wsRef.current; - if (sock && sock.readyState === WebSocket.OPEN) { - sock.send(`\x1b[RESIZE:${term.cols};${term.rows}]`); - } + syncTerminalMetrics(); }); }); @@ -387,8 +541,18 @@ export default function ChatPage() { return () => { onDataDisposable.dispose(); onResizeDisposable.dispose(); + if (metricsDebounce) clearTimeout(metricsDebounce); + window.removeEventListener("resize", scheduleSyncTerminalMetrics); + window.visualViewport?.removeEventListener( + "resize", + scheduleSyncTerminalMetrics, + ); + window.visualViewport?.removeEventListener( + "scroll", + scheduleSyncTerminalMetrics, + ); ro.disconnect(); - if (rafId) cancelAnimationFrame(rafId); + if (hostSyncRaf) cancelAnimationFrame(hostSyncRaf); if (settleRaf1) cancelAnimationFrame(settleRaf1); if (settleRaf2) cancelAnimationFrame(settleRaf2); ws.close(); @@ -416,52 +580,149 @@ export default function ChatPage() { // // `normal-case` opts out of the dashboard's global `uppercase` rule on // the root `
    ` in App.tsx — terminal output must preserve case. + // + // Mobile model/tools sheet is portaled to `document.body` so it stacks + // above the app sidebar (`z-50`) and mobile chrome (`z-40`). The main + // dashboard column uses `relative z-2`, which traps `position:fixed` + // descendants below those layers (see Toast.tsx). + const mobileModelToolsPortal = + narrow && + portalRoot && + createPortal( + <> + {mobilePanelOpen && ( + +
    + +
    + +
    +
    + , + portalRoot, + ); + return ( -
    +
    + {mobileModelToolsPortal} + {banner && (
    {banner}
    )} -
    + +
    -
    +
    -
    - -
    + {!narrow && ( + + )}
    ); diff --git a/web/src/pages/DocsPage.tsx b/web/src/pages/DocsPage.tsx index 83b0694ec..5861aeccc 100644 --- a/web/src/pages/DocsPage.tsx +++ b/web/src/pages/DocsPage.tsx @@ -35,7 +35,7 @@ export default function DocsPage() {

    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�g(c~#B#Bhp~lwy6#P%5!HRS311ojNt= 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