From 8fcc48dcff32f50797d7cfe4965dd1bc3c416c2b Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Sun, 15 Sep 2024 11:18:36 +0200 Subject: [PATCH] main: work in progress [might break] --- .../board/v86/rootfs_overlay/bin/html | 32 +++++++ .../board/v86/rootfs_overlay/bin/infinite | 11 +++ .../board/v86/rootfs_overlay/etc/inittab | 2 +- .../board/v86/rootfs_overlay/etc/motd | 7 +- .../board/v86/rootfs_overlay/etc/profile | 17 +++- .../board/v86/rootfs_overlay/etc/profile.js | 18 +++- .../board/v86/rootfs_overlay/etc/profile.sh | 11 +-- .../board/v86/rootfs_overlay/etc/profile.xrsh | 29 ++++-- .../v86/rootfs_overlay/root/.ash_history | 10 ++ .../board/v86/rootfs_overlay/root/.profile | 15 +++ .../board/v86/rootfs_overlay/root/.profile.js | 15 +++ .../board/v86/rootfs_overlay/root/.screenrc | 5 +- .../rootfs_overlay/root/hook.d/enter-ar/yo | 2 + .../rootfs_overlay/root/hook.d/enter-vr/yo | 2 + .../v86/rootfs_overlay/root/hook.d/exit-ar/yo | 2 + .../v86/rootfs_overlay/root/hook.d/exit-vr/yo | 2 + .../board/v86/rootfs_overlay/root/index.html | 5 + .../board/v86/rootfs_overlay/root/index.js | 2 + .../board/v86/rootfs_overlay/root/manual.md | 92 +++++++++++++++++++ .../board/v86/rootfs_overlay/root/manual.txt | 1 - 20 files changed, 254 insertions(+), 26 deletions(-) create mode 100755 buildroot-v86/board/v86/rootfs_overlay/bin/html create mode 100755 buildroot-v86/board/v86/rootfs_overlay/bin/infinite create mode 100644 buildroot-v86/board/v86/rootfs_overlay/root/.ash_history create mode 100644 buildroot-v86/board/v86/rootfs_overlay/root/.profile create mode 100644 buildroot-v86/board/v86/rootfs_overlay/root/.profile.js create mode 100755 buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-ar/yo create mode 100755 buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-vr/yo create mode 100755 buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-ar/yo create mode 100755 buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-vr/yo create mode 100755 buildroot-v86/board/v86/rootfs_overlay/root/index.html create mode 100755 buildroot-v86/board/v86/rootfs_overlay/root/index.js delete mode 100644 buildroot-v86/board/v86/rootfs_overlay/root/manual.txt diff --git a/buildroot-v86/board/v86/rootfs_overlay/bin/html b/buildroot-v86/board/v86/rootfs_overlay/bin/html new file mode 100755 index 0000000..9622a86 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/bin/html @@ -0,0 +1,32 @@ +#!/bin/sh +PID=$$ +test -z "$1" && { echo "Usage: html 'hello"; exit 0; } + +source /etc/profile.sh + +test -n "$BROWSER" || { alert warning "/dev/browser not active (are you running outside of v86?)"; } +html="$*" + +# if we are run as shebang, use the file as input +test -f "$1" && { + html="$(cat $1 | tail +2)" +} + +# below is not ideal +# first I tried /dev/ttyS* https://github.com/copy/v86/issues/530 +# and differentiate processes by prefixing output by PID's +# to parse it later with AWK, but it was very hairy + +OUTPUT=/mnt/$PID +echo "$html" > /dev/browser/html +sleep 0.1 +test -f $OUTPUT && { + cat $OUTPUT + rm $OUTPUT +} + + +# should we use flock, an awesome way to make processes read/write the same file +# while preventing 1001 concurrency issues? +# +# flock /dev/browser/html -c "echo \"$html\" > /dev/browser/html" diff --git a/buildroot-v86/board/v86/rootfs_overlay/bin/infinite b/buildroot-v86/board/v86/rootfs_overlay/bin/infinite new file mode 100755 index 0000000..3c57b68 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/bin/infinite @@ -0,0 +1,11 @@ +#!/bin/sh +trap 'echo "/bin/infinite: Ctrl-C pressed..infinite does not care.."; sleep 2s' INT +source /etc/profile.sh + +loop(){ + while sleep 1s; do + "$@" + done +} + +loop "$@" diff --git a/buildroot-v86/board/v86/rootfs_overlay/etc/inittab b/buildroot-v86/board/v86/rootfs_overlay/etc/inittab index 22321c6..d7a40bc 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/etc/inittab +++ b/buildroot-v86/board/v86/rootfs_overlay/etc/inittab @@ -27,7 +27,7 @@ # Put a getty on the serial port #console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL -console::respawn:-/bin/sh +#console::respawn:-/bin/sh # vga console # Auto-login as root on ttyS0 ::respawn:/sbin/getty ttyS0 38400 xterm -n -l /bin/sh diff --git a/buildroot-v86/board/v86/rootfs_overlay/etc/motd b/buildroot-v86/board/v86/rootfs_overlay/etc/motd index 8ed4fc0..b4a6ca8 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/etc/motd +++ b/buildroot-v86/board/v86/rootfs_overlay/etc/motd @@ -7,10 +7,15 @@  . . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . .  ▬▬▬▬ https://xrsh.isvery.ninja ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ - Open, local-first, unix hackable & selfcontained XR apps. + Open, local-first, polyglot, unix hackable & selfcontained XR apps. credits: NLnet | @nlnet@nlnet.nl https://nlnet.nl/project all FOSS devs | copy.sh (v86) aframe.io (AFRAME) Leon van Kammen | @lvk@mastodon.online Fabien Benetou | @utopiah@mastodon.pirateparty.be + + Please hook up your (bluetooth) keyboard to use xrsh. + Use Ctrl+a+0/1/2/3/.. to switch terminals. + Use Ctrl+a+c to create a new terminal. + Happy hacking! \o/ diff --git a/buildroot-v86/board/v86/rootfs_overlay/etc/profile b/buildroot-v86/board/v86/rootfs_overlay/etc/profile index bc78fa7..79b11f1 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/etc/profile +++ b/buildroot-v86/board/v86/rootfs_overlay/etc/profile @@ -10,17 +10,23 @@ source /etc/profile.xrsh # source shell functions source /etc/profile.sh +# source user shell defaults +test -f ~/.profile && source ~/.profile + # source js functions test -f /etc/profile.js && chmod +x /etc/profile.js && /etc/profile.js | grep -v undefined +# source user js functions +test -f ~/.profile.js && chmod +x ~/.profile.js && ~/.profile.js | grep -v undefined + ## forward not-found commands to javascript (via jsh) command_not_found_handle(){ echo "[!] '$1' not found, did you mean $1(...) (javascript?)" test -n "$ONBOARDING" && echo "[i] type 'help' for handy commands" - test -n "$ONBOARDING" || help + test -n "$ONBOARDING" || help_tips } -help(){ +help_tips(){ echo "" echo 'TIPS' echo '----' @@ -34,13 +40,16 @@ help(){ echo 'include file into page' "type 'require '" echo 'create AFRAME a-entity' "type 'a_entity [...]" echo '' - echo 'type "man xrsh" to read the full manual' + echo 'type "help" or "man xrsh" to read the full manual' ONBOARDING=1 } export TERM=xterm-256color export PS1="\[\033[38;5;165m\]> \[\033[0m\]" +# aliases +alias ls='ls -ha -w100' + # interactive login [[ -t 0 ]] && { test -n "$STY" || { @@ -49,7 +58,7 @@ export PS1="\[\033[38;5;165m\]> \[\033[0m\]" # add URL-hash as extra screen session test -z "$HASH" || { grep 'screen -t #' /root/.screenrc || { - echo "screen -t xrsh+URL 2 /bin/sh -c '${HASH}; sh'" | sed "s/'#/'/g" >> /root/.screenrc + echo "screen -t xrsh+URL 3 /bin/sh -c '${HASH}; sh'" | sed "s/'#/'/g" >> /root/.screenrc } } screen -Aa -R -T screen-256color -c /root/.screenrc diff --git a/buildroot-v86/board/v86/rootfs_overlay/etc/profile.js b/buildroot-v86/board/v86/rootfs_overlay/etc/profile.js index 794b8ca..db876aa 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/etc/profile.js +++ b/buildroot-v86/board/v86/rootfs_overlay/etc/profile.js @@ -1,6 +1,18 @@ #!/bin/js -window.helloworld = function(){ - alert("hello world") - return "hello world" +// do once (remember /etc/profile gets sources multiple times!) +if( !window['/etc/profile.js'] ){ + + const isoterminal = document.querySelector('[isoterminal]').components.isoterminal.isoterminal + const scene = document.querySelector('a-scene') + + + // map AFRAME events to ~/hook.d/{event}/* triggers + events = ['enter-ar','enter-vr','exit-vr','exit-ar'] + events.map( (event) => { + scene.addEventListener( event, (e) => isoterminal.exec("hook "+event) ) + }) + + window['/etc/profile.js'] = true } + diff --git a/buildroot-v86/board/v86/rootfs_overlay/etc/profile.sh b/buildroot-v86/board/v86/rootfs_overlay/etc/profile.sh index eded036..9f3fb88 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/etc/profile.sh +++ b/buildroot-v86/board/v86/rootfs_overlay/etc/profile.sh @@ -51,13 +51,10 @@ man(){ cat /root/manual.md | less } } +help(){ man xrsh; } -a_entity(){ - code="let el = document.createElement('a-entity')" - for i in "$@"; do - code="$code;\nel.setAttribute('$i','')\n"; +infinite(){ + while sleep 1s; do + "$@" done - code="document.querySelector('a-scene').appendChild(el)" - echo "$code" - js "$code" } diff --git a/buildroot-v86/board/v86/rootfs_overlay/etc/profile.xrsh b/buildroot-v86/board/v86/rootfs_overlay/etc/profile.xrsh index 2dc92d8..885d007 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/etc/profile.xrsh +++ b/buildroot-v86/board/v86/rootfs_overlay/etc/profile.xrsh @@ -3,13 +3,8 @@ test -d /dev/browser || { setup_links(){ - ln -fs /etc/profile ~/.profile - ln -fs /etc/profile.js ~/.profile.js - ln -fs /etc/profile.sh ~/.profile.sh ln -fs /etc/motd ~/.motd ln -fs /mnt/profile.browser ~/.profile.browser - ln -fs ~/.profile.js ~/index.js - ln -fs /dev/browser/index.html ~/index.html chmod +x ~/.profile.js } @@ -18,9 +13,10 @@ test -d /dev/browser || { echo 1 > /mnt/console.tty ln -s /mnt/console.tty /dev/browser/tty ln -fs /mnt/js /dev/browser/js + ln -fs /mnt/index.html /dev/browser/html ln -fs /mnt/console /dev/browser/console touch /mnt/console - touch /dev/browser/index.html + touch /mnt/index.html } setup_network(){ @@ -34,9 +30,28 @@ test -d /dev/browser || { test -f /mnt/overlayfs.zip && unzip /mnt/overlayfs.zip -d / } + setup_incoming_cmds(){ + # listen for shell cmds passed to v86 from browser + # (via isoterminal.exec(...)) + stty raw < /dev/ttyS1 + cat /dev/ttyS1 | xargs -I{} /bin/sh -c 'source /etc/profile; logger "isoterminal.exec({})"; {}' + } + + setup_reflect_index_html(){ + # listen for writes to index.html and send them to DOM + inotifyd echo /root/index.html | awk '/^w / { system("cat "$2" | grep -vE \"^#!\" > /dev/browser/html") }' + } + + setup_reflect_index_js(){ + # listen for writes to index.js and send them to DOM + inotifyd echo /root/index.js | awk '/^w / { system("cat "$2" | grep -vE \"^#!\" > /dev/browser/js") }' + } + setup_browser_dev setup_links setup_network setup_overlayfs - + setup_incoming_cmds & + setup_reflect_index_html & + setup_reflect_index_js & } diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/.ash_history b/buildroot-v86/board/v86/rootfs_overlay/root/.ash_history new file mode 100644 index 0000000..1359231 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/.ash_history @@ -0,0 +1,10 @@ +help +echo $BROWSER +js 'alert("hello")' +jsh alert hello +jsh +enterVR +enterAR +exitVR +exitAR +tail -n1 -f /dev/browser/console /var/log/messages diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/.profile b/buildroot-v86/board/v86/rootfs_overlay/root/.profile new file mode 100644 index 0000000..29c1b9e --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/.profile @@ -0,0 +1,15 @@ +alias enterVR='js "document.querySelector(\"a-scene\").enterVR()"' +alias enterAR='js "document.querySelector(\"a-scene\").enterAR()"' +alias exitVR='js "document.querySelector(\"a-scene\").enterVR()"' +alias exitAR='js "document.querySelector(\"a-scene\").enterAR()"' + +# (new)user friendlyness +alias vi='echo "HINT: type :q (and press enter) to quit";read;vi'; +alias mg='echo "HINT: type Ctrl+c Ctrl-x to quit";read;me'; +alias nano='echo "HINT: type Ctrl+x to quit" ;read;nano'; + +# start index.js +test -f index.js && chmod +x index.js && ./index.js + +# start index.html +test -f index.html && chmod +x index.html && ./index.html diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/.profile.js b/buildroot-v86/board/v86/rootfs_overlay/root/.profile.js new file mode 100644 index 0000000..faa9d42 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/.profile.js @@ -0,0 +1,15 @@ +#!/bin/js + +if( !window['~/.profile.js'] ){ // do once (remember /etc/profile gets sources multiple times!) + + const isoterminal = document.querySelector('[isoterminal]').components.isoterminal.isoterminal + const scene = document.querySelector('a-scene') + + window.helloworld = function(){ + alert("hello world") + return "hello world" + } + + window['~/.profile.js'] = true +} + diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/.screenrc b/buildroot-v86/board/v86/rootfs_overlay/root/.screenrc index 1a7ce45..3dc4ae9 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/root/.screenrc +++ b/buildroot-v86/board/v86/rootfs_overlay/root/.screenrc @@ -33,5 +33,6 @@ term xterm-256color defbce on # use current bg color for erased chars # setup windows -screen -t jsconsole 0 tail -f /dev/browser/console -screen -t xrsh 1 +screen -t manual 0 /bin/sh -c '/bin/infinite help' +screen -t logs 1 /bin/sh -c '/bin/infinite tail -n1 -f /dev/browser/console /var/log/messages' +screen -t xrsh 2 diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-ar/yo b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-ar/yo new file mode 100755 index 0000000..f2ea14f --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-ar/yo @@ -0,0 +1,2 @@ +#!/bin/sh +logger "$0: AFRAME fired enter-ar event" diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-vr/yo b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-vr/yo new file mode 100755 index 0000000..ea33287 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/enter-vr/yo @@ -0,0 +1,2 @@ +#!/bin/sh +logger "$0: AFRAME fired enter-vr event" diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-ar/yo b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-ar/yo new file mode 100755 index 0000000..d48c5ed --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-ar/yo @@ -0,0 +1,2 @@ +#!/bin/sh +logger "$0 AFRAME fired exit-ar event" diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-vr/yo b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-vr/yo new file mode 100755 index 0000000..6f032ca --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/hook.d/exit-vr/yo @@ -0,0 +1,2 @@ +#!/bin/sh +logger "$0: AFRAME fired exit-vr event" diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/index.html b/buildroot-v86/board/v86/rootfs_overlay/root/index.html new file mode 100755 index 0000000..f904142 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/index.html @@ -0,0 +1,5 @@ +#!/bin/html + + + + diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/index.js b/buildroot-v86/board/v86/rootfs_overlay/root/index.js new file mode 100755 index 0000000..4bbd223 --- /dev/null +++ b/buildroot-v86/board/v86/rootfs_overlay/root/index.js @@ -0,0 +1,2 @@ +#!/bin/js +console.log("/root/index.js: hello world") diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/manual.md b/buildroot-v86/board/v86/rootfs_overlay/root/manual.md index b546ed5..96c3342 100644 --- a/buildroot-v86/board/v86/rootfs_overlay/root/manual.md +++ b/buildroot-v86/board/v86/rootfs_overlay/root/manual.md @@ -1,6 +1,98 @@ XRSH Manual =========== + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + . . ____ _____________ ________. ._. ._. . . . . . . . . + . . _\ \/ /\______ \/ _____// | \. . . . . . . . + . . _ \ / | _/\_____ \/ ~ \ . . . . . . . + _ _ / \ | | \/ \ Y / _ _ _ _ _ _ _ + . . /___/\ \ |____|_ /_______ /\___|_ /. . . . . . . . + . . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . . + ▬▬▬▬ https://xrsh.isvery.ninja ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ + + Open, local-first, polyglot, unix hackable & selfcontained XR apps. + Using worlds first WebXR linux distro. + + credits: NLnet | @nlnet@nlnet.nl https://nlnet.nl/project + all FOSS devs | copy.sh (v86) aframe.io (AFRAME) + Leon van Kammen | @lvk@mastodon.online + Fabien Benetou | @utopiah@mastodon.pirateparty.be + +# Getting started + +Please hook up your (bluetooth) keyboard to use xrsh. + +> tip use ctrl+a+0/1/2/3/.. to switch (GNU) screen terminals (and ctrl+a+c to create new ones) + +| usecase | command | +|-----------------------|--------------------------------------------------------| +| js run | js 'alert("hello")' | +| js console.log: | console document.baseURI | +| js inspect: | js "return document.baseURI" | + +# Polyglot environment + +Currently the following languages are supported: + +* shellscript (busybox sh) +* awk (busybox awk v1.33.0) +* python (micropython) +* javascript (via your browser) +* lua (5.3.6) + +> TIP: type `ls -la ~/hook.d/alert/*` for examples + +# Editors + +* vi (busybox vi) +* nano (busybox nano) +* mg (microemacs) + +# Boot sequence + +The following files are loaded during boot (via `/etc/profile`) + +| file | info | +|-----------------------|---------------------------------------------------| +| /etc/profile.xrsh | sets up xrsh environment | +| /etc/profile.sh | global shellscript functions | +| /etc/profile.js | global javascript functions | +| /mnt/profile.browser | environment vars set by browser (`echo $HOSTNAME`)| +| /root/.profile | user shellscript functions/settings | +| /root/.profile.js | user javascript functions | +| /root/.screenrc | GNU screen initialisations | +| https://.../#ls | URI fragment is executed as command in own screen | + +> TIP: to keep things portable with future versions of XRSH: modify files in `/root/*` + +# Calling terminal from javascript + +```javascript +const term = document.querySelector('[isoterminal]').components.isoterminal.isoterminal +term.exec("ls -la") +``` + +# Calling javascript from terminal + +Various options: + +1. Just add the `#!/bin/js` shebang to the top of a javascript file (+ chmod +x) +2. Run `js "alert('hello')"` in the shell +3. Run `jsh alert hello` in the shell +4. Run `jsh` to start an interactive shell + +# Hybrid Terminal/Browser Events + +Events are automatically triggering scripts in `/root/hook.d/{eventname}/*` + +> They can be triggered by the following ways + +1. from shellscript: `hook myevent` (will trigger **executable** files in /root/hook.d/myevent) +2. from javascript: `isoterminal.exec("hook myevent")` (idem) +3. via jsh: `jsh alert hello` (will trigger **executable** files in /root/hook.d/alert) + +These are various ways to enable hybrid eventing between browser and terminal (languages). + # Multiple terminals [GNU screen] ## From the cmdline diff --git a/buildroot-v86/board/v86/rootfs_overlay/root/manual.txt b/buildroot-v86/board/v86/rootfs_overlay/root/manual.txt deleted file mode 100644 index 1e0ca6a..0000000 --- a/buildroot-v86/board/v86/rootfs_overlay/root/manual.txt +++ /dev/null @@ -1 +0,0 @@ -#