Compare commits
No commits in common. "main" and "feat/webworker" have entirely different histories.
main
...
feat/webwo
|
@ -1,4 +1,4 @@
|
||||||
# XRSH ISO
|
# Browser VM
|
||||||
|
|
||||||
A custom [Buildroot](https://buildroot.org/) config for a Linux x86 VM, meant to
|
A custom [Buildroot](https://buildroot.org/) config for a Linux x86 VM, meant to
|
||||||
be run in the browser as part of [XRSH](https://xrsh.isvery.ninja)
|
be run in the browser as part of [XRSH](https://xrsh.isvery.ninja)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Busybox version: 1.33.0
|
# Busybox version: 1.33.0
|
||||||
# Mon Oct 14 15:09:24 2024
|
# Wed Oct 2 12:49:15 2024
|
||||||
#
|
#
|
||||||
CONFIG_HAVE_DOT_CONFIG=y
|
CONFIG_HAVE_DOT_CONFIG=y
|
||||||
|
|
||||||
|
@ -1129,41 +1129,41 @@ CONFIG_ASH_GETOPTS=y
|
||||||
CONFIG_ASH_CMDCMD=y
|
CONFIG_ASH_CMDCMD=y
|
||||||
# CONFIG_CTTYHACK is not set
|
# CONFIG_CTTYHACK is not set
|
||||||
# CONFIG_HUSH is not set
|
# CONFIG_HUSH is not set
|
||||||
# CONFIG_SHELL_HUSH is not set
|
CONFIG_SHELL_HUSH=y
|
||||||
# CONFIG_HUSH_BASH_COMPAT is not set
|
CONFIG_HUSH_BASH_COMPAT=y
|
||||||
# CONFIG_HUSH_BRACE_EXPANSION is not set
|
CONFIG_HUSH_BRACE_EXPANSION=y
|
||||||
# CONFIG_HUSH_LINENO_VAR is not set
|
CONFIG_HUSH_LINENO_VAR=y
|
||||||
# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set
|
# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set
|
||||||
# CONFIG_HUSH_INTERACTIVE is not set
|
CONFIG_HUSH_INTERACTIVE=y
|
||||||
# CONFIG_HUSH_SAVEHISTORY is not set
|
CONFIG_HUSH_SAVEHISTORY=y
|
||||||
# CONFIG_HUSH_JOB is not set
|
CONFIG_HUSH_JOB=y
|
||||||
# CONFIG_HUSH_TICK is not set
|
CONFIG_HUSH_TICK=y
|
||||||
# CONFIG_HUSH_IF is not set
|
CONFIG_HUSH_IF=y
|
||||||
# CONFIG_HUSH_LOOPS is not set
|
CONFIG_HUSH_LOOPS=y
|
||||||
# CONFIG_HUSH_CASE is not set
|
CONFIG_HUSH_CASE=y
|
||||||
# CONFIG_HUSH_FUNCTIONS is not set
|
CONFIG_HUSH_FUNCTIONS=y
|
||||||
# CONFIG_HUSH_LOCAL is not set
|
CONFIG_HUSH_LOCAL=y
|
||||||
# CONFIG_HUSH_RANDOM_SUPPORT is not set
|
CONFIG_HUSH_RANDOM_SUPPORT=y
|
||||||
# CONFIG_HUSH_MODE_X is not set
|
CONFIG_HUSH_MODE_X=y
|
||||||
# CONFIG_HUSH_ECHO is not set
|
CONFIG_HUSH_ECHO=y
|
||||||
# CONFIG_HUSH_PRINTF is not set
|
CONFIG_HUSH_PRINTF=y
|
||||||
# CONFIG_HUSH_TEST is not set
|
CONFIG_HUSH_TEST=y
|
||||||
# CONFIG_HUSH_HELP is not set
|
CONFIG_HUSH_HELP=y
|
||||||
# CONFIG_HUSH_EXPORT is not set
|
CONFIG_HUSH_EXPORT=y
|
||||||
# CONFIG_HUSH_EXPORT_N is not set
|
CONFIG_HUSH_EXPORT_N=y
|
||||||
# CONFIG_HUSH_READONLY is not set
|
CONFIG_HUSH_READONLY=y
|
||||||
# CONFIG_HUSH_KILL is not set
|
CONFIG_HUSH_KILL=y
|
||||||
# CONFIG_HUSH_WAIT is not set
|
CONFIG_HUSH_WAIT=y
|
||||||
# CONFIG_HUSH_COMMAND is not set
|
CONFIG_HUSH_COMMAND=y
|
||||||
# CONFIG_HUSH_TRAP is not set
|
CONFIG_HUSH_TRAP=y
|
||||||
# CONFIG_HUSH_TYPE is not set
|
CONFIG_HUSH_TYPE=y
|
||||||
# CONFIG_HUSH_TIMES is not set
|
CONFIG_HUSH_TIMES=y
|
||||||
# CONFIG_HUSH_READ is not set
|
CONFIG_HUSH_READ=y
|
||||||
# CONFIG_HUSH_SET is not set
|
CONFIG_HUSH_SET=y
|
||||||
# CONFIG_HUSH_UNSET is not set
|
CONFIG_HUSH_UNSET=y
|
||||||
# CONFIG_HUSH_ULIMIT is not set
|
CONFIG_HUSH_ULIMIT=y
|
||||||
# CONFIG_HUSH_UMASK is not set
|
CONFIG_HUSH_UMASK=y
|
||||||
# CONFIG_HUSH_GETOPTS is not set
|
CONFIG_HUSH_GETOPTS=y
|
||||||
# CONFIG_HUSH_MEMLEAK is not set
|
# CONFIG_HUSH_MEMLEAK is not set
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1194,6 +1194,6 @@ CONFIG_FEATURE_REMOTE_LOG=y
|
||||||
# CONFIG_FEATURE_SYSLOGD_CFG is not set
|
# CONFIG_FEATURE_SYSLOGD_CFG is not set
|
||||||
# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set
|
# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set
|
||||||
CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
|
CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
|
||||||
# CONFIG_FEATURE_IPC_SYSLOG is not set
|
CONFIG_FEATURE_IPC_SYSLOG=y
|
||||||
CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0
|
CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
|
||||||
# CONFIG_FEATURE_KMSG_SYSLOG is not set
|
# CONFIG_FEATURE_KMSG_SYSLOG is not set
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/awk awk -f
|
#!/usr/bin/env -S awk -f
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ OUTPUT=/mnt/run/$PID # com/isoterminal/feat/javascript.js writes output here
|
||||||
touch $OUTPUT
|
touch $OUTPUT
|
||||||
echo -n "PID=$PID; $javascript" > /dev/browser/js
|
echo -n "PID=$PID; $javascript" > /dev/browser/js
|
||||||
# todo watch file
|
# todo watch file
|
||||||
sleep 0.1
|
|
||||||
cat $OUTPUT
|
cat $OUTPUT
|
||||||
rm $OUTPUT
|
rm $OUTPUT
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,23 @@
|
||||||
Welcome to XRSH
|
|
||||||
|
[38;5;93m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||||
|
[38;5;57m . . ____ _____________ ________. ._. ._. . . . . . . . .
|
||||||
|
[38;5;93m . . _\ \/ /\______ \/ _____// | \. . . . . . . .
|
||||||
|
[38;5;93m . . _ \ / | _/\_____ \/ ~ \ . . . . . . .
|
||||||
|
[38;5;129m _ _ / \ | | \/ \ Y / _ _ _ _ _ _ _
|
||||||
|
[38;5;165m . . /___/\ \ |____|_ /_______ /\___|_ /. . . . . . . .
|
||||||
|
[38;5;201m . . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . .
|
||||||
|
[38;5;165m ▬▬▬▬ https://xrsh.isvery.ninja ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
|
||||||
|
|
||||||
|
[38;5;165mOpen, 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.
|
Please hook up your (bluetooth) keyboard to use xrsh.
|
||||||
Use [38;5;129mCtrl+a+0/1/2/3/..[38;5;165m to switch terminals.
|
Use [38;5;129mCtrl+a+0/1/2/3/..[38;5;165m to switch terminals.
|
||||||
Use [38;5;129mCtrl+a+c[38;5;165m to create a new terminal.
|
Use [38;5;129mCtrl+a+c[38;5;165m to create a new terminal.
|
||||||
Type [38;5;129m'save'[38;5;165m to save session (survives tab-close)
|
Use [38;5;129m'save'[38;5;165m to save session (survives tab-close)
|
||||||
Type [38;5;129m'help_tips'[38;5;165m for tips
|
|
||||||
Happy hacking! \o/
|
Happy hacking! \o/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
export HOME=/root
|
export HOME=/root
|
||||||
export PATH=~/bin:$PATH:/etc
|
export PATH=$PATH:/etc:~/bin
|
||||||
|
|
||||||
# source URL data from v86 (file created by v86 during boot)
|
# source URL data from v86 (file created by v86 during boot)
|
||||||
test -f /mnt/profile.browser && source /mnt/profile.browser
|
test -f /mnt/profile.browser && source /mnt/profile.browser
|
||||||
|
@ -33,16 +33,13 @@ help_tips(){
|
||||||
echo 'text editors ' "type '<vi|mg|nano> <textfile>'"
|
echo 'text editors ' "type '<vi|mg|nano> <textfile>'"
|
||||||
echo 'programming languages ' "type 'ls ~/bin/helloworld*'"
|
echo 'programming languages ' "type 'ls ~/bin/helloworld*'"
|
||||||
echo 'run 64bit linux app ' "type 'blink <x86_64 binary>'"
|
echo 'run 64bit linux app ' "type 'blink <x86_64 binary>'"
|
||||||
echo 'paste text ' "ctrl/cmd+shift+v'"
|
|
||||||
echo 'paste text to file ' "ctrl/cmd+v'"
|
|
||||||
echo 'import file to scene ' "drag-drop or ctrl/cmd+v'"
|
|
||||||
echo 'reset scene & shell ' "type 'reset'"
|
|
||||||
echo 'js run ' "type 'js 'alert(\"hello\")'"
|
echo 'js run ' "type 'js 'alert(\"hello\")'"
|
||||||
echo 'js console.log: ' "type 'console document.baseURI"
|
echo 'js console.log: ' "type 'console document.baseURI"
|
||||||
echo 'js function as cmd: ' "type 'alias $1=\"jsh $1\"' to run '$1 yo' as $1('yo')"
|
echo 'js function as cmd: ' "type 'alias $1=\"jsh $1\"' to run '$1 yo' as $1('yo')"
|
||||||
echo 'js inspect: ' "type 'js \"return document.baseURI\"'"
|
echo 'js inspect: ' "type 'js \"return document.baseURI\"'"
|
||||||
|
echo 'js console mute: ' "type 'echo 0 > /dev/browser/tty' to disable"
|
||||||
echo 'js capture console: ' "type 'tail -f /dev/browser/console'"
|
echo 'js capture console: ' "type 'tail -f /dev/browser/console'"
|
||||||
echo 'js<->filesystem hooks:' "type 'see [executable] files in ~/hook.d'"
|
echo 'jsh<->sh hooks: ' "type 'chmod +x ~/hook.d/*/* && alert helloworld'"
|
||||||
echo 'include file into page' "type 'require <url.js|css>'"
|
echo 'include file into page' "type 'require <url.js|css>'"
|
||||||
echo ''
|
echo ''
|
||||||
echo 'type "help" or "man xrsh" to read the full manual'
|
echo 'type "help" or "man xrsh" to read the full manual'
|
||||||
|
@ -50,7 +47,7 @@ help_tips(){
|
||||||
}
|
}
|
||||||
|
|
||||||
export TERM=xterm-256color
|
export TERM=xterm-256color
|
||||||
export PS1="\[\e[36m\]> \[\e\[0m\]"
|
export PS1="\[\033[38;5;165m\]> \[\033[0m\]"
|
||||||
|
|
||||||
# aliases
|
# aliases
|
||||||
alias ls='ls -ha -w100'
|
alias ls='ls -ha -w100'
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// do once (remember /etc/profile gets sources multiple times!)
|
// do once (remember /etc/profile gets sources multiple times!)
|
||||||
if( !window['/etc/profile.js'] ){
|
if( !window['/etc/profile.js'] ){
|
||||||
|
|
||||||
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal.term
|
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal.isoterminal
|
||||||
const scene = document.querySelector('a-scene')
|
const scene = document.querySelector('a-scene')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
hook(){
|
hook(){
|
||||||
test -z "$1" && { echo "usage: hook <cmd_or_jsfunction> [args]"; return 0; }
|
test -z "$1" && { echo "usage: hook <cmd_or_jsfunction> [args]"; return 0; }
|
||||||
logger "$ hook $*"
|
|
||||||
cmd=$1
|
cmd=$1
|
||||||
shift
|
shift
|
||||||
test -d ~/hook.d/$cmd && {
|
test -d ~/hook.d/$cmd && {
|
||||||
find -L ~/hook.d/$cmd/ -type f -executable -maxdepth 1 | while read hook; do
|
find ~/hook.d/$cmd/ -type f -executable | while read hook; do
|
||||||
logger " |+ hook $hook $*"
|
|
||||||
{ $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
|
{ $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
|
||||||
done
|
done
|
||||||
} &> ~/hook.d/log.txt
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alert(){
|
alert(){
|
||||||
|
@ -22,11 +20,7 @@ alert(){
|
||||||
|
|
||||||
confirm(){
|
confirm(){
|
||||||
test -z "$1" && { echo "usage: confirm <question>"; return 0; }
|
test -z "$1" && { echo "usage: confirm <question>"; return 0; }
|
||||||
if test -n "$BROWSER"; then
|
|
||||||
jsh confirm "$1"
|
|
||||||
else
|
|
||||||
read -p "$(printf "\033[0m")[?] [38;5;165m$1 [y/n] $(printf "\033[0m")" y
|
read -p "$(printf "\033[0m")[?] [38;5;165m$1 [y/n] $(printf "\033[0m")" y
|
||||||
fi
|
|
||||||
test $y = y && echo true && return 0
|
test $y = y && echo true && return 0
|
||||||
test $y = y || echo false
|
test $y = y || echo false
|
||||||
hook confirm $1 $y
|
hook confirm $1 $y
|
||||||
|
@ -35,11 +29,7 @@ confirm(){
|
||||||
prompt(){
|
prompt(){
|
||||||
test -z "$1" && { echo "usage: prompt <question> [answer_default]"; return 0; }
|
test -z "$1" && { echo "usage: prompt <question> [answer_default]"; return 0; }
|
||||||
test -n "$2" && answer="[$2] " && answer_fallback="$2"
|
test -n "$2" && answer="[$2] " && answer_fallback="$2"
|
||||||
if test -n "$BROWSER"; then
|
|
||||||
jsh prompt "$1" "$answer_fallback"
|
|
||||||
else
|
|
||||||
read -p "$(printf "\033[0m")[?] [38;5;165m$1: $answer $(printf "\033[0m")" answer
|
read -p "$(printf "\033[0m")[?] [38;5;165m$1: $answer $(printf "\033[0m")" answer
|
||||||
fi
|
|
||||||
test -z "$answer" && answer="$answer_fallback"
|
test -z "$answer" && answer="$answer_fallback"
|
||||||
echo "$answer"
|
echo "$answer"
|
||||||
hook prompt $1 $answer
|
hook prompt $1 $answer
|
||||||
|
@ -71,14 +61,6 @@ require(){
|
||||||
echo "<a-entity xrf='$1'></a-entity>" >> /root/index.html
|
echo "<a-entity xrf='$1'></a-entity>" >> /root/index.html
|
||||||
;;
|
;;
|
||||||
|
|
||||||
sh)
|
|
||||||
js '
|
|
||||||
fetch('$1')
|
|
||||||
.then( (res) => res.text() )
|
|
||||||
.then( (text) => console.log(text) )
|
|
||||||
'
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
*)
|
||||||
alert $ext "extension is not supported (yet)"
|
alert $ext "extension is not supported (yet)"
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -9,13 +9,6 @@ test -d /dev/browser || {
|
||||||
ln -fs /mnt/root /root
|
ln -fs /mnt/root /root
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_clipboard(){
|
|
||||||
test -d /mnt/clipboard || {
|
|
||||||
mkdir /mnt/clipboard
|
|
||||||
echo "files appear here when dragdropping- or copy/pasting a file into the 3D scene (minimize in non-immersive mode)" > /mnt/clipboard/README.md
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_links(){
|
setup_links(){
|
||||||
ln -fs /etc/motd ~/.motd
|
ln -fs /etc/motd ~/.motd
|
||||||
ln -fs /mnt/profile.browser ~/.profile.browser
|
ln -fs /mnt/profile.browser ~/.profile.browser
|
||||||
|
@ -45,22 +38,29 @@ test -d /dev/browser || {
|
||||||
# listen for shell cmds passed to v86 from browser
|
# listen for shell cmds passed to v86 from browser
|
||||||
# (via isoterminal.exec(...))
|
# (via isoterminal.exec(...))
|
||||||
stty raw < /dev/ttyS1
|
stty raw < /dev/ttyS1
|
||||||
|
#cat /dev/ttyS1 | xargs -I{} /bin/sh -c 'logger "isoterminal.exec({})"; {}'
|
||||||
mkfifo /var/run/ttyS1
|
mkfifo /var/run/ttyS1
|
||||||
|
echo "source /etc/profile" >> /var/run/ttyS1
|
||||||
cat /dev/ttyS1 > /var/run/ttyS1 &
|
cat /dev/ttyS1 > /var/run/ttyS1 &
|
||||||
/bin/sh < /var/run/ttyS1
|
/bin/sh < /var/run/ttyS1
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_listen_homedir(){
|
setup_listen_homedir(){
|
||||||
sleep 4 # wait for inode of /mnt/root to become live (due to move_root_to_9pfs)
|
sleep 4 # wait for inode of /mnt/root to become live (due to move_root_to_9pfs)
|
||||||
/mnt/root/bin/watchfs &
|
infinite inotifyd echo /mnt/root | awk '
|
||||||
|
|
||||||
|
# listen for writes to rootdir and send them to DOM
|
||||||
|
/^[we] \/mnt\/root index\.html/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/html") }
|
||||||
|
/^[we] \/mnt\/root index\.js/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/js") }
|
||||||
|
|
||||||
|
'
|
||||||
}
|
}
|
||||||
|
|
||||||
move_root_to_9pfs
|
move_root_to_9pfs
|
||||||
setup_browser_dev
|
setup_browser_dev
|
||||||
setup_clipboard
|
|
||||||
setup_links
|
setup_links
|
||||||
setup_network
|
setup_network
|
||||||
setup_overlayfs
|
setup_overlayfs
|
||||||
setup_incoming_cmds &
|
setup_incoming_cmds &
|
||||||
setup_listen_homedir
|
setup_listen_homedir &
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,4 @@ enterAR
|
||||||
exitVR
|
exitVR
|
||||||
exitAR
|
exitAR
|
||||||
tail -n1 -f /dev/browser/console /var/log/messages
|
tail -n1 -f /dev/browser/console /var/log/messages
|
||||||
require https://snips.sh/f/VBz-iWm8so?r=1
|
|
||||||
require https://xrfragment.org/example/assets/index.glb
|
|
||||||
require https://coderofsalvation.github.io/xrsh-media/assets/background.glb
|
require https://coderofsalvation.github.io/xrsh-media/assets/background.glb
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
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
|
# (new)user friendlyness
|
||||||
alias vi='echo -e "HINT: type :q (and press enter) to quit\n[press a key]";read;vi';
|
alias vi='echo "HINT: type :q (and press enter) to quit\n[press a key]";read;vi';
|
||||||
alias mg='echo -e "HINT: type Ctrl+c Ctrl-x to quit\n[press a key]";read;mg';
|
alias mg='echo "HINT: type Ctrl+c Ctrl-x to quit\n[press a key]";read;me';
|
||||||
alias nano='echo -e "HINT: type Ctrl+x to quit\n[press a key]" ;read;nano';
|
alias nano='echo "HINT: type Ctrl+x to quit\n[press a key]" ;read;nano';
|
||||||
|
|
||||||
# start index.js
|
# start index.js
|
||||||
test -f index.js && chmod +x index.js && ./index.js | grep -v undefined
|
test -f index.js && chmod +x index.js && ./index.js | grep -v undefined
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
test -n "$1" || { echo "usage: a-gltf-model <gltf-file>"; exit; }
|
|
||||||
|
|
||||||
file="$(readlink -f "$1")"
|
|
||||||
file="${file#/}" # strip leading slash if present
|
|
||||||
|
|
||||||
echo "<a-gltf-model src='file://xrsh/$file'></a-gltf-model>" >> /root/index.html
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
test -n "$1" || { echo "usage: a-text <textfile_or_string>"; exit; }
|
|
||||||
|
|
||||||
str="$1"
|
|
||||||
test -f "$str" && str="$(cat "$1" | sed ':a;N;$!ba;s/\n/\\n/g' )" # escape linebreaks
|
|
||||||
|
|
||||||
echo "<a-text value='${str}' position='-0.4 1.8 -3' grabbable></a-text>" >> /root/index.html
|
|
|
@ -1,25 +1,24 @@
|
||||||
#!/bin/js
|
#!/bin/js
|
||||||
|
|
||||||
if( args[1] == undefined ) return "usage: codemirror <file>"
|
(async function(){
|
||||||
|
|
||||||
AFRAME.utils.require({
|
await AFRAME.utils.require({
|
||||||
codemirrorjs: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.js",
|
codemirrorjs: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.js",
|
||||||
codemirrorcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css",
|
codemirrorcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css",
|
||||||
cmtheme: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/shadowfox.css"
|
cmtheme: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/theme/shadowfox.css"
|
||||||
})
|
})
|
||||||
.then( () => AFRAME.utils.require({
|
|
||||||
|
await AFRAME.utils.require({
|
||||||
cmxml: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/xml/xml.js",
|
cmxml: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/xml/xml.js",
|
||||||
cmjavascript: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/javascript/javascript.js",
|
cmjavascript: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/javascript/javascript.js",
|
||||||
cmcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/css/css.js",
|
cmcss: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/css/css.js",
|
||||||
highlight: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/htmlmixed/htmlmixed.js",
|
highlight: "https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/mode/htmlmixed/htmlmixed.js",
|
||||||
codemirrorAF: "com/codemirror.js"
|
codemirrorAF: "com/codemirror.js"
|
||||||
})
|
})
|
||||||
)
|
|
||||||
.then( () => {
|
document.querySelector("a-entity#root").innerHTML += `<a-entity codemirror='file: ${args[1]}'></a-entity>`
|
||||||
let el = document.createElement("a-entity")
|
|
||||||
el.setAttribute("codemirror", `file: ${args[1]}`)
|
})()
|
||||||
document.querySelector("a-scene").appendChild(el)
|
|
||||||
})
|
|
||||||
|
|
||||||
return "" // empty stdout(put)
|
return "" // empty stdout(put)
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/js
|
|
||||||
document.querySelector("a-scene").enterAR()
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/js
|
|
||||||
document.querySelector("a-scene").enterVR()
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/js
|
|
||||||
document.querySelector("a-scene").exitAR()
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/js
|
|
||||||
document.querySelector("a-scene").exitVR()
|
|
|
@ -1,2 +1,2 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
echo "$@"
|
echo hook.d/alert/yo: yo $*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/awk -f
|
#!/usr/bin/awk -f
|
||||||
BEGIN{
|
BEGIN{
|
||||||
print( ARGV[0] " " ARGV[1] " " ARGV[2] )
|
print "hook.d/alert/yo.awk: yo " ARGV[1]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/js
|
#!/bin/js
|
||||||
msg = args.join(' ')
|
str = "hook.d/alert/yo.js yo"+args.slice(1).join(' ')
|
||||||
console.log(msg)
|
alert(str)
|
||||||
//alert(msg)
|
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
#!/usr/bin/env lua
|
#!/usr/bin/env lua
|
||||||
local msg = table.concat( arg, " ")
|
print("hook.d/alert/yo.lua: yo " .. args[1])
|
||||||
print( msg ) -- to stdout
|
|
||||||
--os.execute( "logger '" .. msg .. "'") -- to logs (/var/logs/messages)
|
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
#!/usr/bin/env micropython
|
#!/usr/bin/env micropython
|
||||||
import sys
|
import sys
|
||||||
import os
|
print("hook.d/alert/yo.py: "+sys.argv[1])
|
||||||
msg = sys.argv[0] + ": " + " ".join(sys.argv)
|
|
||||||
|
|
||||||
print(msg) # to stdout
|
|
||||||
#os.system("logger '"+ msg +"'") # to logs (/var/log/messages)
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
/usr/bin/reset
|
|
||||||
set -x
|
|
||||||
echo '' > ~/index.html # empty scene
|
|
||||||
set +x
|
|
||||||
echo "[i] terminal and 3D scene are re-initialized"
|
|
|
@ -2,13 +2,12 @@
|
||||||
source /etc/profile.sh
|
source /etc/profile.sh
|
||||||
|
|
||||||
javascript='
|
javascript='
|
||||||
const isoterminal = document.querySelector("[isoterminal]").components.isoterminal.term
|
const isoterminal = document.querySelector("[isoterminal]").components.isoterminal.isoterminal
|
||||||
isoterminal.save()
|
isoterminal.save()
|
||||||
return "[OK] xrsh state saved\n"
|
return "[OK] xrsh state saved\n"
|
||||||
'
|
'
|
||||||
|
|
||||||
echo "[i] triggering ~/hook.d/save/* scripts"
|
echo "[OK] triggering ~/hook.d/save/* scripts"
|
||||||
hook save
|
hook save
|
||||||
echo "[i] warning: do not resize the browserwindow"
|
echo "[..] please wait.."
|
||||||
echo "[i] please wait.."
|
|
||||||
js "$javascript"
|
js "$javascript"
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/js
|
|
||||||
// this allows opening a file upload popup, to upload to the clipboard.
|
|
||||||
// because not all input devices (handcontrols) present copy/paste contextmenus
|
|
||||||
// or file drag/drop functionality
|
|
||||||
//
|
|
||||||
const isoterminal = document.querySelector('[isoterminal]').components.isoterminal
|
|
||||||
const upload = isoterminal.vt100.upload
|
|
||||||
const scene = document.querySelector('a-scene')
|
|
||||||
|
|
||||||
// trigger file input
|
|
||||||
scene.exitVR()
|
|
||||||
upload.click()
|
|
||||||
return "[i] files are uploaded in /mnt/clipboard\n"
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
infinite inotifyd echo /root | awk '
|
|
||||||
|
|
||||||
# listen for writes to rootdir and send them to DOM
|
|
||||||
/^[wne] \/root index\.html/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/html") }
|
|
||||||
/^[wne] \/root index\.js/ { system("cat "$2"/"$3" | grep -vE \"^#!\" > /dev/browser/js") }
|
|
||||||
|
|
||||||
'
|
|
|
@ -1 +0,0 @@
|
||||||
../../bin/helloworld.awk
|
|
|
@ -1 +0,0 @@
|
||||||
../../bin/helloworld.js
|
|
|
@ -1 +0,0 @@
|
||||||
../../bin/helloworld.lua
|
|
|
@ -1 +0,0 @@
|
||||||
../../bin/helloworld.py
|
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# usage: hook clipboard foo.mp3 [audio/mpeg]
|
|
||||||
# this forwards the hook to mimetype or filetype
|
|
||||||
source /etc/profile.sh
|
|
||||||
|
|
||||||
file="$1"
|
|
||||||
ext="${file##*.}"
|
|
||||||
mimetype="$2"
|
|
||||||
|
|
||||||
if test -n "$mimetype"; then
|
|
||||||
hook mimetype/"$mimetype" "$file"
|
|
||||||
else
|
|
||||||
hook filetype $ext "$file"
|
|
||||||
fi
|
|
|
@ -1 +0,0 @@
|
||||||
../../../bin/a-text
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e # halt on error
|
|
||||||
file="$1"
|
|
||||||
dir="$(basename "$file")"
|
|
||||||
|
|
||||||
logger "$0: extracting $file"
|
|
||||||
|
|
||||||
mkdir -p "/root/$dir"
|
|
||||||
cd "/root/$dir"
|
|
||||||
unzip "$file"
|
|
||||||
|
|
||||||
test -x app && {
|
|
||||||
logger "$0: detected $(pwd)/app executable"
|
|
||||||
logger "$0: running $(pwd)/app"
|
|
||||||
./app
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../../filetype/mp3
|
|
|
@ -1 +0,0 @@
|
||||||
../../../../bin/a-gltf-model
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# usage: import-to-aframe <textfile>
|
|
||||||
|
|
||||||
# *FIXME* need consent
|
|
||||||
cat "$1" >> /root/index.html
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
source /etc/profile.sh
|
|
||||||
file="$1"
|
|
||||||
|
|
||||||
# naive javascript detector
|
|
||||||
grep '<a-' "$file" &> /dev/null && {
|
|
||||||
cat "$file" | grep -vE '(<script|iframe)' &> "$file".aframe
|
|
||||||
hook mimetype/text/aframe "$file".aframe
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
source /etc/profile.sh
|
|
||||||
file="$1"
|
|
||||||
|
|
||||||
# naive html detector
|
|
||||||
grep -E '(<\/a>|<\/div>)' "$file" &> /dev/null && {
|
|
||||||
hook mimetype/text/html "$file"
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
source /etc/profile.sh
|
|
||||||
file="$1"
|
|
||||||
|
|
||||||
# naive javascript detector
|
|
||||||
grep -E '[a-zA-Z]\(' "$file" &> /dev/null && {
|
|
||||||
hook mimetype/text/javascript "$file"
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# warning: to activate below make this file executable at own risk
|
|
||||||
|
|
||||||
cat $1 | grep -vE "(<script|<iframe)" >> /root/index.html
|
|
|
@ -1 +0,0 @@
|
||||||
plain/import-to-aframe
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# warning: to activate below make this file executable at own risk
|
|
||||||
|
|
||||||
js "$(cat $1)"
|
|
|
@ -1 +0,0 @@
|
||||||
../../filetype/txt
|
|
|
@ -1 +0,0 @@
|
||||||
../../filetype/mp4
|
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# intialize global funcs
|
|
||||||
/root/index.js &> /dev/null
|
|
||||||
|
|
||||||
# initialize scene
|
|
||||||
/root/index.html &> /dev/null
|
|
||||||
|
|
|
@ -2,12 +2,4 @@
|
||||||
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
|
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
|
||||||
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
|
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
|
||||||
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
|
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
|
||||||
<a-plane position="0 0.05 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
|
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
|
||||||
|
|
||||||
<!--
|
|
||||||
<a-box position="0 1.4 -0.5" scale="0.2 0.2 0.2" color="#FF00AA" grabbable></a-box>
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- for [lowerlevel] THREE.js code see ~/index.js -->
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,2 @@
|
||||||
#!/bin/js
|
#!/bin/js
|
||||||
console.log("/root/index.js: hello world")
|
console.log("/root/index.js: hello world")
|
||||||
|
|
||||||
function doTHREE(){
|
|
||||||
const scene = AFRAME.scenes[0]
|
|
||||||
const object = new THREE.Mesh(
|
|
||||||
new THREE.BoxGeometry(1, 1, 1),
|
|
||||||
new THREE.MeshBasicMaterial({ color: 0xff0000 })
|
|
||||||
);
|
|
||||||
object.position.set(0.3, 1.4, -0.4)
|
|
||||||
object.scale.set(0.2,0.2,0.2)
|
|
||||||
scene.add(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
//doTHREE()
|
|
||||||
|
|
||||||
// for [higherlevel] AFRAME markup see ~/index.html
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
XRSH Manual
|
XRSH Manual
|
||||||
===========
|
===========
|
||||||
|
|
||||||
```
|
|
||||||
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||||
. . ____ _____________ ________. ._. ._. . . . . . . . .
|
. . ____ _____________ ________. ._. ._. . . . . . . . .
|
||||||
. . _\ \/ /\______ \/ _____// | \. . . . . . . .
|
. . _\ \/ /\______ \/ _____// | \. . . . . . . .
|
||||||
|
@ -9,7 +8,7 @@ XRSH Manual
|
||||||
_ _ / \ | | \/ \ Y / _ _ _ _ _ _ _
|
_ _ / \ | | \/ \ Y / _ _ _ _ _ _ _
|
||||||
. . /___/\ \ |____|_ /_______ /\___|_ /. . . . . . . .
|
. . /___/\ \ |____|_ /_______ /\___|_ /. . . . . . . .
|
||||||
. . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . .
|
. . . . . .\_/. . . . \/ . . . .\/ . . _ \/ . . . . . . . .
|
||||||
================ https://xrsh.isvery.ninja ================
|
▬▬▬▬ https://xrsh.isvery.ninja ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬
|
||||||
|
|
||||||
Open, local-first, polyglot, unix hackable & selfcontained XR apps.
|
Open, local-first, polyglot, unix hackable & selfcontained XR apps.
|
||||||
Using worlds first WebXR linux distro.
|
Using worlds first WebXR linux distro.
|
||||||
|
@ -18,7 +17,6 @@ XRSH Manual
|
||||||
all FOSS devs | copy.sh (v86) aframe.io (AFRAME)
|
all FOSS devs | copy.sh (v86) aframe.io (AFRAME)
|
||||||
Leon van Kammen | @lvk@mastodon.online
|
Leon van Kammen | @lvk@mastodon.online
|
||||||
Fabien Benetou | @utopiah@mastodon.pirateparty.be
|
Fabien Benetou | @utopiah@mastodon.pirateparty.be
|
||||||
```
|
|
||||||
|
|
||||||
# Getting started
|
# Getting started
|
||||||
|
|
||||||
|
@ -51,6 +49,51 @@ Currently the following languages are supported:
|
||||||
* nano (busybox nano)
|
* nano (busybox nano)
|
||||||
* mg (microemacs)
|
* 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]
|
# Multiple terminals [GNU screen]
|
||||||
|
|
||||||
## From the cmdline
|
## From the cmdline
|
||||||
|
@ -87,125 +130,3 @@ ctrl a X -> remove active window from split screen
|
||||||
ctrl a O -> logout active window (disable output)
|
ctrl a O -> logout active window (disable output)
|
||||||
ctrl a I -> login active window (enable output)
|
ctrl a I -> login active window (enable output)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Importing files
|
|
||||||
|
|
||||||
Files can be imported (always to /mnt/clipboard) in various ways:
|
|
||||||
|
|
||||||
* copy-pasted text (from clipboard via ctrl/cmd+v )
|
|
||||||
* drag-dropped file ends up in /mnt/clipboard [based on ~/hook.d/mimetype/* things happen or not]
|
|
||||||
* type 'upload' to trigger a file-upload dialog [ends up in /mnt/clip
|
|
||||||
|
|
||||||
XRSH ships with hooks for importing .glb 3D files, text-files & zip-packages, all described below.
|
|
||||||
|
|
||||||
# XRSH Packages
|
|
||||||
|
|
||||||
A XRSH package is just a zip with an entrypoint, which gets extracted to /root/{zipname} that's it!
|
|
||||||
|
|
||||||
It can be loaded in various ways into [your own instance of] https://xrsh.isvery.ninja:
|
|
||||||
|
|
||||||
* copy the zip in a filemanager to your clipboard, and paste it into your XRSH-tab
|
|
||||||
* drag-drop the zip from a filemanager to your XRSH-tab
|
|
||||||
* download the zip, and type 'upload' in XRSH to import it
|
|
||||||
|
|
||||||
Currently, 'app' links to 'bin/app.sh', but there are also other scriptinglanguages it could link to as well (see bin-folder).
|
|
||||||
|
|
||||||
> see example package at https://xrsh.isvery.ninja/package.zip
|
|
||||||
|
|
||||||
# Hooks
|
|
||||||
|
|
||||||
Hooks are filebased events.
|
|
||||||
Why filebased? Well first, because unixy is sexy.
|
|
||||||
Second: it allows reacting to events in a hackable way via polyglot scripts.
|
|
||||||
|
|
||||||
> TLDR: events are automatically triggering scripts found in `/root/hook.d/{eventname}/*`
|
|
||||||
|
|
||||||
**OS related hooks**
|
|
||||||
|
|
||||||
| hook location | when is this hook called? |
|
|
||||||
|-------------------------|-------------------------------------------------------|
|
|
||||||
| hook.d/wakeup/* | restoring xrsh session from cache |
|
|
||||||
| hook.d/save/* | saving xrsh session to cache |
|
|
||||||
| hook.d/alert/* | when 'alert'-function is used in shell |
|
|
||||||
| hook.d/prompt/* | when 'prompt'-function is used in shell |
|
|
||||||
| hook.d/confirm/* | when 'confirm'-function is used in shell |
|
|
||||||
|
|
||||||
**Clipboard related hooks**
|
|
||||||
|
|
||||||
| hook.d/clipboard/* | user copy-pastes clipboard or (drops) file into scene |
|
|
||||||
| hook.d/mimetype/* | clipboard activity (hook.d/clipboard/forwarder) |
|
|
||||||
| hook.d/filetype/* | clipboard activity (hook.d/clipboard/forwarder) |
|
|
||||||
|
|
||||||
**XR related hooks**
|
|
||||||
|
|
||||||
| hook location | when is this hook called? |
|
|
||||||
|-------------------------|-------------------------------------------------------|
|
|
||||||
| hook.d/exit-vr/* | user exits immersive WebXR [VR] mode |
|
|
||||||
| hook.d/enter-vr/* | user enters immersive WebXR [VR] mode |
|
|
||||||
| hook.d/exit-ar/* | user exits immersive WebXR [AR] mode |
|
|
||||||
| hook.d/enter-ar/* | user enters immersive WebXR [AR] mode |
|
|
||||||
|
|
||||||
> How to trigger them?
|
|
||||||
|
|
||||||
Well the isoterminal-AFRAME component triggers them automatically for you.
|
|
||||||
But you can do it manually too:
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
|
|
||||||
## webrequests to the filesystem
|
|
||||||
|
|
||||||
Javascript webrequests can read from the filesystem via the 'file://host/path' protocol:
|
|
||||||
|
|
||||||
```
|
|
||||||
fetch("file://xrsh/mnt/profile.browser")
|
|
||||||
```
|
|
||||||
|
|
||||||
current [security] limitations:
|
|
||||||
|
|
||||||
* only /mnt directory is exposed
|
|
||||||
* file needs to be world-readable (`chmod +r /mnt/<file>`)
|
|
||||||
|
|
||||||
# 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.term
|
|
||||||
term.exec("ls -la")
|
|
||||||
|
|
||||||
// interact directly with files
|
|
||||||
await term.worker.create_file("hello.txt", term.convert.toUint8Array("hello") )
|
|
||||||
await term.worker.update_file("hello.txt", term.convert.toUint8Array("hi") )
|
|
||||||
await term.worker.append_file("hello.txt", term.convert.toUint8Array("world") )
|
|
||||||
const f = await term.worker.read_file("hello.txt")
|
|
||||||
```
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
2
edit.sh
2
edit.sh
|
@ -8,7 +8,7 @@ make menuconfig
|
||||||
test -d output/busybox-1.33.0 || mkdir -p output/busybox-1.33.0
|
test -d output/busybox-1.33.0 || mkdir -p output/busybox-1.33.0
|
||||||
cp /buildroot-v86/.config.busybox output/busybox-1.33.0/.config
|
cp /buildroot-v86/.config.busybox output/busybox-1.33.0/.config
|
||||||
make busybox-menuconfig
|
make busybox-menuconfig
|
||||||
cp output/build/busybox-1.33.0/.config /buildroot-v86/.config.busybox
|
cp output/busybox-1.33.0/.config /buildroot-v86/.config.busybox
|
||||||
|
|
||||||
make linux-menuconfig
|
make linux-menuconfig
|
||||||
make savedefconfig
|
make savedefconfig
|
||||||
|
|
Loading…
Reference in New Issue