9.3 KiB
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 |
---|---|
require | adds javascript or CSS url to DOM |
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)
Multiple terminals [GNU screen]
From the cmdline
xrsh # screen –DR # list of detached screen
xrsh # screen –r PID # attach detached screen session
xrsh # screen –dmS Myses # start a detached screen session
xrsh # screen –r MySes #attach screen session with name MySession
Basics
ctrl a c -> create new window
ctrl a A -> set window name
ctrl a w -> show all window
ctrl a 1|2|3|… -> switch to window n
ctrl a " -> choose window
ctrl a ctrl a -> switch between window
ctrl a d -> detach window
ctrl a ? -> help
ctrl a [ -> start copy, move cursor to the copy location, press ENTER, select the chars, press ENTER to copy the selected characters to the buffer
ctrl a ] -> paste from buffer
Advanced
ctrl a S -> create split screen
ctrl a TAB -> switch between split screens
ctrl a Q -> Kill all regions but the current one.
ctrl a X -> remove active window from split screen
ctrl a O -> logout active window (disable 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
The package follows the popular autoenv
-paradigm (a file called .env
is automatically executed).
Currently, '.env' 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, and an filesystem overlay-zip at https://xrsh.isvery.ninja/package.overlayfs.zip
Autoenv (.env)
When a directory contains an .env-file, it is automatically sourced.
- run echo 0 > ~/.config/autoenv/package to disable auto-execution of zip-packages
- run echo 1 > ~/.config/autoenv/prompt_cd to trigger a confirmation when cd-ing into a directory.
TIP: check out
~/bin/annotate
to annotate directories using the power of autoenv
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:
- from shellscript:
hook myevent
(will trigger executable files in /root/hook.d/myevent) - from javascript:
isoterminal.exec("hook myevent")
(idem) - 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).
Wget: downloading remote files
Internetrequests are limited to port 80 and 443 (as they are routed via javascript's fetch()):
$ wget xrsh.isvery.ninja # fetches https://xrsh.isvery.ninja (*)
$ wget http://xrsh.isvery.ninja # fetches http://xrsh.isvery.ninja
$ wget https://xrsh.isvery.ninja # does not work (*)
* = important for selfhosters: the browser cannot switch ports, therefore hostnames are considered HTTPS when the XRSH webapp is hosted via valid HTTPS certificates. Serving the XRSH webapp via http will render https impossible. XRSH.com (the standalone binary) also launches https://127.0.0.1 (instead of https://localhost) because the latter cripples the network-features.
webrequests to the filesystem
Javascript webrequests can read from the filesystem via the 'file://host/path' protocol:
fetch("file://xrsh/mnt/profile.browser")
NOTE: it's file://xrsh
not file:///
(basically it includes host xrsh
) to prevent the browser security-model from blocking the request (and select the xrsh filesystem, not the native filesystem).
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
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 buf = await term.worker.read_file("hello.txt")
const str = new TextDecoder().decode(buf);
Calling javascript from terminal
Various options:
- Just add the
#!/bin/js
shebang to the top of a javascript file (+ chmod +x) - Run
js "alert('hello')"
in the shell - Run
jsh alert hello
in the shell - Run
jsh
to start an interactive shell