@ai-ecoverse/slicc-bios 1.7.1 → 1.8.1

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
@@ -77,7 +77,7 @@ The kernel runs with users on (slicc-kernel ≥ 1.81.0): files have owners and m
77
77
  - **bios's installs** (pnpm into the base set, `/opt/*` and `/opt/slicc/<project>`, and the `chmod -R a+rX` pass) run as `kernel.run(argv, { cwd, tag: 'bios-installer', env })`. The env is clean: `HOME=/opt/slicc/.installer`, its own config and cache, the system `PNPM_HOME` and `PATH`, and an empty `NODE_OPTIONS`.
78
78
  - **pnpm runs with** `--ignore-scripts --ignore-pnpmfile --config.userconfig=/dev/null --config.store-dir=/opt/slicc/.store --config.verify-store-integrity=true`. No locked package in the base set, `/opt/agent`, `/opt/grammars`, `/opt/tailscale` or the data tools has an install script.
79
79
  - **The base project** moves out of `/`: its `package.json`, `pnpm-lock.yaml` and `pnpm-workspace.yaml` are in `/opt/slicc/base`, written by the BIOS installer and the in-place update, and pnpm installs it with `--modules-dir=/node_modules` from there. So everything pnpm reads is inside a protected path, and a root process that writes `/package.json`, `/pnpm-lock.yaml`, `/.npmrc` or `/pnpm-workspace.yaml` changes nothing; bios removes those at every boot. A protected project without its own `pnpm-workspace.yaml` gets one, so pnpm's search for a workspace stops inside the tree. The service worker's resolver no longer reads a `package.json` at `/` for `browser` mappings.
80
- - **The user layer** (Your packages) for `/opt/*` is off under `'enforce'`: users can't change those projects any more, and its state is in `/var/lib/slicc`, which the agent can write. It keeps working under `'report'`.
80
+ - **The user layers** for `/opt/agent` and `/opt/grammars` are off under `'enforce'`: users can't change those projects any more, and their state is in `/var/lib/slicc`, which the agent can write. They keep working under `'report'`. Your packages live in `/opt/user` instead, which isn't protected (see [Your packages](#your-packages)).
81
81
  - **Under `'report'`** nothing is protected, since protection has no report mode of its own. Installs already run as tagged writers from `/opt/slicc/base` with the clean config, and bios watches the six trees through the kernel (`fs.watch`, recursive). Each change made through the page's kernel outside bios's own installs goes to `denials.log` as `op: 'protect'`, `errno: 'EROFS'`: a write that `'enforce'` would refuse. The watch doesn't say which process wrote, so these lines have no user and no tag. Changes made outside the page's kernel (bios's install kernels, the page itself) aren't seen.
82
82
  - **Global packages** (`pnpm add -g` into `/usr/local/share/pnpm`) aren't protected and run untagged.
83
83
  - **A remembered mount** (`slicc-os.mounts`) at, under or above a protected path is dropped at boot under `'enforce'`, with a notice, *A remembered folder wasn’t mounted*.
@@ -103,13 +103,13 @@ A local folder can be mounted into seven as on Linux ([#73](https://github.com/a
103
103
 
104
104
  [slicc-agent](https://github.com/ai-ecoverse/slicc-agent) and its dependencies (about 100 packages, most of them provider SDKs) aren't part of the first boot either. They are a separate pnpm project, [`src/packages/agent/`](src/packages/agent/), installed like the grammars, so the BIOS boots as fast as without an agent. slicc-agent takes `@ai-ecoverse/slicc-kernel` as a peer, so the project pins the same kernel as the base set, and a test keeps the two pins equal. Its `pnpm-workspace.yaml` overrides `@google/genai` and `esbuild` to nothing (`'-'`): a Bedrock turn never loads them, and dropping them and their trees takes `/opt/agent` from 99 packages to 58. Seven's pnpm reads overrides only from the workspace file, so the installer copies it into `/opt/agent` next to the lockfile:
105
105
 
106
- 1. **After every update check,** `os/agent.js` compares the deployed `packages/agent/pnpm-lock.yaml` with `var/lib/slicc/agent/pnpm-lock.yaml`. If they differ, it writes the manifest (merged with the user's packages, see [Your packages](#your-packages)) and lockfile to `/opt/agent` and runs `pnpm install --frozen-lockfile --trust-lockfile` there under its own Web Lock, `slicc-agent-install`. The **Agent** row of [Install / Update](#install--update) shows pnpm's progress: *Downloading n of m* while pnpm fetches packages (reused from its store or downloaded), then *Linking n of m* once it starts adding them, because pnpm adds nothing until the fetching is done. Only once pnpm succeeds does it record the lockfile. A failed install shows the error, pnpm's log and **Retry**, and the next check tries again.
106
+ 1. **After every update check,** `os/agent.js` compares the deployed `packages/agent/pnpm-lock.yaml` with `var/lib/slicc/agent/pnpm-lock.yaml`. If they differ, it writes the manifest (merged with the user's layer, see [Your packages](#your-packages)) and lockfile to `/opt/agent` and runs `pnpm install --frozen-lockfile --trust-lockfile` there under its own Web Lock, `slicc-agent-install`. The **Agent** row of [Install / Update](#install--update) shows pnpm's progress: *Downloading n of m* while pnpm fetches packages (reused from its store or downloaded), then *Linking n of m* once it starts adding them, because pnpm adds nothing until the fetching is done. Only once pnpm succeeds does it record the lockfile. A failed install shows the error, pnpm's log and **Retry**, and the next check tries again.
107
107
  2. **Once it's installed,** the page imports `page.js` and `spectrum/index.js` from `/opt/agent/node_modules/@ai-ecoverse/slicc-agent/dist/`. `startAgent` takes the Web Lock `slicc-agent`, starts `agent-worker.js` from there as a module worker and hands it a port to the page's kernel, so the agent's `bash`, `read`, `write` and `edit` run on the same kernel and files as the terminal. The page swaps in `createAgentModel()` when the worker connects. On later loads the agent starts at once, before any network check, so chat works offline. If another tab owns the agent, this tab has terminals and files only.
108
108
  3. **The conversation** is kept in SQLite in OPFS (`/.slicc/agent/`).
109
109
 
110
110
  **The `panel` command** (slicc-agent ≥ 3.43.0, spectrum ≥ 1.60.0) lets the agent arrange seven's panels. Every local tab, the one that owns the agent and the tabs that follow it in the same browser, gives `createAgentModel()` a `page` bridge with its tab id, and the bridge runs spectrum's `panelCommand(app, argv, caller)` on that tab. A page that follows seven over a link never gets one. So `panel open monitor left`, `panel reset` and the other verbs in the agent's `bash` act on the tab showing the caller's cone, `panel tabs` lists the tabs, and `--tab <id>` picks one. Each terminal a tab opens has `SLICC_TAB` set to that tab's id, so `panel` typed in it acts on that tab.
111
111
 
112
- `/opt/agent` is an ordinary pnpm project, so `cd /opt/agent && pnpm upgrade` updates the agent in place, and the pin survives seven's updates ([Your packages](#your-packages)), and the service worker drops its resolution cache when `/opt/agent`'s lockfile or `.modules.yaml` changes. When an update installs a new `/opt/agent` while the agent runs, the **Agent** row says *Ready to apply* and offers **Restart agent** (D16). It waits until the agent is idle, then stops the agent worker, imports the newly installed `page.js` and `spectrum/index.js` again and starts the new `agent-worker.js` with them; durable resumes the conversation from SQLite, and the page reconnects and swaps in the new connection and the new adapter's `createAgentModel()`, closing the old connection. The kernel, terminals and the page itself keep running. The page holds one module instance per URL, so each restart, and each retry after a failed import (Chrome keeps a module's failure under its URL too), imports the adapter as `page.js?run=<n>` with a new `n`; the service worker ignores `run` when it reads the file and adds the same `run` to every import that resolves inside `/opt/agent`, so the adapter's own files and dependencies load from the new install while the base set's modules stay shared. If the restart fails, no agent worker is left running and the row offers **Retry**, which starts the installed agent.
112
+ Under users `'off'` and `'report'`, `/opt/agent` is an ordinary pnpm project, so `cd /opt/agent && pnpm upgrade` updates the agent in place, and the pin survives seven's updates ([Your packages](#your-packages)), and the service worker drops its resolution cache when `/opt/agent`'s lockfile or `.modules.yaml` changes. When an update installs a new `/opt/agent` while the agent runs, the **Agent** row says *Ready to apply* and offers **Restart agent** (D16). It waits until the agent is idle, then stops the agent worker, imports the newly installed `page.js` and `spectrum/index.js` again and starts the new `agent-worker.js` with them; durable resumes the conversation from SQLite, and the page reconnects and swaps in the new connection and the new adapter's `createAgentModel()`, closing the old connection. The kernel, terminals and the page itself keep running. The page holds one module instance per URL, so each restart, and each retry after a failed import (Chrome keeps a module's failure under its URL too), imports the adapter as `page.js?run=<n>` with a new `n`; the service worker ignores `run` when it reads the file and adds the same `run` to every import that resolves inside `/opt/agent`, so the adapter's own files and dependencies load from the new install while the base set's modules stay shared. If the restart fails, no agent worker is left running and the row offers **Retry**, which starts the installed agent.
113
113
 
114
114
  ### Tabs
115
115
 
@@ -157,7 +157,7 @@ A hidden owner is fine. In R1, 30 minutes in the background throttled only the o
157
157
  Spectrum bundles 16 syntax languages; the rest come from `@shikijs/langs` and `@shikijs/themes` (725 and 135 files). They aren't part of the first boot. They're a separate pnpm project, [`src/packages/grammars/`](src/packages/grammars/), deployed next to the BIOS's lockfiles:
158
158
 
159
159
  1. **Until they're installed,** the UI loads grammars from jsDelivr.
160
- 2. **After every update check,** `os/grammars.js` compares the deployed `packages/grammars/pnpm-lock.yaml` with `var/lib/slicc/grammars/pnpm-lock.yaml`. If they differ, it writes the manifest (merged with the user's packages, see [Your packages](#your-packages)) and lockfile to `/opt/grammars` and runs `pnpm install --frozen-lockfile --trust-lockfile` there, under its own Web Lock, `slicc-grammars`, so a long install never holds up the BIOS in another tab. Only once pnpm succeeds does it record the lockfile.
160
+ 2. **After every update check,** `os/grammars.js` compares the deployed `packages/grammars/pnpm-lock.yaml` with `var/lib/slicc/grammars/pnpm-lock.yaml`. If they differ, it writes the manifest (merged with the user's layer, see [Your packages](#your-packages)) and lockfile to `/opt/grammars` and runs `pnpm install --frozen-lockfile --trust-lockfile` there, under its own Web Lock, `slicc-grammars`, so a long install never holds up the BIOS in another tab. Only once pnpm succeeds does it record the lockfile.
161
161
  3. **Once they're installed,** `grammarBase` points at `/opt/grammars/node_modules/@shikijs/`. On later loads the page sets it as soon as the recorded lockfile is there, before any network check, so highlighting works offline. If pnpm fails, the page stays on jsDelivr, the **Syntax grammars** row shows the error with **Retry**, and the next check tries again.
162
162
 
163
163
  The Files panel lists `/opt/grammars/node_modules` but doesn't scan it.
@@ -192,10 +192,21 @@ A package dropped from the catalog is listed in `src/packages/optional/retired.j
192
192
 
193
193
  #### Your packages
194
194
 
195
- `/opt/agent` and `/opt/grammars` are ordinary pnpm projects, and what the user (or the agent) changes in them with `pnpm add`, `pnpm upgrade` or `pnpm remove` survives seven's updates. The deployment owns the **base manifest**, its `package.json`; the user's changes are a **user layer** on top of it, and `os/layer.js` merges the two before it runs pnpm (D15).
195
+ **Your packages live in `/opt/user`** (`os/user.js`): a pnpm project that root owns, its directories `0755` and its files `0644` (a package's `bin` files `0755`), outside the protected paths, so root writes it and every cone and scoop only reads it.
196
+
197
+ - **What reads it:** the agent (slicc-agent ≥ 3.50.0) loads skills, prompt templates and roles from `/node_modules` first and `/opt/user/node_modules` after it, and the first name wins; a package whose name seven already ships is skipped whole. It watches `/opt/user/node_modules`, so a package added, upgraded or removed there reaches the running agent without a restart; an edit inside an installed package reaches it when the agent next starts. The page's kernel gets `commands: { append: ['/opt/user/node_modules'] }` (slicc-kernel ≥ 1.88), so each package's `slicc.commands` and `bin` entries are commands in `/usr/bin` for every user, agents included, after every other root, so a package can't shadow `bash`, `sudo` or the base set. Under `'enforce'` the kernel takes that root only while it and every directory above it are root's and not group- or other-writable.
198
+ - **Adding a package:** the human, whose panel terminals are root, runs `cd /opt/user && pnpm add <package>`. A cone runs `cd /opt/user && sudo pnpm add <package>`, which asks the human and offers only *Allow once*, since pnpm writes files. The panel has no field to add one.
199
+ - **bios's own pnpm runs there** (installing what the manifest lists but `node_modules` lacks, and **Remove**) in the page's kernel as root, untagged, since it isn't a protected writer, under the Web Lock `slicc-user-packages`. It runs with `--ignore-scripts --ignore-pnpmfile --config.userconfig=/dev/null` and a clean environment: `HOME=/var/lib/slicc/user/home`, its own config and cache, root's `PNPM_HOME` and its store, the system `PATH` and an empty `NODE_OPTIONS`. Afterwards it runs `chmod -R u=rwX,go=rX /opt/user`, so nothing there is group- or other-writable. The project has its own `pnpm-workspace.yaml`, so pnpm's search for a workspace stops there.
200
+ - **The rows:** every dependency in `/opt/user/package.json` is a row under **Your packages** (`pin: { base: null, range, project: '/opt/user' }`) with its version, its `bin` commands and **Remove**, which runs `pnpm remove <package>` there. A package that isn't installed, because the install failed or hasn't run yet, shows the error with **Retry** and **Remove**. A name the base set ships in `/node_modules` gets the warning "Seven ships its own <name> and ignores this one."
201
+ - **The move from `/opt/agent`:** at every update check, before the agent and the grammars are installed, bios adds every addition in `/opt/agent`'s layer (below) to `/opt/user/package.json` with its spec and field, unless `/opt/user` lists that name already, takes it out of the layer, which installs `/opt/agent` again without it, and installs it in `/opt/user`. So an addition an older seven left in `/opt/agent` moves once, also under `'enforce'`, where the layers are off. Additions to `/opt/grammars` stay there, since the grammars are served only from `/opt/grammars`.
202
+ - **Pins under `'enforce'`:** protect seals `/opt/agent` and `/opt/grammars`, so at that check bios drops every pin in their layers, and the grammar additions, and posts one notice, *Your pinned versions were removed* (*Your pinned versions and added grammar packages were removed* when grammar packages went too): "Seven now uses the versions it ships for the agent and its tools. To add your own packages, use /opt/user (Install / Update › Your packages)." Under `'off'` and `'report'` pins work as below.
203
+
204
+ The Files panel lists `/opt/user/node_modules` but doesn't scan it.
205
+
206
+ Under `'off'` and `'report'`, `/opt/agent` and `/opt/grammars` are ordinary pnpm projects too, and what the user (or the agent) changes in them with `pnpm upgrade` or `pnpm remove` survives seven's updates as a pin; an addition to `/opt/agent` moves to `/opt/user`. The deployment owns the **base manifest**, its `package.json`; the user's changes are a **user layer** on top of it, and `os/layer.js` merges the two before it runs pnpm (D15).
196
207
 
197
208
  - **Detection:** at every update check (boot, the tab becoming visible, every 15 minutes, Retry), bios reads the project's `package.json` and, only when it changed since the last check, compares it with the base it last installed (`var/lib/slicc/<project>/package.json`). A name the base doesn't have is an **addition**; a base name with another spec is a **pin**. Nothing runs pnpm when only the user changed the project, since the user's pnpm already installed it. A base package the user removed is put back.
198
- - **The layer file** is `var/lib/slicc/<project>/user.json`, an interface the agent reads too (it loads extensions from the additions in `/opt/agent`):
209
+ - **The layer file** is `var/lib/slicc/<project>/user.json`:
199
210
 
200
211
  ```json
201
212
  {
@@ -209,7 +220,7 @@ A package dropped from the catalog is listed in `src/packages/optional/retired.j
209
220
  - **Who wins:** a pin wins over the base until the user unpins it. A pin made *ahead* of the base (an upgrade) drops by itself once the deployment's version reaches or passes it, so the user follows the base again; a pin made *behind* it (a rollback) stays. Range, tag and URL pins never drop by themselves. An addition the base later adopts becomes part of the base.
210
221
  - **Certified packages:** a package the base set provides (slicc-kernel, slicc-cdp, wasi-pnpm, spectrum, the `wasm-*` tools) can't be pinned or added in these projects; `/opt/agent`'s kernel has to equal the base set's. bios undoes such a change at the next check and posts a notice naming the base set's version, read from the deployment. After a layered install, every gated package in the project's lockfile (see [Certified packages](#certified-packages)) must be the shipped one or listed in `packages/certs.json` with that integrity.
211
222
  - **Failures:** if the layered install fails or fails that check, bios installs the base again, frozen, and keeps the layer with its error. The rows show it with **Retry**; a new deployment tries again too.
212
- - **The panel** lists the layer under **Your packages** (spectrum ≥ 1.55.0: `origin: 'user'` and `pin: { base, range, project }` on each row, `base` null for an addition), below Optional packages and only when there is one: *Pinned* rows show the user's version next to the one seven ships and offer **Unpin**, *Added* rows offer **Remove**. Both edit `user.json` and the project's `package.json` under the project's Web Lock and install again; unpinning everything restores the deployed lockfile byte for byte. An `/opt/agent` change under a running agent offers **Restart agent**, as any agent update does.
223
+ - **The panel** lists the layers under **Your packages** too (spectrum ≥ 1.55.0: `origin: 'user'` and `pin: { base, range, project }` on each row, `base` null for an addition), below Optional packages and only when there is one: *Pinned* rows show the user's version next to the one seven ships and offer **Unpin**, *Added* rows (grammar additions) offer **Remove**. Both edit `user.json` and the project's `package.json` under the project's Web Lock and install again; unpinning everything restores the deployed lockfile byte for byte. An `/opt/agent` change under a running agent offers **Restart agent**, as any agent update does.
213
224
  - **Limits:** only the project's dependencies are layered. A changed lockfile alone (a transitive `pnpm update`) and edits to `pnpm-workspace.yaml` (overrides) are replaced by the deployment's at the next update. The root project and `/opt/tailscale` hold only certified packages and have no layer; `pnpm add -g` is the place for the user's own tools, and bios never rewrites it.
214
225
 
215
226
  Packages are served unbundled, exactly as npm publishes them, so `pnpm upgrade <package>` updates one of them in place. Browsers refuse bare specifiers, and an import map would only cover documents, so the service worker rewrites the imports of every script it serves from OPFS, for pages and workers alike:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-bios",
3
- "version": "1.7.1",
3
+ "version": "1.8.1",
4
4
  "description": "Slim loader that boots SLICC into OPFS and serves the UI from there",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "@ai-ecoverse/slicc": "1.42.0",
46
- "@ai-ecoverse/slicc-browsers": "1.7.5",
46
+ "@ai-ecoverse/slicc-browsers": "1.7.6",
47
47
  "@ai-ecoverse/slicc-node": "2.5.1",
48
48
  "@ai-ecoverse/slicc-shared-web": "1.20.0",
49
49
  "@ai-ecoverse/slicc-spectrum": "1.77.0",
@@ -6,7 +6,7 @@
6
6
  "": {
7
7
  "name": "slicc-bios-packages",
8
8
  "dependencies": {
9
- "@ai-ecoverse/slicc-browsers": "1.7.5",
9
+ "@ai-ecoverse/slicc-browsers": "1.7.6",
10
10
  "@ai-ecoverse/slicc-cdp": "1.25.1",
11
11
  "@ai-ecoverse/slicc-clipboard": "1.0.2",
12
12
  "@ai-ecoverse/slicc-kernel": "1.110.1",
@@ -37,9 +37,9 @@
37
37
  }
38
38
  },
39
39
  "node_modules/@ai-ecoverse/slicc-browsers": {
40
- "version": "1.7.5",
41
- "resolved": "https://registry.npmjs.org/@ai-ecoverse/slicc-browsers/-/slicc-browsers-1.7.5.tgz",
42
- "integrity": "sha512-98ZdWV86qyEJhV5U6gvd5VaZkvgL4TUjj13FXa8fdO12nTLVagXhGOI4K21jVP4HB1me/KpwQojUf6dB++6+ww==",
40
+ "version": "1.7.6",
41
+ "resolved": "https://registry.npmjs.org/@ai-ecoverse/slicc-browsers/-/slicc-browsers-1.7.6.tgz",
42
+ "integrity": "sha512-clzlvrVLjmWEiKXhuK/Lez7y3Dwmo+FJ8POUs5GYqLJy5u8cOAiXyliQlNUNOVkNx9EoPm0RVvdfFkSTgv/isg==",
43
43
  "license": "Apache-2.0",
44
44
  "engines": {
45
45
  "node": ">=24"
@@ -3,7 +3,7 @@
3
3
  "private": true,
4
4
  "description": "Packages the BIOS installs from npm into OPFS, pinned by package-lock.json and pnpm-lock.yaml",
5
5
  "dependencies": {
6
- "@ai-ecoverse/slicc-browsers": "1.7.5",
6
+ "@ai-ecoverse/slicc-browsers": "1.7.6",
7
7
  "@ai-ecoverse/slicc-cdp": "1.25.1",
8
8
  "@ai-ecoverse/slicc-clipboard": "1.0.2",
9
9
  "@ai-ecoverse/slicc-kernel": "1.110.1",
@@ -9,8 +9,8 @@ importers:
9
9
  .:
10
10
  dependencies:
11
11
  '@ai-ecoverse/slicc-browsers':
12
- specifier: 1.7.5
13
- version: 1.7.5
12
+ specifier: 1.7.6
13
+ version: 1.7.6
14
14
  '@ai-ecoverse/slicc-cdp':
15
15
  specifier: 1.25.1
16
16
  version: 1.25.1
@@ -95,8 +95,8 @@ importers:
95
95
 
96
96
  packages:
97
97
 
98
- '@ai-ecoverse/slicc-browsers@1.7.5':
99
- resolution: {integrity: sha512-98ZdWV86qyEJhV5U6gvd5VaZkvgL4TUjj13FXa8fdO12nTLVagXhGOI4K21jVP4HB1me/KpwQojUf6dB++6+ww==}
98
+ '@ai-ecoverse/slicc-browsers@1.7.6':
99
+ resolution: {integrity: sha512-clzlvrVLjmWEiKXhuK/Lez7y3Dwmo+FJ8POUs5GYqLJy5u8cOAiXyliQlNUNOVkNx9EoPm0RVvdfFkSTgv/isg==}
100
100
  engines: {node: '>=24'}
101
101
 
102
102
  '@ai-ecoverse/slicc-cdp@1.25.1':
@@ -199,7 +199,7 @@ packages:
199
199
 
200
200
  snapshots:
201
201
 
202
- '@ai-ecoverse/slicc-browsers@1.7.5': {}
202
+ '@ai-ecoverse/slicc-browsers@1.7.6': {}
203
203
 
204
204
  '@ai-ecoverse/slicc-cdp@1.25.1': {}
205
205