7.9 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
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:
- 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).
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
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:
- 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