Frontend feature (backend unchanged — manager was already multi-session): - Multi-tab: each tab = independent WS + Terminal + session (terminal-session.ts, tabs.ts); tab bar with +, ×, middle-click close; persisted to localStorage (migrates v0.1 single-session key) - Tab titles: auto from xterm onTitleChange (OSC 0/2), double-click to rename inline (manual wins over auto); ellipsis + tooltip - Shortcut key bar now shown on ALL devices (clickable buttons trigger shortcuts), reordered for Claude Code (Esc prominent, ⇧Tab, ↑↓, ⏎, ^C, Tab, ←→, /); responsive sizing via @media (pointer:coarse) for touch - Verified in browser: rename, two independent sessions, keybar on desktop + narrow viewport. 191 tests green; both typechecks + esbuild build pass.
28 lines
1.0 KiB
TypeScript
28 lines
1.0 KiB
TypeScript
/**
|
|
* public/main.ts — esbuild entry point for the browser frontend.
|
|
*
|
|
* Bootstraps the multi-tab app: a tab bar (#tabbar) over a stack of terminal
|
|
* panes (#term), each tab an independent TerminalSession (own WS + server
|
|
* session). The mobile key bar routes input to the active tab.
|
|
*
|
|
* Per-session terminal/WS/reconnect logic lives in terminal-session.ts;
|
|
* tab management + persistence in tabs.ts.
|
|
*/
|
|
|
|
// CSS side-effect import processed by esbuild (→ public/build/main.css).
|
|
// tsc cannot resolve CSS paths; @ts-ignore suppresses the single diagnostic.
|
|
// @ts-ignore
|
|
import '@xterm/xterm/css/xterm.css'
|
|
import { mountKeybar } from './keybar.js'
|
|
import { TabApp } from './tabs.js'
|
|
|
|
const paneHost = document.getElementById('term')
|
|
const tabBar = document.getElementById('tabbar')
|
|
if (!paneHost) throw new Error('#term element not found in DOM')
|
|
if (!tabBar) throw new Error('#tabbar element not found in DOM')
|
|
|
|
const app = new TabApp(paneHost, tabBar)
|
|
|
|
// Key bar (mobile) sends to whichever tab is active.
|
|
mountKeybar((data) => app.sendToActive(data))
|