feat(v0.3): keybar Claude shortcuts + scrollback search + clickable links
- keybar: add Esc·Esc / ^O / ^T / ^B + per-button tooltips (KEY_MAP 14 keys)
- M1 search: @xterm/addon-search per terminal; 🔍 toolbar button + search box
(Enter=next, Shift+Enter=prev, Esc=close)
- M2 links: @xterm/addon-web-links per terminal (tap URLs Claude prints)
- tab bar split into #tabs (scrollable) + #toolbar (utility cluster) for future
utilities (QR/settings/dashboard)
- Browser-verified: 14 keybar buttons, search highlights matches, no console errors.
199 tests green, typechecks + build ok.
This commit is contained in:
@@ -1,27 +1,34 @@
|
||||
/**
|
||||
* 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.
|
||||
* Bootstraps the multi-tab app: a tab bar (#tabs) + a utility toolbar (#toolbar)
|
||||
* over a stack of terminal panes (#term), each tab an independent TerminalSession.
|
||||
* 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
|
||||
// @ts-ignore CSS side-effect import processed by esbuild (→ public/build/main.css).
|
||||
import '@xterm/xterm/css/xterm.css'
|
||||
import { mountKeybar } from './keybar.js'
|
||||
import { TabApp } from './tabs.js'
|
||||
import { mountSearch } from './search.js'
|
||||
|
||||
const paneHost = document.getElementById('term')
|
||||
const tabBar = document.getElementById('tabbar')
|
||||
const tabs = document.getElementById('tabs')
|
||||
const toolbar = document.getElementById('toolbar')
|
||||
if (!paneHost) throw new Error('#term element not found in DOM')
|
||||
if (!tabBar) throw new Error('#tabbar element not found in DOM')
|
||||
if (!tabs) throw new Error('#tabs element not found in DOM')
|
||||
if (!toolbar) throw new Error('#toolbar element not found in DOM')
|
||||
|
||||
const app = new TabApp(paneHost, tabBar)
|
||||
const app = new TabApp(paneHost, tabs)
|
||||
|
||||
// Key bar (mobile) sends to whichever tab is active.
|
||||
// Key bar (mobile + desktop) sends to whichever tab is active.
|
||||
mountKeybar((data) => app.sendToActive(data))
|
||||
|
||||
// Toolbar utilities.
|
||||
mountSearch(toolbar, {
|
||||
find: (query, dir) => app.findInActive(query, dir),
|
||||
clear: () => app.clearActiveSearch(),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user