@ai-ecoverse/slicc-bios 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -168,7 +168,7 @@ The Files panel lists `/opt/grammars/node_modules` but doesn't scan it.
|
|
|
168
168
|
|
|
169
169
|
#### Optional packages
|
|
170
170
|
|
|
171
|
-
Below the system rows, Install / Update offers **Optional packages** (spectrum ≥ 1.42.0): tools that seven doesn't preinstall, each at the version the homescoop coordinator certified. The catalog is [`src/packages/optional/`](src/packages/optional/): `package.json` pins each package exactly, `package-lock.json` (made with `npm install --package-lock-only --ignore-scripts`, never installed) holds its integrity, and `catalog.json` gives its id, label, description, commands, tarball size and `requires`. A test keeps the three in step. Today it offers git, OpenSSH, Python, uv, Node.js (slicc-jsh's `node` and `jsh`), `sliccy:browser` for `.jsh` scripts, Ruby, Perl, esbuild, TypeScript, Biome, the PDF tools (poppler), qpdf, rsync, buf, screen, SQLite, dig and GnuPG.
|
|
171
|
+
Below the system rows, Install / Update offers **Optional packages** (spectrum ≥ 1.42.0): tools that seven doesn't preinstall, each at the version the homescoop coordinator certified. The catalog is [`src/packages/optional/`](src/packages/optional/): `package.json` pins each package exactly, `package-lock.json` (made with `npm install --package-lock-only --ignore-scripts`, never installed) holds its integrity, and `catalog.json` gives its id, label, description, commands, tarball size and `requires`. A test keeps the three in step. Today it offers git, OpenSSH, Python, uv, Node.js (slicc-jsh's `node` and `jsh`), `sliccy:browser` for `.jsh` scripts, Ruby, Perl, esbuild, TypeScript, Biome, the PDF tools (poppler), qpdf, rsync, buf, screen, SQLite, dig, websocat and GnuPG.
|
|
172
172
|
|
|
173
173
|
- **Install** runs `pnpm add -g <package>@<version>` in the page's kernel, as a user would, under the Web Lock `slicc-optional`, so the commands work at once in every open shell. pnpm 12 gives each global add its own project under `$PNPM_HOME/global/v11/`; bios reads `PNPM_HOME` from the kernel's environment. Afterwards `os/packages.js` reads that project's `pnpm-lock.yaml`: every package in it, the one added and each dependency, must be a version in the catalog's lockfile or the base set's, with that integrity. homescoop pins `@ai-ecoverse/*` dependencies exactly (uv → Python, git → bash), so the catalog's lockfile names them all. Anything else, a dependency pnpm resolved to another version included, removes the package again and fails the row with *This version doesn't match the tested build*. An entry's `requires` (uv needs Python) are installed first.
|
|
174
174
|
- **State** comes from pnpm's global projects, not from a list of bios's own, so a package installed by hand shows as installed with its version. One older than the catalog's offers **Update**, which adds the catalog's version; one at or above it offers **Remove**. bios never downgrades.
|
|
@@ -309,7 +309,7 @@ seven can also join a tailnet, with a patched build of Tailscale's wasm client (
|
|
|
309
309
|
- A device that reconnects replaces only its own process's link, so `slicc <join> prompt` doesn't drop that machine's `follow`. Control-only links (`caps: []`) get no `.slicc.internal` name and no exit.
|
|
310
310
|
- **Folders (`fs`):** a CLI started with `--mount <path>[:<name>][:ro]` lists its folders in HELLO, and later in `OPEN { kind: 'mounts' }` updates; the page offers cap `mounts`. Each is a `hostfs` source named `<device>/<name>`, so `mount -t hostfs lars-mbp/proj /mnt/proj` mounts it, and nothing is mounted unless someone asks. A bare source with no `<device>/`, as slicc-node named its folders (`mount -t hostfs project /mnt/p`, or one remembered from then), is the folder of that name on the CLI linked on this computer, when exactly one local CLI shares one. The device's row in Linked devices lists its folders (`folders`, with a Read-only badge; spectrum ≥ 1.58.0): **Mount** (`mountFolder(source)`) mounts one at `/mnt/<device>/<name>` (a folder named `.` or `..` is never listed), and **Eject** (`ejectFolder(source)`) unmounts it. The Files panel's Mounted strip shows each `hostfs` mount's source (`mountInfo()`), so `/mnt/proj · lars-mbp/proj` reads as another computer's folder. A mounted linked folder stays with the CLI process it was first granted from (`slicc-os.link-sources`), even if that process comes back under another name. If that process isn't linked, the folder goes to whichever process has the name now, but only when no other process with the same host name shares a folder of that name; otherwise it waits. So a remembered `lars-mbp/proj` never lands on another process's `proj`. A remembered linked folder that is mounted again before its CLI is back stays `nomedium`, and fills in when the CLI links. The kernel's `hostfs` hook answers such a source with a `MessagePort` (slicc-kernel ≥ 1.54.9), and the page serves it with `serveHostfsPort` over `OPEN { kind: 'fs', mount, op, … }` streams: `list` collects its NDJSON, a read over 64 KiB and every write get their own channel, and `watch` streams the CLI's change events. A read-only kernel mount, or a read-only export, sends `readonly: true` on every OPEN. A link that drops makes the mount `nomedium` until the CLI is back; files that were open reopen by path and continue if the host didn't change them.
|
|
311
311
|
- **SSH host key:** the CLI's HELLO carries its host key, and the page writes `<host>.slicc.internal,<address> <key>` into the system-wide `/etc/ssh/ssh_known_hosts`, replacing older entries for that name or address, so `ssh` never trusts a key on first sight, whichever user runs it. Seven manages these keys, not the user, and OpenSSH looks up a user's own file under the passwd home, which isn't always `$HOME`.
|
|
312
|
-
- **Tests:** `test/integration/remote.test.mjs` runs the real `slicc watch`, `slicc prompt` and `slicc abort` with `--signal stdio` against seven's real agent and a fake Bedrock. It also leads a fake tray hub and sends a `webhook.event`, which reaches the agent as a webhook lick (without its `authorization` header) and starts a run. `test/integration/tray.test.mjs` leads a fake tray hub and links a follower in the page through it, then rotates and unlinks. `test/integration/link.test.mjs` links a fake node in the page over a real `RTCPeerConnection`, and, with `SLICC_CLI` set, the real `slicc attach --signal stdio`, relaying its NDJSON through the CDP binding: raw TCP and the http kind; kernel `ssh` with strict host-key checking against `--runner sh -c`, after `pnpm add -g @ai-ecoverse/wasix-openssh`; and, with the link as the exit, a name from the CLI's `--hosts` file, then refused under `--deny`; and `<port>.kernel.localhost` through the CLI's listener into a kernel server (`httptest`), with 502 for a closed port and the facade refused; a folder shared with `--mount`, mounted as `ref-node/proj`, read, written, seen changing on the host, and refused for writes when mounted `ro`; a second headless Chromium shared with `--cdp-extra`, listed and driven by `playwright-cli --runtime ref-node/<id>`; and a program WebSocket from kernel `bash` through the proxy to a `ws` echo server on the CLI's loopback: text, binary, the subprotocol, a close from each end, and `EACCES` under `--deny`; and a kernel `python3` UDP socket (after `pnpm add -g @ai-ecoverse/wasix-python`) to a UDP echo server on the CLI's loopback, unconnected and connected, and `EACCES` on a connected socket under `--deny`, as with the fake node's own refusal. CI runs the CLI from npm, the pinned `@ai-ecoverse/slicc` devDependency.
|
|
312
|
+
- **Tests:** `test/integration/remote.test.mjs` runs the real `slicc watch`, `slicc prompt` and `slicc abort` with `--signal stdio` against seven's real agent and a fake Bedrock. It also leads a fake tray hub and sends a `webhook.event`, which reaches the agent as a webhook lick (without its `authorization` header) and starts a run. `test/integration/tray.test.mjs` leads a fake tray hub and links a follower in the page through it, then rotates and unlinks. `test/integration/link.test.mjs` links a fake node in the page over a real `RTCPeerConnection`, and, with `SLICC_CLI` set, the real `slicc attach --signal stdio`, relaying its NDJSON through the CDP binding: raw TCP and the http kind; kernel `ssh` with strict host-key checking against `--runner sh -c`, after `pnpm add -g @ai-ecoverse/wasix-openssh`; and, with the link as the exit, a name from the CLI's `--hosts` file, then refused under `--deny`; and `<port>.kernel.localhost` through the CLI's listener into a kernel server (`httptest`), with 502 for a closed port and the facade refused; a folder shared with `--mount`, mounted as `ref-node/proj`, read, written, seen changing on the host, and refused for writes when mounted `ro`; a second headless Chromium shared with `--cdp-extra`, listed and driven by `playwright-cli --runtime ref-node/<id>`; and a program WebSocket from kernel `bash` through the proxy to a `ws` echo server on the CLI's loopback: text, binary, the subprotocol, a close from each end, and `EACCES` under `--deny`; kernel `websocat`, installed from the catalog, to a `ws` echo on the CLI's loopback and, without `-k`, to `wss://echo.sliccy.ai/` (SLICC's echo, behind Cloudflare's certificate), so its own TLS checks the chain over raw TCP through the link, then failing at once under Directly and with no exit, and its `cmd:`, `exec:` and `sh-c:` refused at startup; and a kernel `python3` UDP socket (after `pnpm add -g @ai-ecoverse/wasix-python`) to a UDP echo server on the CLI's loopback, unconnected and connected, and `EACCES` on a connected socket under `--deny`, as with the fake node's own refusal. CI runs the CLI from npm, the pinned `@ai-ecoverse/slicc` devDependency.
|
|
313
313
|
- **As the exit:** a CLI linked on this computer (`npx sliccy@next`) is the exit by itself until the user chooses one, so the kernel's HTTP and raw TCP get past CORS at once, as slicc-node's proxy did; a Tailscale exit node that is on comes first. A remote device that offers to be a default exit carries other traffic only once it's chosen. The Network panel's **Internet traffic** picker (`setExit`) is one choice across Directly, Tailscale exit nodes and linked devices: choosing a device turns off Tailscale's exit node, and choosing Tailscale clears the device. The choice of a device is kept in `localStorage` (`slicc-os.exit`), and while that device isn't connected, after a reload or while it reconnects, internet traffic **waits**: raw connections get `ENETUNREACH` and HTTP fails, rather than going out directly. Choosing Directly sends it directly again and is kept (`direct`), so a local CLI doesn't take it over, while a Tailscale exit node turned on later still does; unlinking the chosen exit device goes back to the automatic choice.
|
|
314
314
|
- **What the agent sees:** the transport's `traits` name the default exit while there is one, so the agent can say how its fetches go. `traits.exit` is `{ kind, caps }`:
|
|
315
315
|
- **`kind`:** `local` (a CLI on this computer), `remote` (a chosen linked device) or `tailnet` (a Tailscale exit node);
|
|
@@ -326,6 +326,7 @@ seven can also join a tailnet, with a patched build of Tailscale's wasm client (
|
|
|
326
326
|
- **When nothing carries it:** an exit without WebSockets (a CLI without cap `ws`) answers `502`. A held exit waits as HTTP does.
|
|
327
327
|
- **No secrets yet:** a handshake whose URL or headers carry a vault placeholder (`fnox_proxy_…`) is refused (`EACCES`, "secrets in WebSocket handshakes aren't supported yet"), so the placeholder never leaves seven.
|
|
328
328
|
- **Never through the page:** seven never opens a browser WebSocket itself. Unlike `fetch`, a browser WebSocket can't leave out the user's cookies for the site it reaches, so a program could act as the user there. With **Directly**, or no exit, a WebSocket is `501` with a hint to link a slicc CLI or use a Tailscale exit node.
|
|
329
|
+
- **websocat** (the catalog's, an upstream alpha) doesn't use the proxy: it dials raw TCP and does its own TLS against its embedded roots, so `ws://` and `wss://` hosts outside seven need an exit for raw TCP, a linked slicc CLI or a Tailscale exit node. Without one it fails at once (`Network unreachable`, or `No such file or directory` for a name).
|
|
329
330
|
- **UDP (`udp`):** a WASIX program's datagram socket (`AF_INET`/`AF_INET6` `SOCK_DGRAM`, such as Python's `socket` or a resolver) reaches a routed address through the exits, as `connect()` does. The kernel opens one uplink socket per program socket and family on its first routed send, and the router picks its exit then, by that first destination: a route claim (a linked device's own address, a tailnet address), then the default exit. Every later datagram of that socket goes through the same exit, whatever its destination, until the socket closes or that exit's socket ends. `traits.udp` is always `true`, because the kernel reads the uplink's traits once at start; with no exit that carries UDP (none, Directly, a held exit, a CLI without cap `udp`), a send fails with `ENETUNREACH`.
|
|
330
331
|
- **A linked CLI** with cap `udp` (slicc CLI ≥ 1.42.0) carries it as `OPEN { kind: 'udp', family }` (`os/link-udp.js`). Each datagram is a record, both ways: a type byte (`1` a datagram, `2` unreachable), a big-endian `u16` host length, the host, a `u16` port, a `u32` length, then the payload. Its own `<host>.slicc.internal` address goes to the CLI's `127.0.0.1`, and replies from there come back from that address, so a connected socket accepts them.
|
|
331
332
|
- **What's carried:** datagrams of at most 65 507 bytes (IPv4) or 65 527 (IPv6) to IP addresses; a larger send is `EMSGSIZE`. There's no back-pressure, as with UDP: a datagram that doesn't fit the link's window is dropped, and at most 512 datagrams or 256 KiB wait to be read before more are dropped.
|
package/package.json
CHANGED
package/src/packages/certs.json
CHANGED
|
@@ -371,6 +371,10 @@
|
|
|
371
371
|
"integrity": "sha512-fEmBJVZ6DDWwogpP7mmgQGnOHqQ0VPCeuhJh/IkHsril59T5InBczSEZ2y8KY+Vl71lVQRKt5IJ5Au7JP4YpAQ==",
|
|
372
372
|
"sha256": "b3ecab2258cd2e07fc71d38358eeaff3818d366559b41d37eb5d9af3fc10f5b8"
|
|
373
373
|
},
|
|
374
|
+
"@ai-ecoverse/wasix-websocat@4.0.0-alpha3-3": {
|
|
375
|
+
"integrity": "sha512-D3iGDb+tx30SUwuONfyMfRDY9ZIJnEnF8A4X5r4P8uPXYUge9ZTL8wVTMW9x060kq0VN1w9mifNzDF6Lb1/fFA==",
|
|
376
|
+
"sha256": "50062e7d8f0d05eb04735aa3f5fd71b561bd831d7426f5a4baa0621980c20a61"
|
|
377
|
+
},
|
|
374
378
|
"@ai-ecoverse/wasm-bash@5.3.0-13": {
|
|
375
379
|
"integrity": "sha512-pusddMmR2Y7k1fSDtF8vCNzPcpe4LCPEvwPhsxhnx9V7NmMcdudBvPE1nKLzetnqNQtXLjVaMNvKPxzrLO9KGw==",
|
|
376
380
|
"sha256": "10fea4a64c1622155b24127dcdecb4c843ce608b42725806d6ca944d5035d3b9"
|
|
@@ -150,6 +150,13 @@
|
|
|
150
150
|
"commands": ["dig"],
|
|
151
151
|
"size": 207317
|
|
152
152
|
},
|
|
153
|
+
"@ai-ecoverse/wasix-websocat": {
|
|
154
|
+
"id": "websocat",
|
|
155
|
+
"label": "websocat",
|
|
156
|
+
"description": "Connects to WebSocket servers (ws:// and wss://) from the terminal. An upstream alpha (websocat 4). It speaks raw TCP, so hosts outside seven need an exit: a linked slicc CLI or a Tailscale exit node. A listener that can't bind still exits 0.",
|
|
157
|
+
"commands": ["websocat"],
|
|
158
|
+
"size": 1266828
|
|
159
|
+
},
|
|
153
160
|
"@ai-ecoverse/wasix-gnupg": {
|
|
154
161
|
"id": "gpg",
|
|
155
162
|
"label": "GnuPG",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"@ai-ecoverse/wasix-python": "3.14.2-20",
|
|
21
21
|
"@ai-ecoverse/wasix-ruby": "3.4.11-12",
|
|
22
22
|
"@ai-ecoverse/wasix-uv-shim": "0.1.0-6",
|
|
23
|
+
"@ai-ecoverse/wasix-websocat": "4.0.0-alpha3-3",
|
|
23
24
|
"@ai-ecoverse/wasm-git": "2.55.0-15",
|
|
24
25
|
"@ai-ecoverse/wasm-libheif": "1.23.6-1",
|
|
25
26
|
"@ai-ecoverse/wasm-poppler": "26.10.0-2",
|
|
@@ -174,6 +175,15 @@
|
|
|
174
175
|
"slicc-kernel": ">=1.51.0"
|
|
175
176
|
}
|
|
176
177
|
},
|
|
178
|
+
"node_modules/@ai-ecoverse/wasix-websocat": {
|
|
179
|
+
"version": "4.0.0-alpha3-3",
|
|
180
|
+
"resolved": "https://registry.npmjs.org/@ai-ecoverse/wasix-websocat/-/wasix-websocat-4.0.0-alpha3-3.tgz",
|
|
181
|
+
"integrity": "sha512-D3iGDb+tx30SUwuONfyMfRDY9ZIJnEnF8A4X5r4P8uPXYUge9ZTL8wVTMW9x060kq0VN1w9mifNzDF6Lb1/fFA==",
|
|
182
|
+
"license": "MIT OR Apache-2.0",
|
|
183
|
+
"engines": {
|
|
184
|
+
"slicc-kernel": ">=1.95.0"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
177
187
|
"node_modules/@ai-ecoverse/wasm-bash": {
|
|
178
188
|
"version": "5.3.0-13",
|
|
179
189
|
"resolved": "https://registry.npmjs.org/@ai-ecoverse/wasm-bash/-/wasm-bash-5.3.0-13.tgz",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"@ai-ecoverse/wasix-python": "3.14.2-20",
|
|
18
18
|
"@ai-ecoverse/wasix-ruby": "3.4.11-12",
|
|
19
19
|
"@ai-ecoverse/wasix-uv-shim": "0.1.0-6",
|
|
20
|
+
"@ai-ecoverse/wasix-websocat": "4.0.0-alpha3-3",
|
|
20
21
|
"@ai-ecoverse/wasm-git": "2.55.0-15",
|
|
21
22
|
"@ai-ecoverse/wasm-libheif": "1.23.6-1",
|
|
22
23
|
"@ai-ecoverse/wasm-poppler": "26.10.0-2",
|