Compare commits

...

130 commits
0.142 ... main

Author SHA1 Message Date
0407a23747 typofix urls
Some checks failed
/ mirror_to_github (push) Failing after 2m24s
/ test (push) Successful in 8s
2025-12-22 15:44:11 +01:00
cbc9daa8cd rerwote forgejo links to codeberg
Some checks failed
/ mirror_to_github (push) Failing after 4m26s
/ test (push) Has been cancelled
2025-12-22 15:39:55 +01:00
92590d6ecc new version
Some checks failed
/ mirror_to_github (push) Has been cancelled
/ test (push) Has been cancelled
2025-10-23 18:08:23 +02:00
e486111105 ignore remotestorage.js for vanilla terminal
Some checks are pending
/ mirror_to_github (push) Waiting to run
/ test (push) Waiting to run
2025-10-23 18:06:57 +02:00
11674a1509 added FoT talk
Some checks are pending
/ mirror_to_github (push) Waiting to run
/ test (push) Waiting to run
2025-10-22 17:25:09 +02:00
06ea1c56c8 added 'features' tag to gesture management page
Some checks failed
/ mirror_to_github (push) Has been cancelled
/ test (push) Has been cancelled
2025-07-18 16:11:33 +02:00
Fabien Benetou
6b2b9834ac gesture documentation
Some checks are pending
/ mirror_to_github (push) Waiting to run
/ test (push) Waiting to run
2025-07-18 15:21:21 +02:00
468cee87af added multibrowser cast
Some checks failed
/ mirror_to_github (push) Has been cancelled
/ test (push) Has been cancelled
2025-07-14 16:14:32 +02:00
8ac69c4aed window buttons in XR (better)
Some checks failed
/ mirror_to_github (push) Failing after 5m44s
/ test (push) Successful in 13s
2025-07-01 16:14:56 +02:00
f2d0c36f09 window buttons in XR (better) 2025-07-01 16:12:33 +02:00
a38fe0a16d window-buttons in XR
All checks were successful
/ test (push) Successful in 16s
2025-06-30 20:54:56 +02:00
a74e1dd60d wip: window close bugfix
All checks were successful
/ test (push) Successful in 16s
2025-06-27 11:49:29 +02:00
628357019c index.html: added more to XR hands page
Some checks failed
/ mirror_to_github (push) Failing after 2m24s
/ test (push) Successful in 13s
2025-06-26 15:18:25 +02:00
2cf3cb6808 added keyboard handfocus page
Some checks failed
/ mirror_to_github (push) Failing after 2m37s
/ test (push) Successful in 12s
2025-06-26 14:51:54 +02:00
310d7304a4 new build
Some checks failed
/ mirror_to_github (push) Failing after 2m22s
/ test (push) Successful in 18s
2025-06-25 18:54:04 +02:00
6f8dfc7bc3 new build + docs
Some checks failed
/ mirror_to_github (push) Failing after 2m17s
/ test (push) Successful in 12s
2025-06-24 12:48:07 +02:00
c17c2e4808 run server with vanilla redbean to prevent loading iso in xrsh.com 2025-06-24 12:47:56 +02:00
277bc79e78 added packages.zip video
Some checks failed
/ mirror_to_github (push) Failing after 2m5s
/ test (push) Successful in 11s
2025-06-20 18:23:32 +02:00
d2698c5e8e bugfix: array-less leftover exec() call
Some checks failed
/ mirror_to_github (push) Failing after 2m18s
/ test (push) Successful in 10s
2025-06-20 17:20:12 +02:00
95c91c72d8 added new build
Some checks failed
/ mirror_to_github (push) Failing after 1m18s
/ test (push) Successful in 10s
2025-06-20 16:45:29 +02:00
d424328c9a updated docs 2025-06-20 16:45:00 +02:00
aca83f7235 wip: adding more tests
All checks were successful
/ test (push) Successful in 13s
2025-06-13 23:50:32 +02:00
bd9de85ffc wip: adding more tests
All checks were successful
/ test (push) Successful in 12s
2025-06-10 15:08:11 +02:00
ab5efe4a33 new build
Some checks failed
/ mirror_to_github (push) Failing after 2m5s
/ test (push) Successful in 10s
2025-05-23 18:05:33 +02:00
9a9994a105 update components
Some checks failed
/ mirror_to_github (push) Failing after 2m10s
/ test (push) Has been cancelled
2025-05-23 18:02:56 +02:00
e72d296726 better async js execution page
Some checks failed
/ mirror_to_github (push) Failing after 2m22s
/ test (push) Successful in 10s
2025-05-23 12:49:43 +02:00
139f12031f new build
Some checks failed
/ mirror_to_github (push) Failing after 1m55s
/ test (push) Successful in 11s
2025-05-22 20:00:49 +02:00
05a2858ef7 upgrade xrfragment build 2025-05-22 20:00:26 +02:00
14bdd5fff3 index.html: update video of remotestorage page
Some checks failed
/ mirror_to_github (push) Failing after 2m3s
/ test (push) Successful in 9s
2025-05-22 18:37:13 +02:00
b48f9f47cc added assets
Some checks failed
/ mirror_to_github (push) Failing after 2m31s
/ test (push) Successful in 11s
2025-05-22 16:26:22 +02:00
5a35281c33 updated build + docs with remotestorage 2025-05-22 16:26:08 +02:00
5a3de2604d added remotestorage 2025-05-22 16:25:39 +02:00
f9ca00efb8 bugfix: properly escape exec command-strings
Some checks failed
/ mirror_to_github (push) Failing after 2m34s
/ test (push) Successful in 13s
2025-04-18 15:22:41 +02:00
4cc11e282a doc update
Some checks failed
/ mirror_to_github (push) Failing after 2m22s
/ test (push) Successful in 11s
2025-04-14 18:34:19 +02:00
2565aa3a70 new build
Some checks failed
/ mirror_to_github (push) Failing after 4m24s
/ test (push) Successful in 9s
2025-04-10 16:58:28 +02:00
0ab3eadcf0 doc: typofix
Some checks failed
/ mirror_to_github (push) Failing after 4m33s
/ test (push) Successful in 13s
2025-04-09 20:50:15 +02:00
ebd1895271 new build
Some checks failed
/ test (push) Waiting to run
/ mirror_to_github (push) Has been cancelled
2025-04-09 20:49:07 +02:00
afc2aa5373 doc: update term.exec()
Some checks failed
/ mirror_to_github (push) Failing after 2m27s
/ test (push) Successful in 11s
2025-04-09 20:42:45 +02:00
5d791ff0f4 doc: rename 'save index.html' to 'download index.html' 2025-04-09 18:41:22 +02:00
4337681504 doc: update prototype page
Some checks failed
/ mirror_to_github (push) Failing after 2m12s
/ test (push) Successful in 10s
2025-04-08 18:02:12 +02:00
1db899d837 doc: improved prototype paragraph
Some checks failed
/ mirror_to_github (push) Failing after 2m23s
/ test (push) Successful in 10s
2025-04-08 15:39:51 +02:00
5709e557a8 doc: added dialog info + autoenv URL
Some checks failed
/ mirror_to_github (push) Failing after 2m23s
/ test (push) Successful in 12s
2025-04-08 14:55:35 +02:00
819240c1b1 xrsh shellscript: improved ssl arg position
Some checks failed
/ mirror_to_github (push) Failing after 3m0s
/ test (push) Successful in 12s
2025-04-03 09:58:03 +02:00
b7bdbd74bc doc: update
Some checks failed
/ mirror_to_github (push) Failing after 3m1s
/ test (push) Successful in 18s
2025-04-03 09:49:34 +02:00
3662b84d8c doc: update
Some checks failed
/ mirror_to_github (push) Failing after 2m45s
/ test (push) Successful in 10s
2025-04-02 16:43:41 +02:00
ec1da5d108 doc: updated remote input
Some checks failed
/ mirror_to_github (push) Failing after 2m16s
/ test (push) Successful in 11s
2025-04-02 15:54:44 +02:00
653cecd599 xrsh ssl as option
Some checks failed
/ mirror_to_github (push) Failing after 2m13s
/ test (push) Successful in 12s
2025-04-02 15:44:32 +02:00
f8bc04d057 doc: added accessibility
Some checks failed
/ mirror_to_github (push) Failing after 2m24s
/ test (push) Successful in 10s
2025-04-02 11:30:56 +02:00
9bdac406ca doc: typofix
Some checks failed
/ mirror_to_github (push) Failing after 2m29s
/ test (push) Successful in 11s
2025-04-01 15:31:07 +02:00
9886f03082 doc: extra info for distribution xrsh.com for fabien
Some checks failed
/ mirror_to_github (push) Failing after 2m32s
/ test (push) Successful in 17s
2025-04-01 15:26:03 +02:00
2000557ef5 update docs: mention XR autoenv in 'what is a package' 2025-04-01 15:17:26 +02:00
5a3c4ecc13 update build
Some checks failed
/ mirror_to_github (push) Failing after 2m29s
/ test (push) Successful in 15s
2025-04-01 14:56:56 +02:00
770c70f250 README.md: more pointers iso-building 2025-04-01 14:56:41 +02:00
6eb4feb04d doc: added hint for straight AFARME hacking
Some checks failed
/ mirror_to_github (push) Failing after 2m13s
/ test (push) Successful in 10s
2025-03-28 16:16:50 +01:00
288ea3e5ec doc: added prototyping things menu-item
Some checks failed
/ mirror_to_github (push) Failing after 2m56s
/ test (push) Successful in 12s
2025-03-28 14:44:22 +01:00
c8478ae010 doc: added prototyping things menu-item
Some checks failed
/ mirror_to_github (push) Failing after 2m16s
/ test (push) Successful in 11s
2025-03-28 14:40:32 +01:00
59e2282ce7 doc: updated more links
Some checks failed
/ mirror_to_github (push) Failing after 2m8s
/ test (push) Successful in 10s
2025-03-28 14:09:18 +01:00
15d2d54f0d doc: updated links
Some checks failed
/ mirror_to_github (push) Failing after 2m10s
/ test (push) Successful in 10s
2025-03-28 13:30:33 +01:00
89807ef7e5 doc: added XR autoenv examples
Some checks failed
/ mirror_to_github (push) Failing after 2m16s
/ test (push) Successful in 12s
2025-03-28 11:21:16 +01:00
5a01767628 doc: added more fzf info
Some checks failed
/ mirror_to_github (push) Failing after 2m3s
/ test (push) Successful in 12s
2025-03-27 18:08:08 +01:00
df59d14947 added vim.zip + video to package-menu
Some checks failed
/ test (push) Successful in 14s
/ mirror_to_github (push) Failing after 10m30s
2025-03-27 17:52:22 +01:00
de69069222 css fix: show xrsh package-menuitem on non-localhost
Some checks failed
/ mirror_to_github (push) Failing after 2m0s
/ test (push) Successful in 10s
2025-03-27 13:10:40 +01:00
16ebd1785d added vim-package to docs
Some checks failed
/ mirror_to_github (push) Failing after 2m1s
/ test (push) Successful in 10s
2025-03-27 12:39:29 +01:00
1a6053e7e8 update package documentation
All checks were successful
/ test (push) Successful in 12s
2025-03-27 08:43:51 +01:00
58b100c0b2 doc update
Some checks failed
/ mirror_to_github (push) Failing after 2m9s
/ test (push) Successful in 11s
2025-03-25 10:19:04 +01:00
e894052988 icon fix build
Some checks failed
/ mirror_to_github (push) Failing after 1m47s
/ test (push) Successful in 10s
2025-03-24 18:12:13 +01:00
d598c74dbc updated docs
Some checks failed
/ mirror_to_github (push) Failing after 2m20s
/ test (push) Successful in 12s
2025-03-24 17:45:22 +01:00
ff8e61ff8a updated js build + remotekb
Some checks failed
/ mirror_to_github (push) Failing after 2m1s
/ test (push) Successful in 11s
2025-03-24 17:40:09 +01:00
5576340c4a updated js build
Some checks failed
/ test (push) Waiting to run
/ mirror_to_github (push) Has been cancelled
2025-03-24 17:38:49 +01:00
f0c80645db build
Some checks failed
/ mirror_to_github (push) Failing after 1m51s
/ test (push) Successful in 11s
2025-03-24 17:35:18 +01:00
481c2e7516 update with improved js-to-wasm api
Some checks failed
/ mirror_to_github (push) Failing after 1m52s
/ test (push) Successful in 9s
2025-03-24 16:12:19 +01:00
445d5f138c doc: fixed terminal height to 605px so AR/VR-mode never clips terminalprompt
Some checks failed
/ mirror_to_github (push) Failing after 2m27s
/ test (push) Successful in 13s
2025-03-21 16:03:22 +01:00
06660eb19b better grabbable + example form now demos increase/decrease iconsize
Some checks failed
/ mirror_to_github (push) Failing after 1m55s
/ test (push) Successful in 13s
2025-03-21 15:59:35 +01:00
83c1cd510d doc: fixnlnet logo
Some checks failed
/ mirror_to_github (push) Failing after 1m46s
/ test (push) Successful in 11s
2025-03-21 14:41:42 +01:00
f9f2454e0c doc: fix title (regression)
Some checks failed
/ mirror_to_github (push) Failing after 1m43s
/ test (push) Successful in 9s
2025-03-21 14:31:29 +01:00
c15c5a591c doc: shown only logo in sidebar
Some checks failed
/ mirror_to_github (push) Failing after 1m50s
/ test (push) Successful in 10s
2025-03-21 14:20:04 +01:00
940272cccc doc: dont close sidebar always
Some checks are pending
/ mirror_to_github (push) Waiting to run
/ test (push) Waiting to run
2025-03-21 14:17:52 +01:00
ca2793b81c doc: improved sidebar logic
Some checks are pending
/ mirror_to_github (push) Waiting to run
/ test (push) Waiting to run
2025-03-21 14:04:54 +01:00
59e84ea962 doc update: disabled sideviewer, used iframe embed on mainpage
Some checks are pending
/ mirror_to_github (push) Waiting to run
/ test (push) Waiting to run
2025-03-21 13:49:55 +01:00
353c8a0a74 update docs
Some checks failed
/ mirror_to_github (push) Failing after 1m39s
/ test (push) Successful in 9s
2025-03-14 15:00:38 +01:00
a413dc047e Merge branch 'feat/handmenu' 2025-03-14 14:52:01 +01:00
7b28c0ef1b launcher / handmenu
All checks were successful
/ test (push) Successful in 8s
2025-03-14 14:51:29 +01:00
5d6e9f4615 remove unused symlinks
Some checks failed
/ mirror_to_github (push) Failing after 4m34s
/ test (push) Failing after 12m4s
2025-02-28 13:41:01 +01:00
435ac2fc51 removed alert()
Some checks failed
/ mirror_to_github (push) Failing after 2m0s
/ test (push) Successful in 9s
2025-02-21 16:03:10 +01:00
20e0854c5a improved hashboot
Some checks failed
/ mirror_to_github (push) Failing after 2m3s
/ test (push) Successful in 9s
2025-02-21 16:00:38 +01:00
abe4fc33b1 update docs
Some checks failed
/ mirror_to_github (push) Failing after 1m53s
/ test (push) Successful in 8s
2025-02-18 16:26:06 +01:00
d6bb3eabfa update docs
Some checks failed
/ mirror_to_github (push) Failing after 1m43s
/ test (push) Successful in 8s
2025-02-18 16:16:40 +01:00
368daefbe6 added new build
Some checks failed
/ mirror_to_github (push) Failing after 1m57s
/ test (push) Successful in 11s
2025-02-18 15:27:12 +01:00
5139be3965 added overlayfs + nix docs 2025-02-17 18:32:32 +01:00
47f319b29b improved feature/remote keyboard text [added link]
Some checks failed
/ mirror_to_github (push) Failing after 1m39s
/ test (push) Successful in 9s
2025-02-14 18:38:43 +01:00
b6283b75ae improved feature/remote keyboard text
Some checks failed
/ mirror_to_github (push) Failing after 1m43s
/ test (push) Successful in 9s
2025-02-14 18:36:09 +01:00
8584b0f784 added picture to feature/remote keyboard
Some checks failed
/ mirror_to_github (push) Failing after 1m51s
/ test (push) Successful in 9s
2025-02-14 18:33:25 +01:00
e3903e3beb remote keyboard improvements + docs
Some checks failed
/ mirror_to_github (push) Failing after 1m57s
/ test (push) Successful in 8s
2025-02-14 17:19:04 +01:00
2991f0b73e added xrsh shell-util with remote keyboard support
Some checks failed
/ mirror_to_github (push) Failing after 1m42s
/ test (push) Successful in 7s
2025-02-14 12:17:10 +01:00
5b1b6df448 docs: reorder pages to make menu-clicks autoclose menu on mobile
Some checks failed
/ mirror_to_github (push) Failing after 2m20s
/ test (push) Successful in 13s
2025-02-11 11:19:10 +01:00
33c2a6cf92 update build
Some checks failed
/ mirror_to_github (push) Failing after 3m6s
/ test (push) Successful in 14s
2025-02-10 20:02:43 +01:00
946d091385 update components
Some checks failed
/ mirror_to_github (push) Failing after 2m19s
/ test (push) Successful in 8s
2025-02-10 19:55:24 +01:00
4a395a2d06 new build
Some checks failed
/ mirror_to_github (push) Failing after 1m38s
/ test (push) Successful in 8s
2025-02-07 20:46:28 +01:00
d3f9c4df56 docs: added wolvic url
Some checks failed
/ mirror_to_github (push) Failing after 1m41s
/ test (push) Successful in 6s
2025-01-29 10:53:05 +01:00
6548accd48 docs: update extension url
Some checks failed
/ mirror_to_github (push) Failing after 1m40s
/ test (push) Successful in 6s
2025-01-28 12:13:41 +01:00
b352c95b57 docs: better wording (preload => prime)
Some checks failed
/ mirror_to_github (push) Failing after 1m47s
/ test (push) Successful in 7s
2025-01-28 11:52:20 +01:00
1ef3cf5c3a docs: markup fix installation-page
Some checks failed
/ mirror_to_github (push) Failing after 2m7s
/ test (push) Successful in 8s
2025-01-28 11:37:50 +01:00
fc2e42c714 promote more readable this.send() in REPLs
Some checks failed
/ mirror_to_github (push) Failing after 1m59s
/ test (push) Successful in 8s
2025-01-28 11:31:37 +01:00
5bf33dedcd added browser-extension + docs
Some checks failed
/ mirror_to_github (push) Failing after 1m41s
/ test (push) Successful in 7s
2025-01-28 10:22:54 +01:00
80c5301e29 doc: better landingpage
Some checks failed
/ mirror_to_github (push) Failing after 1m53s
/ test (push) Successful in 13s
2025-01-27 18:53:48 +01:00
fa3422723c doc: typofix
Some checks failed
/ mirror_to_github (push) Failing after 1m41s
/ test (push) Successful in 8s
2025-01-27 18:51:07 +01:00
330fe0eff2 doc: added iso instructions
Some checks failed
/ mirror_to_github (push) Failing after 1m42s
/ test (push) Successful in 5s
2025-01-27 18:42:58 +01:00
6cf4bd0d31 doc: added iso instructions
Some checks failed
/ mirror_to_github (push) Failing after 1m38s
/ test (push) Successful in 6s
2025-01-27 18:37:25 +01:00
ea70f8f775 update docs with 'getting data in'-section in getting started
Some checks failed
/ mirror_to_github (push) Failing after 1m47s
/ test (push) Successful in 5s
2025-01-27 18:20:19 +01:00
b5d4f6c4bc updated docs + comps
Some checks failed
/ mirror_to_github (push) Failing after 1m41s
/ test (push) Successful in 5s
2025-01-27 18:06:48 +01:00
bee2fe0968 update components + build
Some checks failed
/ mirror_to_github (push) Failing after 1m45s
/ test (push) Successful in 6s
2025-01-27 17:44:06 +01:00
8a9b58bb5e typofix docs
Some checks failed
/ mirror_to_github (push) Failing after 1m35s
/ test (push) Successful in 5s
2025-01-27 17:40:48 +01:00
fece3b8032 added portable xrsh.js + LICENSE + docs
Some checks failed
/ mirror_to_github (push) Failing after 1m44s
/ test (push) Successful in 6s
2025-01-27 17:07:19 +01:00
bd57a09923 added new build
Some checks failed
/ mirror_to_github (push) Failing after 2m9s
/ test (push) Successful in 15s
2025-01-27 12:01:13 +01:00
4cf80a6164 dynamic repl update
Some checks failed
/ test (push) Waiting to run
/ mirror_to_github (push) Has been cancelled
2025-01-27 12:00:35 +01:00
8b78dfe9ed bugfix: scope fix
Some checks failed
/ mirror_to_github (push) Failing after 1m43s
/ test (push) Successful in 8s
2025-01-24 17:35:12 +01:00
deeb3176e3 backspace support in bootmenu
Some checks failed
/ mirror_to_github (push) Failing after 1m48s
/ test (push) Successful in 7s
2025-01-24 17:30:36 +01:00
ed15da5f71 extendable repls
Some checks failed
/ mirror_to_github (push) Failing after 2m4s
/ test (push) Successful in 9s
2025-01-24 17:26:27 +01:00
af0d710f2d deploy submodule workaround
Some checks failed
/ mirror_to_github (push) Failing after 1m36s
/ test (push) Successful in 5s
2025-01-23 15:43:18 +01:00
09611c8569 deploy submodule workaround
Some checks failed
/ mirror_to_github (push) Failing after 1m46s
/ test (push) Successful in 6s
2025-01-23 15:40:02 +01:00
b49835ffd6 deploy submodule workaround
Some checks failed
/ mirror_to_github (push) Failing after 1m47s
/ test (push) Has been cancelled
2025-01-23 15:38:07 +01:00
5a116394d3 update build + coms
Some checks failed
/ mirror_to_github (push) Failing after 1m34s
/ test (push) Successful in 6s
2025-01-23 15:33:07 +01:00
39e0a1356f added Dockerfile
Some checks failed
/ mirror_to_github (push) Failing after 1s
/ test (push) Successful in 6s
2025-01-21 16:38:42 +01:00
5f3622e2bb added github hint to README.md
Some checks are pending
/ mirror_to_github (push) Has started running
/ test (push) Successful in 5s
2025-01-21 16:31:48 +01:00
3cca7f2d69 added installation page
Some checks failed
/ mirror_to_github (push) Failing after 1m27s
/ test (push) Successful in 5s
2025-01-21 16:04:38 +01:00
851a589471 added nix/docker/yunohost howtos
Some checks failed
/ mirror_to_github (push) Failing after 1m23s
/ test (push) Has been cancelled
2025-01-21 16:03:06 +01:00
3989ca1bbf nix tutorial
All checks were successful
/ mirror_to_github (push) Successful in 1m33s
/ test (push) Successful in 6s
2025-01-20 15:50:21 +01:00
0a85da40ef cleanup
All checks were successful
/ mirror_to_github (push) Successful in 1m29s
/ test (push) Successful in 5s
2025-01-20 15:32:50 +01:00
12f84e4cf7 typofix .gitmodules
All checks were successful
/ mirror_to_github (push) Successful in 1m59s
/ test (push) Successful in 10s
2025-01-20 15:01:32 +01:00
19b326c524 make submodule relative to origin
All checks were successful
/ mirror_to_github (push) Successful in 1m48s
/ test (push) Successful in 7s
2025-01-20 14:58:40 +01:00
44 changed files with 13423 additions and 106929 deletions

2
.env
View file

@ -21,5 +21,5 @@ which nix-shell && test -z "$NIX_SHELL_XRSH" && {
test "$GITEA_ROOT_URL" = "https://forgejo.isvery.ninja/" && {
# on the website xrsh.isvery.ninja
echo hello deployment
echo hello website deployment
}

1
.gitignore vendored
View file

@ -2,5 +2,6 @@ xrsh-media
XRSH milestones.odt
aframe/CHANGELOG.md aframe/codecov.yml aframe/CODE_OF_CONDUCT.md aframe/CONTRIBUTING.md aframe/dist aframe/docs aframe/examples aframe/index.html aframe/LICENSE aframe/ORGANIZATION.md aframe/package.json aframe/README.md aframe/ROADMAP.md aframe/scripts aframe/src aframe/tests aframe/vendor aframe/webpack.config.js aframe/webpack.prod.config.js
result
src/aframe
tags

2
.gitmodules vendored
View file

@ -1,5 +1,5 @@
[submodule "src/xrsh-com"]
path = src/xrsh-com
url = https://forgejo.isvery.ninja/xrsh/xrsh-com.git
url = ./../xrsh-com
#url = ssh://git@forgejo.isvery.ninja:8222/xrsh/xrsh-com.git

19
Dockerfile Normal file
View file

@ -0,0 +1,19 @@
FROM alpine:latest as build
RUN apk add --update zip bash file curl
ADD xrsh.com /
RUN curl -o assimilate https://cosmo.zip/pub/cosmos/bin/assimilate && \
chmod +x assimilate && \
./assimilate /xrsh.com && \
file /xrsh.com
# normalize the binary to ELF
#RUN sh /xrsh.com --assimilate && file /xrsh.com
FROM scratch
COPY --from=build /xrsh.com /
CMD ["/xrsh.com"]

View file

@ -672,3 +672,4 @@ may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

208
README.md
View file

@ -18,17 +18,19 @@ See [the wiki here](https://forgejo.isvery.ninja/xrsh/xrsh/wiki/Home#milestones)
> NOTE: installation is optional: just surf to the public version [here](https://xrsh.isvery.ninja)
<details>
<summary>install using nix</summary>
For local use: download the crossplatform <a href="/xrsh.com" target="_blank">xrsh.com</a> executable [<a href="/xrsh.com.txt" target="_blank">checksum</a>]:<br>
[NIX](https://nixos.org/) is a convenient way to install or develop xrsh:
1. [linux/mac only] run `chmod +x xrsh.com` in the console
2. run `./xrsh.com` in the console
3. xrsh opens in your browser at `https://127.0.0.1:8080`
4. profit!
1. run `nix-run -p xrsh --run "xrsh.com"` (pass `-p XXXX` to specify non-default 8080 port )
2. build it when package does not exist: `nix-build -E "with import <nixpkgs> { }; callPackage ./xrsh.nix"`
</details>
> pass `-p XXXX` to specify port (default:8080)
### Installation guides
<details>
<summary>install without nix</summary>
<summary>run standalone binary</summary>
1. Download [xrsh.com](https://forgejo.isvery.ninja/xrsh/xrsh/raw/branch/main/xrsh.com)
2. optional: run `unzip xrsh.com` to verify repository contents
@ -37,6 +39,124 @@ See [the wiki here](https://forgejo.isvery.ninja/xrsh/xrsh/wiki/Home#milestones)
5. Profit! ✔
</details>
<details>
<summary>install using nixos</summary>
[NIX](https://nixos.org/) is a convenient way to install or develop xrsh:
1. `nix-shell -p xrsh thttpd`
2. run it (`thttpd -p 8080 -d /nix/store/5q4vd50gmh52jh48z62ln1j05xzfh1fz-xrsh-0.142` e.g.)
3. point your browser to `localhost:8080`
4. profit!
</details>
<details>
<summary>run OCI container [podman/docker]</summary>
1. `$(which podman || which docker) run -p 8080:8080 docker.io/coderofsalvation/xrsh`
2. point your browser to `localhost:8080`
3. profit!
> NOTE 1: to add files use the `-D <dir>` overlay webroot parameter.
> NOTE 2: to enable SSL and add (iso)file try something like this:
```
$ mkdir data
$ cp ../xrsh.iso data/. # copy custom iso
$ $(which podman || which docker) run -p 8080:8080 -v data/cert:etc/cert -v data:/data docker.io/coderofsalvation/xrsh /xrsh.com -D /data -c 0 -C /etc/cert/cert.pem -K /etc/cert/key.pem
```
> or as an exercise in constructive laziness setup a reverse proxy like [zoraxy](https://github.com/tobychui/zoraxy), [go-proxy](https://github.com/yusing/go-proxy), [droxy], caddy or nginx-reverse-proxymanager.
</details>
<details>
<summary>run from codeberg.org</summary>
(codeberg.org is a nonprofit-backed forgejo instance)
1. create a repository on codeberg.org
2. `git push` the [xrsh repository](https://forgejo.isvery.ninja/xrsh/xrsh) to it
1. create a `pages` branchclone
2. push it to the codeberg repository
3. profit! it is now live
> more info: https://docs.codeberg.org/codeberg-pages/
</details>
<details>
<summary>run from selfhosted forgejo/gitea instance</summary>
1. clone the xrsh [xrsh repository](https://forgejo.isvery.ninja/xrsh/xrsh) locally
2. create a repo on your [forgejo](https://forgejo.org) instance
3. `git push` the xrsh to it
4. in your forgejo (docker/nix)-instance symlink it to the public folder (*)
5. point your browser to `https://yourforgejo.org/assets/xrsh`
> \* = for example: `ln -f git/repositories/yourusername/xrsh gitea/public/assets/.`
> optionally customize the [xrsh yunohost package](https://forgejo.isvery.ninja/xrsh/xrsh_ynh) with your own ISO
</details>
<details>
<summary>install in yunohost</summary>
1. search for xrsh in the [yunohost](https://yunohost.org) application catalog
2. click install
3. profit!
> optionally customize the [xrsh yunohost package](https://forgejo.isvery.ninja/xrsh/xrsh_ynh) with your own ISO
</details>
<details>
<summary>install with systemd</summary>
1. Create a new systemd service file (`sudo nano /etc/systemd/system/xrsh.service` e.g.)
2. Specify the `ExecStart` directive to run the xrsh (`[Service]\ExecStart=/path/to/xrsh.com -p 8080` e.g.).
3. Enable the service (`sudo systemctl enable xrsh.service` e.g.)
4. Start the service (`sudo systemctl start xrsh.service`).
4. Verify the service: `sudo systemctl status xrsh.service` or `netstat -tuln`.
</details>
<details>
<summary>run from github</summary>
Sigh..good old github times (RIP)..<br>
It used to be a simple webinterface around git in 2008.<br>
These days running a forgejo/gitea instance + CI is literally one cmd away (or hosted by codeberg.org.<br>
</details>
## Developers
Make sure to clone the repo including submodules (the [xrsh-com](https://forgejo.isvery.ninja/xrsh/xrsh-com) repo)
```
$ git clone --recurse-submodules https://forgejo.isvery.ninja/xrsh/xrsh
$ cd xrsh
$ nix-shell # optional but adviced (to get up and running instantly)
```
> Now serve the repo from a HTTPS webserver (for example run `./make dev`)
Eventhough a custom ISO-image can be **built**, XRSH is **buildless** software.<br>
The crossplatform binary is just a zip-file with the source (using https://redbean.dev):
<details>
<summary>build using shellscript</summary>
1. Run `./make standalone` to package everything into `xrsh.com`
</details>
<details>
<summary>build using nix</summary>
1. `nix-build -E "with import <nixpkgs> { }; callPackage ./nix/xrsh-package.nix"`
2. optionally see the other nix-files in `nix`-folder
</details>
<details>
<summary>launch different .iso / modify files</summary>
@ -50,27 +170,65 @@ You can specify a different `.iso` file in various ways:
</details>
The browser auto-launches `https://localhost:8080` on most platforms
> pass `-p XXXX` to specify port (default:8080)
## Developers
Make sure to clone the repo including submodules (the [xrsh-com](https://forgejo.isvery.ninja/xrsh/xrsh-com) repo)
```
$ git clone --recurse-submodules https://forgejo.isvery.ninja/xrsh/xrsh
$ cd xrsh
$ nix-shell # optional but adviced (to get up and running instantly)
```
> Now serve the repo from a HTTPS webserver (for example run `./make dev`)
Run `./make standalone` to package everything into `xrsh.com`
* development of components (`src/com`) takes places [in this git submodule](https://forgejo.isvery.ninja/xrsh/xrsh-com)
* development of `xrsh.iso` takes places [in this gitsubmodule](https://forgejo.isvery.ninja/xrsh/xrsh-buildroot)
> IMPORTANT: existing AFRAME apps can embed a barebones XR terminal / REPL like this:
```html
<html>
<head>
<script src="https://aframe.io/releases/1.6.0/aframe.min.js"></script>
<script src="https://xrsh.isvery.ninja/xrsh.js"></script>
</head>
<body>
<a-scene>
<a-entity isoterminal position="0 1.6 -0.3"></a-entity>
</a-scene>
<script>
document.querySelector('a-scene').addEventListener('isoterminal_init', function(e){
// (OPTIONAL) override/extend bootmenu-array with your own REPL(s)
// see com/isoterminal/feat/boot.REPL.*.js for examples
ISOTerminal.prototype.boot.menu.push({
key: "f",
title: (opts) => `other awesome NLnet FOSS projects ❤️`,
init: function( mainmenu ){
window.open('https://nlnet.nl/project/current.html','_blank')
// return to main menu
mainmenu()
},
keyHandler: function(ch){
this.send("\n\ryou typed:"+ch) // write to term
}
})
})
// AFRAME exposes THREE too
console.log(THREE)
</script>
</body>
</html>
> this portable version runs without the ISO (which requires wasm-files, longer loadingtimes e.g.)
```
## Building your own ISO
As described in the [website documentation](https://xrsh.isvery.ninja/#Booting%20an%20ISO%20image) you could boot your own ISO distribution (TIP: a [filesystem overlay](https://xrsh.isvery.ninja/#Filesystem%20overlay) is easier):
```
$ git clone --recurse-submodules ssh://git@forgejo.isvery.ninja:8222/xrsh/xrsh.git
$ git clone ssh://git@forgejo.isvery.ninja:8222/xrsh/xrsh-buildroot
$ cd xrsh
$ rm xrsh.iso && ln -fs ../xrsh-buildroot/dist/v86-linux.iso xrsh.iso
$ ./make dev
```
You can read the [repo-README](https://forgejo.isvery.ninja/xrsh/xrsh-buildroot) about (re)building/modifying the iso
## Funding

View file

@ -1,93 +0,0 @@
{ lib
, stdenv
, fetchFromGitHub
, bintools-unwrapped
, callPackage
, coreutils
, substituteAll
, unzip
}:
stdenv.mkDerivation (finalAttrs: {
pname = "cosmopolitan";
version = "2.2";
src = fetchFromGitHub {
owner = "jart";
repo = "cosmopolitan";
rev = finalAttrs.version;
hash = "sha256-DTL1dXH+LhaxWpiCrsNjV74Bw5+kPbhEAA2Z1NKiPDk=";
};
patches = [
# make sure tests set PATH correctly
(substituteAll {
src = ./fix-paths.patch;
inherit coreutils;
})
];
nativeBuildInputs = [
bintools-unwrapped
unzip
];
strictDeps = true;
outputs = [ "out" "dist" ];
# slashes are significant because upstream uses o/$(MODE)/foo.o
buildFlags = [
"o/cosmopolitan.h"
"o//cosmopolitan.a"
"o//libc/crt/crt.o"
"o//ape/ape.o"
"o//ape/ape.lds"
"o//tool/net/redbean.com"
];
checkTarget = "o//test";
enableParallelBuilding = true;
doCheck = false;
dontConfigure = true;
dontFixup = true;
preCheck = let
failingTests = [
# some syscall tests fail because we're in a sandbox
"test/libc/calls/sched_setscheduler_test.c"
"test/libc/thread/pthread_create_test.c"
"test/libc/calls/getgroups_test.c"
# fails
"test/libc/stdio/posix_spawn_test.c"
];
in lib.concatStringsSep ";\n" (map (t: "rm -v ${t}") failingTests);
installPhase = ''
runHook preInstall
mkdir -p $out/{include,lib,bin}
install o/cosmopolitan.h $out/include
install o/cosmopolitan.a o/libc/crt/crt.o o/ape/ape.{o,lds} o/ape/ape-no-modify-self.o $out/lib
install o/tool/net/redbean.com $out/bin/xrsh.com
cp -RT . "$dist"
runHook postInstall
'';
passthru = {
cosmocc = callPackage ./cosmocc.nix {
cosmopolitan = finalAttrs.finalPackage;
};
};
meta = {
homepage = "https://xrsh.isvery.ninja/";
description = "XR shell runs a linux ISO in WebXR";
license = lib.licenses.isc;
maintainers = lib.teams.cosmopolitan.members;
platforms = lib.platforms.x86_64;
};
})

File diff suppressed because one or more lines are too long

77
make
View file

@ -15,25 +15,76 @@ deps(){ # check dependencies
}
standalone(){ # build standalone xrsh.com binary
FILE=${APP}.com
test -z "$1" && {
rm ${APP}.com || true
deps
exec(){
FILE=${APP}.com
test -z "$1" && {
rm ${APP}.com || true
deps
}
test -n "$1" && FILE="$1"
#cp index.html /tmp/index.html
#sed -i 's|isoterminal=".*"|isoterminal="iso: ./../xrsh.iso"|g' index.html
zip -x "*.git*" -r "$FILE" index.html xrsh.iso .args LICENSE src/index.{html,css} src/assets src/com/*.js src/com/lib src/com/isoterminal/{libv86.js,bios,v86.wasm,feat,PromiseWorker.js,ISOTerminal.js,localforage.js,term.js,assets,worker.js}
#cp /tmp/index.html index.html
sha256sum "$FILE" > "$FILE".txt
ls -lah "$FILE"
}
test -n "$1" && FILE="$1"
#cp index.html /tmp/index.html
#sed -i 's|isoterminal=".*"|isoterminal="iso: ./../xrsh.iso"|g' index.html
zip -x "*.git*" -r "$FILE" index.html xrsh.iso .args LICENSE src/index.{html,css} src/assets src/com/*.js src/com/lib src/com/isoterminal/{libv86.js,bios,v86.wasm,feat,PromiseWorker.js,ISOTerminal.js,localforage.js,term.js,assets,worker.js}
#cp /tmp/index.html index.html
sha256sum "$FILE" > "$FILE".txt
ls -lah "$FILE"
jslib(){
{
echo ""
echo "/* xrsh.js AFRAME component "
echo " * https://xrsh.isvery.ninja "
echo " * SPDX: AGPL-3.0-or-later "
echo " */"
echo "document.head.innerHTML += \`<style type='text/css'>"
cat src/index.css
echo -e "</style>\`;\n"
cat src/assets/winbox* src/com/{isoterminal,data2event,dom,html-as-texture-in-xr,pastedrop,require,window}.js src/com/lib/*.js src/com/isoterminal/{ISOTerminal.js,term.js,feat/boot.js,feat/jsconsole.js,feat/term.js,feat/remotekeyboard.js}
echo "// mark above libs as pre-required in require.js, to prevent 'component already registered' errors "
echo "AFRAME.utils.require.required = {";
echo " window: true,"
echo " winboxjs: true,"
echo " com: true,"
echo " dom: true,"
echo " xhook: true,"
echo " pastedrop: true,"
echo " selfcontain: true,"
echo " v86: true,"
echo " htmlinxr: true,"
echo " html: true,"
echo " PromiseWorker: true,"
echo " ISOTerminal: true,"
echo " localforage: true,"
echo " boot: true,"
echo " javascript: true,"
echo " jsconsole: true,"
echo " indexhtml: true,"
echo " indexjs: true,"
echo " autorestore: true,"
echo " pastedropFeat: true,"
echo " httpfs: true,"
echo " fbterm: true,"
echo " fbtermjs: true,"
echo " remotekeyboard: true"
echo " remotestorage: true"
echo " };"
} > xrsh.js
ls -lh xrsh.js
}
test -z "$1" && { jslib; exec; }
test -n "$1" && "$@"
}
dev(){ # start dev http server
set -x
cd "$DIR"
test -f xrsh.com || standalone
wget "$REDBEAN_VERSION" -O /tmp/server.com
chmod +x /tmp/server.com
test -f /tmp/cert.pem || openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout /tmp/key.pem -out /tmp/cert.pem
./xrsh.com -c 0 -C /tmp/cert.pem -K /tmp/key.pem -D . "$@"
/tmp/server.com -c 0 -C /tmp/cert.pem -K /tmp/key.pem -D . "$@"
}
shell(){ # run xrsh shell via docker

29
nix/xrsh-package.nix Normal file
View file

@ -0,0 +1,29 @@
{ stdenv, fetchgit, lib }:
stdenv.mkDerivation rec {
pname = "xrsh";
version = "0.142";
src = fetchgit {
fetchSubmodules = true;
url = "https://codeberg.org/xrsh/xrsh.git";
rev = "12f84e4cf72bf1e1268a6a4120594a825a8f66a7";
sha256 = "sha256-0MBBlqL2TWgN94ErI2Joub0Aub5XBxGWXILPDAfiNpc=";
};
dontBuild = true;
installPhase = ''
mkdir $out
cp -r $src/{index.html,src,xrsh.ico,xrsh.svg} $out/.
'';
meta = with lib; {
description = "XR shell which runs a linux ISO in WebXR";
license = "GPL3";
homepage = "https://xrsh.isvery.ninja";
maintainers = with maintainers; [ coderofsalvation ];
platforms = [ "i686-linux" "x86_64-linux" "x86_64-windows" "i686-windows" "x86_64-darwin" ];
};
}

View file

@ -1,25 +0,0 @@
{ stdenv, fetchurl }:
stdenv.mkDerivation rec {
pname = "xrsh";
version = "0.1";
src = fetchurl {
url = "https://codeberg.org/xrsh/xrsh/archive/24e117f5125e4b2ecd7432baf6fdd5f60e6b3a70.tar.gz";
sha256 = "11v22pijnjm3mb3n8dki4m95rc73azschfwvh2c1pc3bxrfsk0k8";
};
#cosmopolitan = pkgs.callPackage pkgs.cosmopolitan { };
## Override derivation to modify buildFlags
#redbean = cosmopolitan.overrideDerivation (oldAttrs: {
# buildFlags = oldAttrs.buildFlags ++ ["--enable-feature-x"];
#});
buildInputs = [];
buildFlags = [];
# Define phases if needed, e.g., build, install, etc.
# phases = [ "buildPhase" "installPhase" ];
}

Binary file not shown.

View file

@ -1 +0,0 @@
../../../aframe

416
src/assets/aframe-remotestorage.min.js vendored Normal file

File diff suppressed because one or more lines are too long

46403
src/assets/aframe.min.js vendored

File diff suppressed because one or more lines are too long

34
src/assets/winbox.bundle.min.js vendored Normal file
View file

@ -0,0 +1,34 @@
/**
* WinBox.js v0.2.82 (Bundle)
* Author and Copyright: Thomas Wilkerling
* Licence: Apache-2.0
* Hosted by Nextapps GmbH
* https://github.com/nextapps-de/winbox
*/
(function(){'use strict';var e,aa=document.createElement("style");aa.innerHTML="@keyframes wb-fade-in{0%{opacity:0}to{opacity:.85}}.winbox{position:fixed;left:0;top:0;background:#0050ff;box-shadow:0 14px 28px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.22);transition:width .3s,height .3s,left .3s,top .3s;transition-timing-function:cubic-bezier(.3,1,.3,1);contain:layout size;text-align:left;touch-action:none}.wb-body,.wb-header{position:absolute;left:0}.wb-header{top:0;width:100%;height:35px;line-height:35px;color:#fff;overflow:hidden;z-index:1}.wb-body{top:35px;right:0;bottom:0;overflow:auto;-webkit-overflow-scrolling:touch;overflow-scrolling:touch;will-change:contents;background:#fff;margin-top:0!important;contain:strict;z-index:0}.wb-control *,.wb-icon{background-repeat:no-repeat}.wb-drag{height:100%;padding-left:10px;cursor:move}.wb-title{font-family:Arial,sans-serif;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wb-icon{display:none;width:20px;height:100%;margin:-1px 8px 0-3px;float:left;background-size:100%;background-position:center}.wb-e,.wb-w{width:10px;top:0}.wb-n,.wb-s{left:0;height:10px;position:absolute}.wb-n{top:-5px;right:0;cursor:n-resize;z-index:2}.wb-e{position:absolute;right:-5px;bottom:0;cursor:w-resize;z-index:2}.wb-s{bottom:-5px;right:0;cursor:n-resize;z-index:2}.wb-nw,.wb-sw,.wb-w{left:-5px}.wb-w{position:absolute;bottom:0;cursor:w-resize;z-index:2}.wb-ne,.wb-nw,.wb-sw{width:15px;height:15px;z-index:2;position:absolute}.wb-nw{top:-5px;cursor:nw-resize}.wb-ne,.wb-sw{cursor:ne-resize}.wb-ne{top:-5px;right:-5px}.wb-se,.wb-sw{bottom:-5px}.wb-se{position:absolute;right:-5px;width:15px;height:15px;cursor:nw-resize;z-index:2}.wb-control{float:right;height:100%;max-width:100%;text-align:center}.wb-control *{display:inline-block;width:30px;height:100%;max-width:100%;background-position:center;cursor:pointer}.no-close .wb-close,.no-full .wb-full,.no-header .wb-header,.no-max .wb-max,.no-min .wb-min,.no-resize .wb-body~div,.wb-body .wb-hide,.wb-show,.winbox.hide,.winbox.min .wb-body>*,.winbox.min .wb-full,.winbox.min .wb-min,.winbox.modal .wb-full,.winbox.modal .wb-max,.winbox.modal .wb-min{display:none}.winbox.max .wb-drag,.winbox.min .wb-drag{cursor:default}.wb-min{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAyIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNOCAwaDdhMSAxIDAgMCAxIDAgMkgxYTEgMSAwIDAgMSAwLTJoN3oiLz48L3N2Zz4=);background-size:14px auto;background-position:center calc(50% + 6px)}.wb-max{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHZpZXdCb3g9IjAgMCA5NiA5NiI+PHBhdGggZD0iTTIwIDcxLjMxMUMxNS4zNCA2OS42NyAxMiA2NS4yMyAxMiA2MFYyMGMwLTYuNjMgNS4zNy0xMiAxMi0xMmg0MGM1LjIzIDAgOS42NyAzLjM0IDExLjMxMSA4SDI0Yy0yLjIxIDAtNCAxLjc5LTQgNHY1MS4zMTF6Ii8+PHBhdGggZD0iTTkyIDc2VjM2YzAtNi42My01LjM3LTEyLTEyLTEySDQwYy02LjYzIDAtMTIgNS4zNy0xMiAxMnY0MGMwIDYuNjMgNS4zNyAxMiAxMiAxMmg0MGM2LjYzIDAgMTItNS4zNyAxMi0xMnptLTUyIDRjLTIuMjEgMC00LTEuNzktNC00VjM2YzAtMi4yMSAxLjc5LTQgNC00aDQwYzIuMjEgMCA0IDEuNzkgNCA0djQwYzAgMi4yMS0xLjc5IDQtNCA0SDQweiIvPjwvc3ZnPg==);background-size:17px auto}.wb-close{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xIC0xIDE4IDE4Ij48cGF0aCBmaWxsPSIjZmZmIiBkPSJtMS42MTMuMjEuMDk0LjA4M0w4IDYuNTg1IDE0LjI5My4yOTNsLjA5NC0uMDgzYTEgMSAwIDAgMSAxLjQwMyAxLjQwM2wtLjA4My4wOTRMOS40MTUgOGw2LjI5MiA2LjI5M2ExIDEgMCAwIDEtMS4zMiAxLjQ5N2wtLjA5NC0uMDgzTDggOS40MTVsLTYuMjkzIDYuMjkyLS4wOTQuMDgzQTEgMSAwIDAgMSAuMjEgMTQuMzg3bC4wODMtLjA5NEw2LjU4NSA4IC4yOTMgMS43MDdBMSAxIDAgMCAxIDEuNjEzLjIxeiIvPjwvc3ZnPg==);background-size:15px auto;background-position:5px center}.wb-full{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjIuNSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNOCAzSDVhMiAyIDAgMCAwLTIgMnYzbTE4IDBWNWEyIDIgMCAwIDAtMi0yaC0zbTAgMThoM2EyIDIgMCAwIDAgMi0ydi0zTTMgMTZ2M2EyIDIgMCAwIDAgMiAyaDMiLz48L3N2Zz4=);background-size:16px auto}.winbox.max .wb-body~div,.winbox.min .wb-body~div,.winbox.modal .wb-body~div,.winbox.modal .wb-drag,body.wb-lock iframe{pointer-events:none}.winbox.max{box-shadow:none}.winbox.max .wb-body{margin:0!important}.winbox iframe{position:absolute;width:100%;height:100%;border:0}body.wb-lock .winbox{will-change:left,top,width,height;transition:none}.winbox.modal:before{content:'';position:absolute;top:0;left:0;right:0;bottom:0;background:inherit;border-radius:inherit}.winbox.modal:after{content:'';position:absolute;top:-50vh;left:-50vw;right:-50vw;bottom:-50vh;background:#0d1117;animation:wb-fade-in .2s ease-out forwards;z-index:-1}.no-animation{transition:none}.no-shadow{box-shadow:none}.no-header .wb-body{top:0}.no-move:not(.min) .wb-title{pointer-events:none}.wb-body .wb-show{display:revert}";
var h=document.getElementsByTagName("head")[0];h.firstChild?h.insertBefore(aa,h.firstChild):h.appendChild(aa);var ba=document.createElement("div");ba.innerHTML="<div class=wb-header><div class=wb-control><span class=wb-min></span><span class=wb-max></span><span class=wb-full></span><span class=wb-close></span></div><div class=wb-drag><div class=wb-icon></div><div class=wb-title></div></div></div><div class=wb-body></div><div class=wb-n></div><div class=wb-s></div><div class=wb-w></div><div class=wb-e></div><div class=wb-nw></div><div class=wb-ne></div><div class=wb-se></div><div class=wb-sw></div>";function k(a,b,c,f){a&&a.addEventListener(b,c,f||!1)}function l(a,b){var c=window,f=m;c&&c.removeEventListener(a,b,f||!1)}function t(a,b){a.stopPropagation();b&&a.preventDefault()}function u(a,b,c){c=""+c;a["_s_"+b]!==c&&(a.style.setProperty(b,c),a["_s_"+b]=c)};/*
self.max &&*/
var x=[],A=[],ca={capture:!0,passive:!1},m={capture:!0,passive:!0},B,da=0,E=10,F,J,ha,K,P,ia;
function U(a,b){if(!(this instanceof U))return new U(a);B||ja();if(a){if(b){var c=a;a=b}if("string"===typeof a)c=a;else{var f=a.id;var d=a.index;var n=a.root;var p=a.template;c=c||a.title;var v=a.icon;var L=a.mount;var Q=a.html;var g=a.url;var q=a.width;var r=a.height;var w=a.minwidth;var C=a.minheight;var y=a.maxwidth;var z=a.maxheight;var ea=a.autosize;var D=a.overflow;var G=a.min;var H=a.max;var I=a.hidden;var fa=a.modal;var X=a.x||(fa?"center":0);var Y=a.y||(fa?"center":0);var M=a.top;var N=a.left;
var R=a.bottom;var S=a.right;var la=a.background;var O=a.border;var T=a.header;var Z=a["class"];var ma=a.oncreate;var ra=a.onclose;var sa=a.onfocus;var ta=a.onblur;var ua=a.onmove;var va=a.onresize;var wa=a.onfullscreen;var xa=a.onmaximize;var ya=a.onminimize;var za=a.onrestore;var Aa=a.onhide;var Ba=a.onshow;var Ca=a.onload}}this.g=(p||ba).cloneNode(!0);this.g.id=this.id=f||"winbox-"+ ++da;this.g.className="winbox"+(Z?" "+("string"===typeof Z?Z:Z.join(" ")):"")+(fa?" modal":"");this.g.winbox=this;
this.window=this.g;this.body=this.g.getElementsByClassName("wb-body")[0];this.h=T||35;A.push(this);la&&this.setBackground(la);O?u(this.body,"margin",O+(isNaN(O)?"":"px")):O=0;T&&(b=this.g.getElementsByClassName("wb-header")[0],u(b,"height",T+"px"),u(b,"line-height",T+"px"),u(this.body,"top",T+"px"));c&&this.setTitle(c);v&&this.setIcon(v);L?this.mount(L):Q?this.body.innerHTML=Q:g&&this.setUrl(g,Ca);M=M?V(M,P):0;R=R?V(R,P):0;N=N?V(N,K):0;S=S?V(S,K):0;c=K-N-S;v=P-M-R;y=y?V(y,c):c;z=z?V(z,v):v;w=w?V(w,
y):150;C=C?V(C,z):this.h;ea?((n||B).appendChild(this.body),q=Math.max(Math.min(this.body.clientWidth+2*O+1,y),w),r=Math.max(Math.min(this.body.clientHeight+this.h+O+1,z),C),this.g.appendChild(this.body)):(q=q?V(q,y):Math.max(y/2,w)|0,r=r?V(r,z):Math.max(z/2,C)|0);X=X?V(X,c,q):N;Y=Y?V(Y,v,r):M;this.x=X;this.y=Y;this.width=q;this.height=r;this.s=w;this.o=C;this.m=y;this.l=z;this.top=M;this.right=S;this.bottom=R;this.left=N;this.index=d;this.j=D;this.focused=this.hidden=this.full=this.max=this.min=!1;
this.onclose=ra;this.onfocus=sa;this.onblur=ta;this.onmove=ua;this.onresize=va;this.onfullscreen=wa;this.onmaximize=xa;this.onminimize=ya;this.onrestore=za;this.onhide=Aa;this.onshow=Ba;I?this.hide():this.focus();if(d||0===d)this.index=d,u(this.g,"z-index",d),d>E&&(E=d);H?this.maximize():G?this.minimize():this.resize().move();ka(this);(n||B).appendChild(this.g);ma&&ma.call(this,a)}U["new"]=function(a){return new U(a)};U.stack=function(){return A};
function V(a,b,c){"string"===typeof a&&("center"===a?a=(b-c)/2+.5|0:"right"===a||"bottom"===a?a=b-c:(c=parseFloat(a),a="%"===(""+c!==a&&a.substring((""+c).length))?b/100*c+.5|0:c));return a}
function ja(){B=document.body;B[J="requestFullscreen"]||B[J="msRequestFullscreen"]||B[J="webkitRequestFullscreen"]||B[J="mozRequestFullscreen"]||(J="");ha=J&&J.replace("request","exit").replace("mozRequest","mozCancel").replace("Request","Exit");k(window,"resize",function(){na();oa()});k(B,"mousedown",function(){ia=!1},!0);k(B,"mousedown",function(){if(!ia){var a=A.length;if(a)for(--a;0<=a;a--){var b=A[a];if(b.focused){b.blur();break}}}});na()}
function ka(a){W(a,"drag");W(a,"n");W(a,"s");W(a,"w");W(a,"e");W(a,"nw");W(a,"ne");W(a,"se");W(a,"sw");k(a.g.getElementsByClassName("wb-min")[0],"click",function(b){t(b);a.min?a.restore().focus():a.minimize()});k(a.g.getElementsByClassName("wb-max")[0],"click",function(b){t(b);a.max?a.restore().focus():a.maximize().focus()});J?k(a.g.getElementsByClassName("wb-full")[0],"click",function(b){t(b);a.fullscreen().focus()}):a.addClass("no-full");k(a.g.getElementsByClassName("wb-close")[0],"click",function(b){t(b);
a.close()||(a=null)});k(a.g,"mousedown",function(){ia=!0},!0);k(a.body,"mousedown",function(){a.focus()},!0)}function pa(a){x.splice(x.indexOf(a),1);oa();a.removeClass("min");a.min=!1;a.g.title=""}function oa(){for(var a=x.length,b={},c={},f=0,d;f<a;f++)d=x[f],d=d.left+":"+d.top,c[d]?c[d]++:(b[d]=0,c[d]=1);f=0;for(var n,p;f<a;f++)d=x[f],n=d.left+":"+d.top,p=Math.min((K-d.left-d.right)/c[n],250),d.resize(p+1|0,d.h,!0).move(d.left+b[n]*p|0,P-d.bottom-d.h,!0),b[n]++}
function W(a,b){function c(g){t(g,!0);a.focus();if("drag"===b){if(a.min){a.restore();return}if(!a.g.classList.contains("no-max")){var q=Date.now(),r=q-Q;Q=q;if(300>r){a.max?a.restore():a.maximize();return}}}a.min||(B.classList.add("wb-lock"),(p=g.touches)&&(p=p[0])?(g=p,k(window,"touchmove",f,m),k(window,"touchend",d,m)):(k(window,"mousemove",f,m),k(window,"mouseup",d,m)),v=g.pageX,L=g.pageY)}function f(g){t(g);p&&(g=g.touches[0]);var q=g.pageX;g=g.pageY;var r=q-v,w=g-L,C=a.width,y=a.height,z=a.x,
ea=a.y,D;if("drag"===b){if(a.g.classList.contains("no-move"))return;a.x+=r;a.y+=w;var G=D=1}else{if("e"===b||"se"===b||"ne"===b){a.width+=r;var H=1}else if("w"===b||"sw"===b||"nw"===b)a.x+=r,a.width-=r,G=H=1;if("s"===b||"se"===b||"sw"===b){a.height+=w;var I=1}else if("n"===b||"ne"===b||"nw"===b)a.y+=w,a.height-=w,D=I=1}H&&(a.width=Math.max(Math.min(a.width,a.m,K-a.x-a.right),a.s),H=a.width!==C);I&&(a.height=Math.max(Math.min(a.height,a.l,P-a.y-a.bottom),a.o),I=a.height!==y);(H||I)&&a.resize();G&&
(a.max&&(a.x=(q<K/3?a.left:q>K/3*2?K-a.width-a.right:K/2-a.width/2)+r),a.x=Math.max(Math.min(a.x,a.j?K-30:K-a.width-a.right),a.j?30-a.width:a.left),G=a.x!==z);D&&(a.max&&(a.y=a.top+w),a.y=Math.max(Math.min(a.y,a.j?P-a.h:P-a.height-a.bottom),a.top),D=a.y!==ea);if(G||D)a.max&&a.restore(),a.move();if(H||G)v=q;if(I||D)L=g}function d(g){t(g);B.classList.remove("wb-lock");p?(l("touchmove",f),l("touchend",d)):(l("mousemove",f),l("mouseup",d))}var n=a.g.getElementsByClassName("wb-"+b)[0];if(n){var p,v,L,
Q=0;k(n,"mousedown",c,ca);k(n,"touchstart",c,ca)}}function na(){var a=document.documentElement;K=a.clientWidth;P=a.clientHeight}e=U.prototype;e.mount=function(a){this.unmount();a.i||(a.i=a.parentNode);this.body.textContent="";this.body.appendChild(a);return this};e.unmount=function(a){var b=this.body.firstChild;if(b){var c=a||b.i;c&&c.appendChild(b);b.i=a}return this};
e.setTitle=function(a){var b=this.g.getElementsByClassName("wb-title")[0];a=this.title=a;var c=b.firstChild;c?c.nodeValue=a:b.textContent=a;return this};e.setIcon=function(a){var b=this.g.getElementsByClassName("wb-icon")[0];u(b,"background-image","url("+a+")");u(b,"display","inline-block");return this};e.setBackground=function(a){u(this.g,"background",a);return this};
e.setUrl=function(a,b){var c=this.body.firstChild;c&&"iframe"===c.tagName.toLowerCase()?c.src=a:(this.body.innerHTML='<iframe src="'+a+'"></iframe>',b&&(this.body.firstChild.onload=b));return this};e.focus=function(a){if(!1===a)return this.blur();if(!this.focused){a=A.length;if(1<a)for(var b=1;b<=a;b++){var c=A[a-b];if(c.focused){c.blur();A.push(A.splice(A.indexOf(this),1)[0]);break}}u(this.g,"z-index",++E);this.index=E;this.addClass("focus");this.focused=!0;this.onfocus&&this.onfocus()}return this};
e.blur=function(a){if(!1===a)return this.focus();this.focused&&(this.removeClass("focus"),this.focused=!1,this.onblur&&this.onblur());return this};e.hide=function(a){if(!1===a)return this.show();if(!this.hidden)return this.onhide&&this.onhide(),this.hidden=!0,this.addClass("hide")};e.show=function(a){if(!1===a)return this.hide();if(this.hidden)return this.onshow&&this.onshow(),this.hidden=!1,this.removeClass("hide")};
e.minimize=function(a){if(!1===a)return this.restore();F&&qa();this.max&&(this.removeClass("max"),this.max=!1);this.min||(x.push(this),oa(),this.g.title=this.title,this.addClass("min"),this.min=!0,this.focused&&(this.blur(),Da()),this.onminimize&&this.onminimize());return this};function Da(){var a=A.length;if(a)for(--a;0<=a;a--){var b=A[a];if(!b.min){b.focus();break}}}
e.restore=function(){F&&qa();this.min&&(pa(this),this.resize().move(),this.onrestore&&this.onrestore());this.max&&(this.max=!1,this.removeClass("max").resize().move(),this.onrestore&&this.onrestore());return this};e.maximize=function(a){if(!1===a)return this.restore();F&&qa();this.min&&pa(this);this.max||(this.addClass("max").resize(K-this.left-this.right,P-this.top-this.bottom,!0).move(this.left,this.top,!0),this.max=!0,this.onmaximize&&this.onmaximize());return this};
e.fullscreen=function(a){this.min&&(pa(this),this.resize().move());if(!F||!qa())this.body[J](),F=this,this.full=!0,this.onfullscreen&&this.onfullscreen();else if(!1===a)return this.restore();return this};function qa(){F.full=!1;if(document.fullscreen||document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement)return document[ha](),!0}
e.close=function(a){if(this.onclose&&this.onclose(a))return!0;this.min&&pa(this);A.splice(A.indexOf(this),1);this.unmount();this.g.remove();this.g.textContent="";this.g=this.body=this.g.winbox=null;this.focused&&Da()};e.move=function(a,b,c){a||0===a?c||(this.x=a?a=V(a,K-this.left-this.right,this.width):0,this.y=b?b=V(b,P-this.top-this.bottom,this.height):0):(a=this.x,b=this.y);u(this.g,"left",a+"px");u(this.g,"top",b+"px");this.onmove&&this.onmove(a,b);return this};
e.resize=function(a,b,c){a||0===a?c||(this.width=a?a=V(a,this.m):0,this.height=b?b=V(b,this.l):0,a=Math.max(a,this.s),b=Math.max(b,this.o)):(a=this.width,b=this.height);u(this.g,"width",a+"px");u(this.g,"height",b+"px");this.onresize&&this.onresize(a,b);return this};
e.addControl=function(a){var b=a["class"],c=a.image,f=a.click;a=a.index;var d=document.createElement("span"),n=this.g.getElementsByClassName("wb-control")[0],p=this;b&&(d.className=b);c&&u(d,"background-image","url("+c+")");f&&(d.onclick=function(v){f.call(this,v,p)});n.insertBefore(d,n.childNodes[a||0]);return this};e.removeControl=function(a){(a=this.g.getElementsByClassName(a)[0])&&a.remove();return this};e.addClass=function(a){this.g.classList.add(a);return this};
e.removeClass=function(a){this.g.classList.remove(a);return this};e.toggleClass=function(a){return this.g.classList.contains(a)?this.removeClass(a):this.addClass(a)};window.WinBox=U;}).call(this);

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,51 @@
function waitForAScene(callback) {
let scene = document.querySelector("a-scene")
if( scene ) return callback(scene)
// Create a MutationObserver to monitor the DOM for changes
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
// Check if new nodes are added
if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
for (const node of mutation.addedNodes) {
// Check if the added node is <a-scene> or contains one
if (node.nodeName === "A-SCENE" || node.querySelector?.("a-scene")) {
observer.disconnect(); // Stop observing once found
callback(node.nodeName === "A-SCENE" ? node : node.querySelector("a-scene"));
return;
}
}
}
}
});
// Start observing the entire document for child node additions
observer.observe(document.documentElement, {
childList: true, // Observe direct children changes
subtree: true, // Observe all levels of the DOM
});
}
// Example usage
waitForAScene((aScene) => {
if( aScene.innerHTML.match(/ isoterminal/) ) return; // prevent duplicates
// Inject the external script
const xrshScript = document.createElement("script");
xrshScript.src = chrome.runtime.getURL("xrsh.js");
document.head.appendChild(xrshScript);
// Add the A-Frame entity after the script loads
xrshScript.onload = () => {
const scene = document.querySelector("a-scene");
if (scene) {
const entity = document.createElement("a-entity");
entity.setAttribute("isoterminal", "");
entity.setAttribute("position", "0 1.6 -0.3");
scene.appendChild(entity);
}
};
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,24 @@
{
"manifest_version": 3,
"name": "XRSH",
"version": "1.0",
"description": "Injects XRSH Terminal into WebXR [AFRAME] scenes.",
"permissions": ["scripting", "activeTab"],
"host_permissions": ["<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_end"
}
],
"web_accessible_resources": [
{
"resources": ["xrsh.js"],
"matches": ["<all_urls>"]
}
],
"icons": {
"128": "icon.png"
}
}

View file

@ -0,0 +1 @@
../../xrsh.js

Binary file not shown.

View file

@ -8,7 +8,7 @@
*/
:root {
--xrsh-primary: #3a51ff;
--xrsh-primary: #00AA;
--xrsh-primary-fg: #FFF;
--xrsh-light-primary: #00a3Ff;
--xrsh-secondary: #872eff;
@ -17,9 +17,11 @@
--xrsh-dark-gray: #343334;
--xrsh-gray: #424280;
--xrsh-white: #fdfdfd;
--xrsh-black: #001c;
--xrsh-light-gray: #efefef;
--xrsh-lighter-gray: #e4e2fb96;
--xrsh-window-radius: 10px;
--xrsh-control-radius: 7px;
--xrsh-font-sans-serif: system-ui, -apple-system, segoe ui, roboto, ubuntu, helvetica, cantarell, noto sans, sans-serif;
--xrsh-font-monospace: menlo, monaco, lucida console, liberation mono, dejavu sans mono, bitstream vera sans mono, courier new, monospace, serif;
--xrsh-font-size-0: 12px;
@ -54,7 +56,7 @@ a,a:visited,a:active{
*/
button,.btn,input[type=submit]{
border-radius:7px;
border-radius: var(--xrsh-control-radius);
background: var(--xrsh-primary);
color: var(--xrsh-primary-fg);
transition:0.3s;
@ -98,31 +100,55 @@ button,input,.btn{
*/
.winbox {
box-shadow:none !important;
background:transparent !important;
background: transparent !important;
}
.winbox .wb-body{
background: var(--xrsh-dark-gray);
margin-top: -6px !important;
/*margin-top: -6px !important;*/
z-index: 100;
border: 1px solid #FFF3;
border-radius:7px;
border-radius:0px 0px var(--xrsh-window-radius) var(--xrsh-window-radius);
}
.winbox .wb-header{
background:transparent !important;
background: var(--xrsh-dark-gray);
z-index:1000;
font-weight: bold;
border-radius: var(--xrsh-window-radius) var(--xrsh-window-radius) 0px 0px;
line-height:36px;
}
.winbox.max .wb-header{
border-radius:0px;
}
.XR .winbox .wb-header{
border-radius:0px !important;
margin-top:0px;
}
.XR .winbox .wb-control .xr {
display:block;
}
.winbox .wb-control .xr {
display:none;
background:transparent !important;
position: absolute;
top: -2px;
cursor:pointer;
}
.winbox .wb-control .xr.xr-wb-close,
.winbox .wb-control .xr.xr-wb-min{
right: 2px;
}
.winbox .wb-body{
top:0px;
top: 35 !important;
padding-top:35px;
}
.winbox .wb-control{
padding-right:5px;
height:29px;
color:#FFF;
z-index:1001;
}
.winbox .wb-drag{
padding-left:19px;
@ -160,7 +186,6 @@ button,input,.btn{
background: var(--xrsh-white);
}
/*
* icons for non-XR (please source from https://css.gg
*

View file

@ -1,14 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>xrsh v0.142</title>
<title>xrsh v0.143</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="./index.css"></link>
<script src="./assets/aframe.min.js"></script>
<script src="./assets/xrfragment.aframe.js"></script>
<script src="com/require.js"></script>
<script src="com/isoterminal.js"></script>
<!-- todo fix lazy initialisation of require.js -->
<script src="com/launcher.js"></script>
<script src="com/helloworld-window.js"></script>
<script src="com/pressable.js"></script>
</head>
<body style="background:linear-gradient( 45deg, #324, #8c74ff)">
@ -18,42 +24,60 @@
renderer="colorManagement: false; stencil: true; antialias:true; highRefreshRate:true; foveationLevel: 0.5;"
xr-mode-ui="XRMode: xr"
obb-collider="showColliders:false"
raycaster="objects: [html]; interval:100;">
raycaster="objects: [html]; interval:100;"
>
<!--
<a-assets timeout="1000">
<a-asset-item id="environment" src="https://coderofsalvation.github.io/xrsh-media/assets/background.glb"></a-asset-item>
<a-mixin id="menuitem" geometry="primitive: plane; width: 0.15; height: 0.15; depth: 0.02" obb-collider="size: 0.03 0.03 0.03" ></a-mixin>
<a-mixin id="menubutton" geometry="primitive: circle; radius: 0.025" material="side: double; color:#4C73FE"
obb-collider="size: 0.03 0.03 0.03" position="-0.003 -0.027 -0.077" rotation="94.53 -6.35 -59.0"></a-mixin>
</a-assets>
<a-entity isoterminal="iso: ./../xrsh.iso; overlayfs: /package.overlayfs.zip; bootMenuURL: 1" position="0 1.6 -0.3">
<a-entity launcher pressable position="0 -0.315 0"></a-entity>
</a-entity>
<a-entity helloworld></a-entity>
<a-entity helloworld-window></a-entity>
<a-entity save></a-entity>
<a-entity launcher="attach: #left-hand; fingerTip: #right-hand;" dom position="-0.017 -0.094 -0.085" rotation="133.19 -24.75 -203.1"></a-entity>
<a-entity launcher-optional="comps: cast,aframestats,paste,save,xrfragments,example/helloworld-iframe,example/helloworld-htmlform,example/helloworld-window,look-controls-toggle,wasd-controls-toggle"></a-entity>
<a-entity noxrf gltf-model="#environment" hide-on-enter-ar></a-entity>
-->
<a-entity isoterminal="iso: ./../xrsh.iso" position="0 1.6 -0.3"></a-entity>
<a-entity helloworld-window pressable position="0 1.6 0"></a-entity>
<a-entity id="player" >
<a-entity camera="fov:90" position="0 1.6 0" id="camera" wasd-controls com="uri: com/control/gaze-touch-to-click.js"></a-entity>
<a-entity id="left-hand" hand-tracking-grab-controls="hand: left; modelColor: #cccccc; hoverEnabled:true" laser-controls="hand: left" raycaster="objects:.ray,[html]" blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor">
<a-entity rotation="-35 0 0" position="0 0.1 0" id="navigator">
<a-entity id="back" xrf-button="label: <; width:0.05; action: history.back()" position="-0.025 0 0" class="ray"></a-entity>
<a-entity id="next" xrf-button="label: >; width:0.05; action: history.forward()" position=" 0.025 0 0" class="ray"></a-entity>
</a-entity>
<a-entity id="player">
<a-entity camera="fov:90" position="0 1.6 0" id="camera" wasd-controls gaze-touch-to-click></a-entity>
<a-entity id="left-hand" hand-tracking-grab-controls="hand: left; modelColor: #EEEEEE; hoverEnabled:true"
laser-controls="hand: left"
raycaster="far:0.04"
blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor"
>
</a-entity>
<a-entity id="right-hand" hand-tracking-grab-controls="hand: right; modelColor: #EEEEEE; hoverEnabled:true"
laser-controls="hand: right"
raycaster="objects:.ray,[html]"
raycaster="far:0.04"
blink-controls="cameraRig:#player; teleportOrigin: #camera; collisionEntities: #floor"
com="uri: com/control/pinch-to-teleport.js; rig: #player"></a-entity>
____pinch-to-teleport="rig: #player"></a-entity>
</a-entity>
</a-scene>
</body>
<script>
// HOWDY DEVELOPER!
// for a REPL boilerplate see this codepen instead: https://codepen.io/coderofsalvation/pen/wBwRpew
document.querySelector('a-scene').addEventListener('isoterminal_init', function(e){
// example custom REPL (https://xrsh.isvery.ninja/#Custom%20REPLs)
const myREPL = {
key: "f",
prompt: "\r\nmyrepl> ",
title: (opts) => `other awesome NLnet FOSS projects ❤️`,
init: function( mainmenu ){
window.open('https://nlnet.nl/project/current.html','_blank')
this.send("\n\rreturning to mainmenu")
mainmenu()
},
keyHandler: function(ch){
this.send(ch) // echo keys to user
},
cmdHandler: function(cmd){
this.send("\r\n"+cmd) // only works after commenting mainmenu()\n")
this.send(myREPL.prompt)
}
}
ISOTerminal.prototype.boot.menu.push(myREPL)
})
</script>
</html>

View file

@ -1,28 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="./index.css" rel="stylesheet">
</head>
<body>
<h1>Welcome to XRSHell</h1>
<br>
<img src="https://i.imgur.com/BW22wrb.png"/>
<br><br>
The <b>xrsh</b> (xrshell) brings the <a href="https://en.wikipedia.org/wiki/Free_and_open-source_software" target="_blank">FOSS</a>- and <a href="https://en.wikipedia.org/wiki/Linux" target="_blank">Linux</a>-soul to <a href="https://en.wikipedia.org/wiki/WebXR" target="_blank">WebXR</a>, promoting the use of (interactive text) terminal and user-provided operating systems inside WebXR.
<br><br>Technically, <b>xrsh</b> is a bundle of freshly created re-usable FOSS WebXR components.<br>These provide a common filesystem interface for interacting with WebXR, offering the well-known linux/unix toolchain including a commandline to invoke, store, edit and run WebXR utilities - regardless of their implementation.
<br><br>Think of it as termux for the VR/AR headset browser, which can be used to e.g. livecode (using terminal auto-completion!) for XR component (registries).
<br>
<ul>
<li><a href="https://forgejo.isvery.ninja/xrsh" target="_blank">source xrsh</a></li>
<li><a href="https://forgejo.isvery.ninja/xrsh-apps" target="_blank">source xrsh apps</a></li>
<li><a href="https://forgejo.isvery.ninja/xrsh-media" target="_blank">roadmap meeting recordings</a></li>
</ul>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
/home/leon/.ctags.js

View file

@ -1,37 +1,56 @@
term = document.querySelector('[isoterminal]').components.isoterminal.term
convert = ISOTerminal.prototype.convert
isoterminal = document.querySelector("[isoterminal]")
console.test("com/isoterminal/ISOTerminal.js", async () => {
isoterminal.addEventListener("ready", function(){
term = isoterminal.components.isoterminal.term
convert = ISOTerminal.prototype.convert
console.test.tests = {} // empty previous tests
console.test("com/isoterminal/ISOTerminal.js", async () => {
term.worker.create_file("foo", convert.toUint8Array("hello") )
.then( (res) => {
term.worker.read_file("foo")
.then( (res) => {
try{
let data = convert.Uint8ArrayToString( res )
console.assert( data == "hello", "worker.create_file")
}catch(e){
console.assert( false, "worker.create_file")
}
})
})
.catch(console.error)
.finally(console.dir)
term.worker.read_file("root/.profile")
.then( (res) => {
try{
let data = convert.Uint8ArrayToString( res )
console.assert( data.length, "worker.postMessage.promise()")
}catch(e){
console.assert( false, "worker.postMessage.promise()")
}
})
.catch(console.error)
.finally(console.dir)
})
console.test("com/isoterminal/ISOTerminal.js", async () => {
console.test("com/isoterminal/ISOTerminal.js", async () => {
term.worker.create_file("foo", convert.toUint8Array("hello") )
.then( (res) => {
term.worker.read_file("foo")
.then( (res) => {
try{
let data = convert.Uint8ArrayToString( res )
console.assert( data == "hello", "worker.create_file")
console.assert( data.length && data == "hello", "worker.postMessage.promise()")
}catch(e){
console.assert( false, "worker.create_file")
console.assert( false, "worker.postMessage.promise()")
}
})
.catch(console.error)
.finally(console.dir)
})
.catch(console.error)
.finally(console.dir)
console.test.run()
})
console.test("com/isoterminal.js", async () => {
console.assert( AFRAME.components.isoterminal != undefined, "AFRAME.components.isoterminal")
})
console.test("xrsh.iso", async () => {
console.assert( false, "create testsuite.zip package which tests iso")
})

10
src/tests/index.js Normal file
View file

@ -0,0 +1,10 @@
const run = async function(){
await AFRAME.utils.require({
"test_util": "tests/util.js",
"test_isoterminal":"tests/ISOTerminal.js"
})
console.test.run()
}
run()

View file

@ -1,20 +1,23 @@
// minimalistc testrunner
console.test = async (name,cb) => {
window.console.test = async (name,cb) => {
let tests = console.test.tests = console.test.tests || {}
tests[name] = tests[name] || []
tests[name].push(cb)
console.test.run = async () => {
for( let name in tests ){
console.log("\x1b[34m\x1b[36;49m"+name+"\x1B[m")
for( let test in tests[name] ){
await tests[name][test]()
}
}
}
}
console.assert = ((assert) => (a,reason,data) => {
window.console.test.run = async (cb) => {
const tests = window.console.test.tests
for( let name in tests ){
console.log("\x1b[34m\x1b[36;49m"+name+"\x1B[m")
for( let test in tests[name] ){
await tests[name][test]()
}
}
if( cb ) cb()
}
window.console.assert = ((assert) => (a,reason,data) => {
console.log("\x1b[34m\x1b[36;49m♥ \x1B[m"+reason)
assert.call( console, a, {reason} )
if( !a ){

@ -1 +1 @@
Subproject commit 1b5cf3febbb0f451003c56d4579294ca57e447f0
Subproject commit 10bbfd27e21a1b7368c38432178309263662aef6

File diff suppressed because one or more lines are too long

60
xrsh Executable file
View file

@ -0,0 +1,60 @@
#!/bin/sh
PORT=9090
PROCFILE=/tmp/.xrsh
usage(){ echo "Usage: xrsh [--keyboard] [--kill]"; exit; }
assert_cmds(){
for cmd in $1; do
command -v $cmd &>/dev/null || { echo "error: please install $cmd (not found)"; exit 1; }
done
}
showip(){
{ # naive way of getting network ip
command -v ip &>/dev/null && ip addr show
command -v ifconfig &>/dev/null && ifconfig
} | grep 'inet ' | grep -v ' 127' | awk '! /addr:/ { gsub(/\/.*/,"",$2); if( !SEEN[$2] ) print $2; SEEN[$2]=1 }'
}
setupcerts(){
test -f ~/.websocat/cert.pem && return 0
mkdir ~/.websocat 2>/dev/null || true
echo "--- generating temporary SSL certs (press enter to all questions) ---"
#openssl req -x509 -newkey rsa:4096 -keyout ~/.websocat/key.pem -out ~/.websocat/cert.pem -days 365
openssl req -x509 -newkey rsa:2048 -new -nodes -keyout ~/.websocat/key.pem -out ~/.websocat/cert.pem -days 3650
openssl pkcs12 -export -out ~/.websocat/q.pkcs12 -inkey ~/.websocat/key.pem -in ~/.websocat/cert.pem
wget "https://curl.haxx.se/ca/cacert.pem" -O ~/.websocat/cacert.pem
}
keyboard(){
assert_cmds websocat pkill
trap "stty sane; trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT # cleanup processes when exit
echo $$ > $PROCFILE
echo ""
echo " 1. type 'k' (remote keyboard) in xrsh"
echo " 2. enter ipaddress: $(showip)"
echo ""
echo "warn: CTRL-C is forwarded too"
echo "warn: to exit this app run: $0 --kill"
echo "warn: this terminal is now in raw sendmode, expect weird characters!"
stty raw
if test -n "$SSL"; then
setupcerts
websocat -E -b -s --pkcs12-der ~/.websocat/q.pkcs12 0.0.0.0:$PORT 2>&1
else
websocat -E -b -s 0.0.0.0:$PORT 2>&1 # http-only
fi
}
# launch!
test -n "$1" || { echo "usage: xrsh [--ssl] [--keyboard] [--kill]"; exit; }
for arg in $*; do
case $arg in
--kill) pkill -P $(cat $PROCFILE); exit ;;
--ssl) export SSL=1; ;;
--keyboard) keyboard "$@"; ;;
esac
done

BIN
xrsh.com

Binary file not shown.

View file

@ -1 +1 @@
56341bacae1c5574767d2488c8fb33633bbfca06082943403f06b5ebebf6ecfd xrsh.com
e791dba58adf568d34648eeed71e047d60b126b3dd5a6d81306a4307c5b7c3ad xrsh.com

36
xrsh.html Normal file
View file

@ -0,0 +1,36 @@
<script src="https://aframe.io/releases/1.6.0/aframe.min.js"></script>
<script src="https://xrsh.isvery.ninja/xrsh.js"></script>
<a-scene>
<a-entity isoterminal position="0 1.6 -0.3"></a-entity>
<a-entity id="left-hand" hand-tracking-grab-controls="hand: left; modelColor: #EEEEEE; hoverEnabled:true"
laser-controls="hand: left" raycaster="objects:.ray,[html]"></a-entity>
<a-entity id="right-hand" hand-tracking-grab-controls="hand: right; modelColor: #EEEEEE; hoverEnabled:true"
laser-controls="hand: right"
raycaster="objects:.ray,[html]"></a-entity>
</a-scene>
<script>
document.querySelector('a-scene').addEventListener('isoterminal_init', function(e){
// override/extend bootmenu-array with your own REPL(s)
// see com/isoterminal/feat/boot.REPL.*.js for examples
ISOTerminal.prototype.boot.menu.push({
key: "f",
title: (opts) => `other awesome NLnet FOSS projects ❤️`,
init: function( mainmenu ){
window.open('https://nlnet.nl/project/current.html','_blank')
// return to main menu
mainmenu()
},
keyHandler: function(ch){
this.send("\n\ryou typed:"+ch) // write to term
}
})
// AFRAME exposes THREE by default
console.log( THREE )
})
</script>

View file

@ -1 +1 @@
src/xrsh-buildroot/xrsh.iso
xrsh.iso.buildroot

1
xrsh.iso.buildroot Symbolic link
View file

@ -0,0 +1 @@
../xrsh-buildroot/dist/v86-linux.iso

1
xrsh.iso.repository Symbolic link
View file

@ -0,0 +1 @@
src/xrsh-buildroot/xrsh.iso

1
xrsh.iso.wtux Symbolic link
View file

@ -0,0 +1 @@
../wtux/output/wtux.iso

4503
xrsh.js Normal file

File diff suppressed because one or more lines are too long

9
xrsh.nix.log Normal file
View file

@ -0,0 +1,9 @@
env-vars:
CHANNEL=nixpkgs
CMD=nix-build
channels:
nixos https://nixos.org/channels/nixos-24.05
nixos-22.11 https://nixos.org/channels/nixos-22.11
nixos-24.05 https://nixos.org/channels/nixos-24.05
nixos-unstable https://nixos.org/channels/nixos-unstable
/nix/store/p3314mbnga40x8sdmfx1xzc0cdbqvf50-xrsh-0.221