mirror of
https://github.com/hanzoai/cli.git
synced 2026-10-30 15:00:27 +00:00
ttyd's page is a fine terminal and the wrong surface for this product. It cannot be themed to match the console that frames it, it has no touch affordances, and — being somebody else's document inside a cross-origin frame — it swallows every keystroke the workspace would like to hear. Three problems, one cause: we did not own the page. Now we do. ttyd itself is untouched; only `--index` changes. WHAT THE PAGE IS. xterm.js and the fit addon, vendored and INLINED, plus ~180 lines of client. Inlined because ttyd serves exactly one document and no assets, so `src="./xterm.js"` would ask it for a file it does not have and render nothing — and because a terminal must not need a CDN to be up. Tests assert both: no relative asset, no remote fetch, and every placeholder substituted. THEMED. True black, because the terminal is the deepest surface in the product; monochrome foreground with the app's status hues; a bar cursor, 10k lines of scrollback, and a scrollbar that matches the console rather than the OS. THE KEY ROW. A soft keyboard has no Esc, no Ctrl, no Tab and no arrows, so on a phone a terminal without one is a terminal you can read and not use. Fourteen keys, docked above the software keyboard via visualViewport, with a STICKY ctrl — tap it, then tap a letter — which is the only way to reach ^C on a touch device and how Blink and Termius both do it. Rendered only where `pointer: coarse`. THE CHORD BRIDGE. The workspace's shortcuts cannot exist unless this page forwards them, so it forwards `⌃⌥` and NOTHING else: Ctrl belongs to the shell, Alt is readline's Meta, ⌘ is the browser's, and a workspace that takes one of those breaks the terminal it contains. AltGr reports as ctrl+alt on European layouts and is excluded explicitly, or AltGr+E (€) would read as a chord. PROVEN IN A REAL BROWSER, not asserted. Chromium at 1200x800 and as an iPhone 14: 43 rows and 33 rows, black ground, zero console errors, the key row present on touch and absent on desktop — and a round trip, typing a command and reading its output back out of the terminal. Both pages ran DIFFERENT shells from one server (`?arg=desktop`, `?arg=phone`), which is the one-link-many-shells claim demonstrated rather than described. Best-effort by design: a page we cannot write is a reason to serve ttyd's own, never a reason to have no terminal. Co-authored-by: Hanzo Dev <[email protected]>
2 lines
1.5 KiB
JavaScript
2 lines
1.5 KiB
JavaScript
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(globalThis,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;const t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),i=parseInt(r.getPropertyValue("height")),o=Math.max(0,parseInt(r.getPropertyValue("width"))),s=window.getComputedStyle(this._terminal.element),n=i-(parseInt(s.getPropertyValue("padding-top"))+parseInt(s.getPropertyValue("padding-bottom"))),l=o-(parseInt(s.getPropertyValue("padding-right"))+parseInt(s.getPropertyValue("padding-left")))-t;return{cols:Math.max(2,Math.floor(l/e.css.cell.width)),rows:Math.max(1,Math.floor(n/e.css.cell.height))}}}})(),e})()));
|
|
//# sourceMappingURL=addon-fit.js.map
|