Files tab: browser with breadcrumbs/sort/filter, text editor, image preview, streamed upload with progress, download, mkdir/touch/rename/move/chmod/delete, open-in-terminal; root toggle via sudo-reexecuted 'hamlab fs' helper

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-18 05:39:57 -07:00
co-authored by Claude Fable 5.1
parent 38d4ee09ae
commit 63b020d556
9 changed files with 1094 additions and 9 deletions
+3 -2
View File
@@ -51,7 +51,8 @@ export default function TerminalPane({ id, active, register, onStatus, onExit }:
let lastSize = ''
const enc = new TextEncoder()
const send = (s: string) => { if (ws && ws.readyState === WebSocket.OPEN) ws.send(enc.encode(s)) }
const queued: string[] = []
const send = (s: string) => { if (ws && ws.readyState === WebSocket.OPEN) ws.send(enc.encode(s)); else queued.push(s) }
const sendResize = () => {
const key = `${term.cols}x${term.rows}`
if (key === lastSize) return
@@ -69,7 +70,7 @@ export default function TerminalPane({ id, active, register, onStatus, onExit }:
const sock = new WebSocket(wsURL(id))
sock.binaryType = 'arraybuffer'
ws = sock
sock.onopen = () => { retry = 0; setConn('open'); cbs.current.onStatus(true); lastSize = ''; doFit() }
sock.onopen = () => { retry = 0; setConn('open'); cbs.current.onStatus(true); lastSize = ''; doFit(); while (queued.length) sock.send(enc.encode(queued.shift()!)) }
sock.onmessage = (ev) => {
if (ev.data instanceof ArrayBuffer) { term.write(new Uint8Array(ev.data)); return }
try {