char-slop/berry
multipurpose self-modifiable agentic harness
git clone https://git.t4t.associates/char-slop/berry
0853dde
main
1import { assertEquals , assertStringIncludes } from "@std/assert" ; 2import { BACKGROUND_CONTEXT as context } from "@earendil-works/chord/context" ; 3import { until } from "@berry/util" ; 4import { BOOTSTRAP , Connection , RemoteEnvironment , sshCommand } from "./connection.ts" ; 5 6const destination = Deno . env . get ( "BERRY_TEST_SSH" ); 7 8Deno . test ({ 9name :"remote terminal I/O stays inside its channel and leaves the worker usable" , 10ignore :! destination && ! [ "linux" , "windows" ]. includes ( Deno . build . os ), 11async fn () { 12const connection = await Connection . open ( 13"pty-test" , 14destination ?sshCommand ( destination ) :[ Deno . execPath (), "eval" , "--quiet" , BOOTSTRAP ], 15); 16const env = new RemoteEnvironment ( "pty-test" , connection , connection . hello . home ); 17try { 18const pty = await env . pty ( 19[ 20destination ?"deno" :Deno . execPath (), 21"eval" , 22` 23console.log('terminal=' + [Deno.stdin, Deno.stdout, Deno.stderr].every(s => s.isTerminal())); 24if (!Deno.stdin.isTerminal()) Deno.exit(2); 25Deno.stdin.setRaw(true); 26console.log('ready'); 27const buffer = new Uint8Array(1024); 28const decoder = new TextDecoder(); 29let input = ''; 30while (!input.includes('\\r')) { 31const n = await Deno.stdin.read(buffer); 32if (n === null) break; 33input += decoder.decode(buffer.subarray(0, n), { stream: true }); 34} 35console.log('received=' + input.trimEnd()); 36console.error('terminal-stderr'); 37console.log('size=' + JSON.stringify(Deno.consoleSize())); 38Deno.exit(17); 39` , 40], 41{ cols :100 , rows :30 }, 42context , 43); 44let output = "" ; 45let readError :unknown ; 46let exit :number | null | undefined ; 47const drained = ( async () => { 48const decoder = new TextDecoder (); 49for await ( const chunk of pty . readable ) output += decoder . decode ( chunk , { stream :true }); 50})(). catch (( error ) => readError = error ); 51void pty . exited . then (( code ) => exit = code ); 52const input = pty . writable . getWriter (); 53try { 54await until (() => { 55if ( connection . lost ) throw connection . lost ; 56return output . includes ( "ready" ); 57}); 58assertStringIncludes ( output , "terminal=true" ); 59pty . resize ( 90 , 33 ); 60await input . write ( new TextEncoder (). encode ( "berry-pty-probe\r" )); 61await until (() => exit !== undefined ); 62assertEquals ( exit , 17 ); 63await drained ; 64assertEquals ( readError , undefined ); 65assertStringIncludes ( output , "received=berry-pty-probe" ); 66assertStringIncludes ( output , "terminal-stderr" ); 67assertStringIncludes ( output , 'size={"columns":90,"rows":33}' ); 68assertEquals (( await env . fileInfo ( env . home , context )). ok , true ); 69} finally { 70pty . kill (); 71input . releaseLock (); 72} 73} finally { 74await connection . close (); 75} 76}, 77});