@ai-ecoverse/slicc 1.45.0 → 1.46.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 +69 -24
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`slicc` is SLICC's command line for seven, the SLICC on `*.sliccy.ai`. It is one binary for macOS, Windows and Linux. It launches and links browsers, and shares a machine's network, compute and browsers with a running seven over a WebRTC link. `npx sliccy` and Sliccstart.app run this binary. It replaces slicc-node and slicc-swift (see [Coming from slicc-node](#coming-from-slicc-node)).
|
|
4
4
|
|
|
5
|
-
**Status:** being built. `slicc` (the default flow), `slicc attach` (with the `cdp` capability), `slicc open`, `slicc pair` and `slicc unpair` (seven in your everyday browser, without CDP), `slicc <join-url> follow`, `slicc tray` (on a machine and inside seven), remote control with `prompt`, `watch` and `abort` (also from inside seven's kernel, see [Inside seven](#inside-seven)), host folders with `--mount`, `slicc browsers`, `slicc launch`, `update`, `install`, `--version` and `--help` work so far, plus a hidden diagnostic, `slicc <join-url> follow --signal-only [--timeout 2m]`. It attaches through the tray hub, prints a summary of the leader's offer (its size, media sections, candidate count and DTLS fingerprint) and the ICE server URLs (credentials are never printed), and exits without answering. The link protocol is specified in [Link protocol](#link-protocol).
|
|
5
|
+
**Status:** being built. `slicc` (the default flow), `slicc attach` (with the `cdp` capability), `slicc open`, `slicc pair` and `slicc unpair` (seven in your everyday browser, without CDP), `slicc <join-url> follow`, `slicc tray` (on a machine and inside seven), remote control with `prompt`, `watch`, `wait` and `abort` (also from inside seven's kernel, see [Inside seven](#inside-seven)), host folders with `--mount`, `slicc browsers`, `slicc launch`, `update`, `install`, `--version` and `--help` work so far, plus a hidden diagnostic, `slicc <join-url> follow --signal-only [--timeout 2m]`. It attaches through the tray hub, prints a summary of the leader's offer (its size, media sections, candidate count and DTLS fingerprint) and the ICE server URLs (credentials are never printed), and exits without answering. The link protocol is specified in [Link protocol](#link-protocol).
|
|
6
6
|
|
|
7
7
|
## Commands (planned)
|
|
8
8
|
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
| `slicc tray [--json] [-q] [-a]` | list the `slicc` processes on this machine that hold a link: mode, seven, device, state and offers (works now; see [Running links](#running-links-slicc-tray)) |
|
|
16
16
|
| `slicc launch` | launch a browser with CDP in a separate SLICC profile and print its CDP URL |
|
|
17
17
|
| `slicc <join-url> follow [--exit] [--runner …] [--cdp <url>] [--mount <path>]` | follow a seven's tray from another machine and offer its network, compute (over SSH), browsers or folders (`--exit`, `--runner`, `--cdp` and `--mount` work now; see [Remote setup](#remote-setup-slicc-join-url-follow)). `-` or `@<file>` in place of `<join-url>` reads it from stdin or a file, out of sight of `ps` |
|
|
18
|
-
| `slicc <join-url> prompt <text>`, `watch`, `abort` | send a prompt to seven's agent and stream its answer, follow the agent as it works, or abort its run; `--cdp <url>` instead of a join URL links locally (works now; see [Remote control](#remote-control-slicc-prompt-watch-and-abort)) |
|
|
19
|
-
| `slicc <join-url> prompt`, `watch`, `abort` inside seven | the same commands from seven's kernel, as `@ai-ecoverse/wasi-slicc` (works now; see [Inside seven](#inside-seven)) |
|
|
18
|
+
| `slicc <join-url> prompt <text>`, `watch`, `wait`, `abort` | send a prompt to seven's agent and stream its answer, follow the agent as it works, wait until it has nothing left to do, or abort its run; `--cdp <url>` instead of a join URL links locally (works now; see [Remote control](#remote-control-slicc-prompt-watch-wait-and-abort)) |
|
|
19
|
+
| `slicc <join-url> prompt`, `watch`, `wait`, `abort` inside seven | the same commands from seven's kernel, as `@ai-ecoverse/wasi-slicc` (works now; see [Inside seven](#inside-seven)) |
|
|
20
20
|
| `slicc tray [url \| rotate \| unlink <device> \| retry]` inside seven | this seven's tray: its state and devices, the join URL on request, rotate it, drop a device, reconnect (see [Inside seven](#inside-seven)) |
|
|
21
21
|
| `slicc browsers --json` | list running CDP endpoints and installed browsers, ranked |
|
|
22
22
|
| `slicc update [--check]` | replace this binary with the latest release (works now; see [Updates](#updates)) |
|
|
@@ -299,7 +299,7 @@ Release builds outside npm and app bundles print a notice on stderr when a newer
|
|
|
299
299
|
## Telemetry
|
|
300
300
|
|
|
301
301
|
Release builds (a plain `X.Y.Z` version, linked in or, for `go install`, from the module version) send operational telemetry through [go-optel](https://github.com/ai-ecoverse/go-optel) with the app id `slicc-cli`, sampled once per process (1 in 100 by default):
|
|
302
|
-
- `enter`, with the subcommand as `source`, from a fixed list (`abort`, `attach`, `browsers`, `follow`, `install`, `launch`, `open`, `pair`, `prompt`, `unpair`, `update`, `watch`, `default` for no command (no arguments, or only flags), `join` for a bare join URL, otherwise `unknown`). No other argument is ever sent.
|
|
302
|
+
- `enter`, with the subcommand as `source`, from a fixed list (`abort`, `attach`, `browsers`, `follow`, `install`, `launch`, `open`, `pair`, `prompt`, `unpair`, `update`, `wait`, `watch`, `default` for no command (no arguments, or only flags), `join` for a bare join URL, otherwise `unknown`). No other argument is ever sent.
|
|
303
303
|
- `error`, for operational failures, from a fixed set of sources (`update`, `signal`, `link`, `browser`, `ssh`, `cdp`). Messages pass through go-optel's sanitizer, which strips URLs and paths.
|
|
304
304
|
|
|
305
305
|
`--version`, and any command line with `--help`, `-h` or `-help` (such as `slicc update --help`), send nothing, and development builds never configure a client.
|
|
@@ -737,7 +737,7 @@ Link spec §5.14 (J1). slicc-jerk (`jerk`, [Companion tools](#companion-tools))
|
|
|
737
737
|
**Offered** when host jerk is found: of the first `jerk` on `PATH` and `jerk` in the data folder's `bin`, in that order, the first whose `jerk --version` names 0.6.0 or later. 0.6.0 is the first slicc-jerk with the `--via-link` calls below. An older jerk counts as absent: slicc says `jerk: host jerk <version> is older than 0.6.0; run slicc install jerk`, and HELLO has neither cap.
|
|
738
738
|
- `slicc` and `slicc attach`: caps `jerk` and `jerk-seal`, unless `--no-jerk`.
|
|
739
739
|
- `follow`: only with `--jerk` (cap `jerk`) or `--jerk-seal` (both).
|
|
740
|
-
- `prompt`, `watch` and `abort`: never.
|
|
740
|
+
- `prompt`, `watch`, `wait` and `abort`: never.
|
|
741
741
|
- slicc says `jerk: offering slicc-jerk <version> (jerk, jerk-seal)`, and HELLO adds `"jerk": { "version" }`. Without the cap an OPEN gets `EOPNOTSUPP`.
|
|
742
742
|
|
|
743
743
|
**OPEN** `{ "kind": "jerk", "op", "provider"?, "scope"?, "lease_id"?, "duration"?, "params"? }`. The page sends END right after it. slicc runs jerk as the user, with no terminal and its stderr dropped:
|
|
@@ -795,7 +795,8 @@ Only browsers the user named are listed: the one seven runs in, `--cdp` and `--c
|
|
|
795
795
|
- **Privileged pages** (slicc-browsers ≥ 1.8.0) are protected the same way, as if they were seven's: every URL whose scheme is in `protectedSchemes` (`chrome:`, `chrome-untrusted:`, `chrome-extension:`, `devtools:`, `file:`, from 1.8.5 also `chrome-search:`, `chrome-native:`, `chrome-distiller:`, `isolated-app:`, `chrome-experimental-site-token-provider:`, `externalfile:` and `content:`, and the UI schemes of the catalog's other Chromium browsers, `edge:`, `brave:`, `opera:`, `vivaldi:` and `arc:`), on any host and path, except the new tab pages in `schemeExceptions` (`chrome://newtab`, `chrome://new-tab-page` and its `chrome-untrusted://new-tab-page` frames, `edge://newtab`, `brave://newtab`, `opera://startpage`), matched by the parsed scheme and exact host, so `chrome-untrusted://new-tab-page.evil/` stays protected. `chrome-error:` is not protected: Chrome's network and frame error pages stay readable, snapshottable, reattachable and navigable away from, like the ordinary pages they stand in for. So `chrome://settings`, `chrome://password-manager`, an extension's pages, frames and workers (a password manager's or a wallet's vault included) and any local file are refused, hidden from auto-attach and detached like a seven tab. A wrapper is judged by what it wraps: `view-source:chrome://settings/` and `view-source:file:///…` by their inner URL, `blob:` and `filesystem:` by their origin. An `about:` URL other than `about:blank` and `about:srcdoc` is judged as the `chrome://` URL Chrome makes of it, so `about:settings` is `chrome://settings`. A target whose `type` is in `targetTypes` (`browser_ui`, Chrome's own UI such as `chrome://omnibox-popup.top-chrome/`) is protected whatever its URL, and hidden altogether (see *Listing*).
|
|
796
796
|
- **Targets.** Before the stream opens, the node attaches its own session to the browser target and calls `Target.setDiscoverTargets` and `Target.getTargets` on it with ids of its own. Neither the session nor its messages ever reach the page. From then on it knows every target's URL and opener. A target on an inheriting URL (`about:blank`, `about:srcdoc`, none) is protected when it was protected before or when its opener is protected or unknown, so a blank popup that seven opens counts as seven. On a page session, the main frame's `securityOrigin` (`Page.frameNavigated`) and the default context's `origin` (`Runtime.executionContextCreated`) count too.
|
|
797
797
|
- **Extension worlds.** Any other execution context on a protected origin, such as a password manager's content-script isolated world on an ordinary page, is hidden rather than cutting the page. Seven never sees it, and commands, objects and call frames that name it are refused with `slicc: refused: that execution context belongs to a browser extension` ([§5.8](#58-cdp-cap-cdp-page--node)).
|
|
798
|
-
- **
|
|
798
|
+
- **URLs slicc can't parse** count as protected wherever the node judges a URL the browser will load or has loaded. Chrome's parser and the node's (WHATWG) disagree at the edges: Chrome loads `http://exa mple.sliccy.ai/` as `http://exa%20mple.sliccy.ai/`, a `sliccy.ai` host that gets seven's cookies, and, in some versions, `http://<U+200D>.sliccy.ai/` as `http://xn--1ug.sliccy.ai/`, and the node's parser rejects all of those forms. So a command whose destination doesn't parse (`url` of `Target.createTarget`, `Page.navigate`, `Fetch.continueRequest`, `Network.continueInterceptedRequest`, `Network.loadNetworkResource` and `PWA.launch`, `installUrlOrOrigin` of `PWA.install`, the `url` of a cookie command, and a history entry's `url` or `userTypedURL`) is refused with `slicc: refused: slicc can't parse this URL, so it could be a protected page`. An empty URL is fine (`Target.createTarget` with `url: ""` opens `about:blank`). On the browser's side, a target, a main frame's `securityOrigin`, an execution context's `origin`, a request or WebSocket, and a service worker whose URL doesn't parse are protected like seven's: redacted (to an empty `url` and `title`), not attachable, detached, hidden, their document loads failed and their requests stripped. The opaque origins `null` and `://` are not affected, and neither are `blob:null/…` URLs (blobs made on an opaque origin, such as a `data:` page or a sandboxed frame). URLs the node only reads, such as storage keys, script URLs and values it redacts, are unaffected. The cost: a page on a host that Chrome accepts and WHATWG doesn't (an invalid `xn--` label, a joiner such as U+200D, a space or another forbidden code point), and Chrome's error page for one, is cut too, and navigating to it is refused. URLs Chrome rejects as well (`http://[::1`, `http://a:99999/`, `http://1.2.3.4.5/`) lose nothing: Chrome answers `Page.navigate` with `Cannot navigate to invalid URL`, and `Target.createTarget` with a tab that never loads a document.
|
|
799
|
+
- **Refused**, with `{"id":…,"sessionId"?:…,"error":{"code":-32000,"message":"slicc: refused: target is on seven's origin"}}`, never forwarded: `Target.createTarget`, `Page.navigate` and anything else whose `url` is protected (one that doesn't parse is refused with `slicc: refused: slicc can't parse this URL, so it could be a protected page`, see above); `Page.navigateToHistoryEntry` to an entry whose URL is protected (the node looks it up with `Page.getNavigationHistory`); `Target.attachToTarget`, `activateTarget`, `closeTarget`, `autoAttachRelated`, `Browser.getWindowForTarget` and any other command whose `targetId` or `frameId` is a protected target; and every command on a session whose target is protected, or became so. `Target.getTargetInfo` and `Target.detachFromTarget` stay allowed, except `Target.getTargetInfo` on a hidden target (see *Listing*).
|
|
799
800
|
- **Origins and storage.** A command whose `origin`, `securityOrigin`, `ownerOrigin`, `issuerOrigin`, `topLevelOrigin`, `topLevelSite`, `embeddedOrigin`, `requestingOrigin`, `scopeURL` or `manifestId` is protected, or whose `storageKey` or `cacheId` names seven's storage, is refused the same way. This covers `Storage.*`, `IndexedDB.*`, `CacheStorage.*`, `DOMStorage.*`, `FileSystem.*`, `ServiceWorker.*`, `PWA.*`, `Browser.setPermission` and `Browser.grantPermissions`. Free-form values (`expression`, `arguments`, `value`, `headers`, `postData` and the like) aren't searched.
|
|
800
801
|
- **Cookies.** `Network.getCookies`, `Network.getAllCookies`, `Storage.getCookies` and `Page.getCookies` answer without the cookies whose domain is protected (`sliccy.ai` and every subdomain, and each extra origin's host and its parents: cookies ignore ports), and without partitioned cookies whose `partitionKey.topLevelSite` is such a site. `Network.setCookie`, `setCookies`, `deleteCookies`, `Storage.setCookies` and `Page.deleteCookie` for such a domain, a URL on such a host, or a partition key under such a site, are refused with `slicc: refused: cookies on seven's origin`. So are `Network.clearBrowserCookies` and `Storage.clearCookies`, except in a browser context this stream created with `Target.createBrowserContext`.
|
|
801
802
|
- **Requests a page makes to seven.** For a request whose URL is protected, `Network.*` and `Fetch.*` events lose their `Cookie` and `Set-Cookie` headers, their raw header texts and their cookie lists, and `requestWillBeSentExtraInfo` drops seven's cookies from `associatedCookies` for any request. Chrome can send `requestWillBeSentExtraInfo` and `responseReceivedExtraInfo` before the event that names the request's URL, so the node holds them until the request is found to be protected, gets its response, finishes or fails (a WebSocket or WebTransport once it is created); one still held after 2 seconds is passed on stripped, as for a protected request. For a WebSocket, WebTransport or EventSource on a protected origin (`ws:` and `wss:` count as `http:` and `https:`), `webSocketWillSendHandshakeRequest`, `webSocketHandshakeResponseReceived`, `webSocketFrameError`, `eventSourceMessageReceived` and `dataReceived` are dropped. Reading such a request's body (`Network.getResponseBody`, `Fetch.getResponseBody`, `takeResponseBody…AsStream`, `Audits.getEncodedResponse` and the like) is refused. The node also checks the answer, because the page may ask before the node has seen the request. When `Network.getResponseBody`, `searchInResponseBody`, `streamResourceContent`, `getResponseBodyForInterception`, `takeResponseBodyForInterceptionAsStream`, `getRequestPostData`, `Fetch.getResponseBody`, `Fetch.takeResponseBodyAsStream` or `Audits.getEncodedResponse` answers, the node holds the answer until the request has a response (for `getRequestPostData`, until it is sent; for an intercepted request, until it is paused). If the request is protected by then, the answer is refused, and a stream it handed out is closed. If the node still hasn't seen the request after 2 seconds, the answer is refused with `slicc: refused: slicc hasn't seen this request, so it could be seven's`. `Network.replayXHR` is refused with that message too, unless the node has already seen the request; for a protected request it is refused like the body getters. `IO.read` is refused, with `slicc: refused: slicc didn't hand out this stream, so it could be seven's`, unless the node passed that handle to the page in an allowed answer (`take…AsStream`, `Page.printToPDF`, `Network.loadNetworkResource`, or `IO.resolveBlob` as `blob:<uuid>`). - **Paused requests to seven.** A page session's own interception never gets to touch a request whose URL is protected, whatever its kind (a document, `fetch()`, XHR, an image or any other subresource), at either stage. The node keeps `Fetch.requestPaused`, `Fetch.authRequired` and the deprecated `Network.requestIntercepted` for such a request from the page and settles it itself:
|
|
@@ -1089,7 +1090,7 @@ slicc @<file> follow [flags]
|
|
|
1089
1090
|
|
|
1090
1091
|
`follow` links this machine to a seven on another machine through the tray hub (see [Tray hub signaling](#tray-hub-signaling-remote-setup)). It serves the link until interrupted (`SIGINT`, `SIGTERM`) and reconnects when the link drops. Status lines go to stderr, and `SLICC_DEBUG=1` adds diagnostics. The join URL is never printed.
|
|
1091
1092
|
|
|
1092
|
-
**The join URL off the command line.** On the command line, `ps` shows the join URL to every user of this machine. In its place, `-` reads it from stdin and `@<file>` from a file: the first non-empty line, trimmed. From stdin slicc reads only up to that line's end, so the rest of stdin is left for `prompt -`. The file must be a regular file, not a symlink. On macOS and Linux it must also belong to you and be readable by no one else (`chmod 600`). Exit 2 follows when there's no join URL, when the file can't be read, breaks those rules or is over 64 KiB, or when what's there isn't a join URL. The message names the file but never shows what it holds, inside seven too. `prompt`, `watch` and `abort` take `-` and `@<file>` the same way, inside seven too. There is no environment variable for it, because `--runner`'s processes would inherit it.
|
|
1093
|
+
**The join URL off the command line.** On the command line, `ps` shows the join URL to every user of this machine. In its place, `-` reads it from stdin and `@<file>` from a file: the first non-empty line, trimmed. From stdin slicc reads only up to that line's end, so the rest of stdin is left for `prompt -`. The file must be a regular file, not a symlink. On macOS and Linux it must also belong to you and be readable by no one else (`chmod 600`). Exit 2 follows when there's no join URL, when the file can't be read, breaks those rules or is over 64 KiB, or when what's there isn't a join URL. The message names the file but never shows what it holds, inside seven too. `prompt`, `watch`, `wait` and `abort` take `-` and `@<file>` the same way, inside seven too. There is no environment variable for it, because `--runner`'s processes would inherit it.
|
|
1093
1094
|
|
|
1094
1095
|
**Flags.**
|
|
1095
1096
|
- `--exit`: offer this machine's network to seven, as `tcp` and `resolve` streams (cap `net`), `http` streams (cap `http`), `ws` streams (cap `ws`) and `udp` streams (cap `udp`) under the remote policy, so public addresses only by default. Without `--exit`, all five are refused with `EOPNOTSUPP`.
|
|
@@ -1113,16 +1114,18 @@ HELLO from `follow`: `{ "v": 1, "role": "node", "name", "host", "version", "mode
|
|
|
1113
1114
|
|
|
1114
1115
|
**Stops** with exit 1 and says why on `INVALID_JOIN_CAPABILITY`, `TRAY_EXPIRED` or `TRAY_SUPERSEDED_MISSING_JOIN_URL` from the hub, and on `UNTRUSTED`, `UNSUPPORTED_RUNTIME` or `NO_FINGERPRINT` (an internal error: the answer had no SHA-256 fingerprint) from seven. The device's fingerprint is always SHA-256.
|
|
1115
1116
|
|
|
1116
|
-
## Remote control: `slicc prompt`, `watch` and `abort`
|
|
1117
|
+
## Remote control: `slicc prompt`, `watch`, `wait` and `abort`
|
|
1117
1118
|
|
|
1118
1119
|
```
|
|
1119
|
-
slicc <join-url> prompt [--steer | --reject] [--thinking] [--json] [--plain] [--abort-on-interrupt] <text>|@file|-
|
|
1120
|
+
slicc <join-url> prompt [--allsettled <quiet>] [--steer | --reject] [--thinking] [--json] [--plain] [--abort-on-interrupt] <text>|@file|-
|
|
1120
1121
|
slicc <join-url> watch [--thinking] [--json] [--plain]
|
|
1122
|
+
slicc <join-url> wait [--allsettled <quiet>] [--timeout <limit>] [--json]
|
|
1121
1123
|
slicc <join-url> abort
|
|
1122
1124
|
slicc prompt --cdp <url> [--origin <origin>]... [flags] <text>|@file|-
|
|
1123
1125
|
slicc watch --cdp <url> [--origin <origin>]... [flags]
|
|
1126
|
+
slicc wait --cdp <url> [--origin <origin>]... [flags]
|
|
1124
1127
|
slicc abort --cdp <url> [--origin <origin>]...
|
|
1125
|
-
slicc prompt|watch|abort --signal stdio [flags] …
|
|
1128
|
+
slicc prompt|watch|wait|abort --signal stdio [flags] …
|
|
1126
1129
|
```
|
|
1127
1130
|
|
|
1128
1131
|
These commands talk to seven's agent over a link that offers nothing to seven (`caps: []`).
|
|
@@ -1152,6 +1155,28 @@ These commands talk to seven's agent over a link that offers nothing to seven (`
|
|
|
1152
1155
|
- `130` on Ctrl-C or `SIGTERM`.
|
|
1153
1156
|
- **Ctrl-C** leaves the run going in seven. With `--abort-on-interrupt`, slicc first opens `abort`.
|
|
1154
1157
|
|
|
1158
|
+
**`prompt --allsettled <quiet>`** (for benchmarks and scripts) goes on after the prompt's run until seven has nothing left to do. The cone can end a run while scoops it started are still working, and run again when their results come in. `<quiet>` is a duration such as `2m` or `0s`.
|
|
1159
|
+
- **Needs** a seven whose agent is @ai-ecoverse/slicc-agent 6.15.0 or later, the first that reports `busy`. `wait` needs it too.
|
|
1160
|
+
- **Settled** means seven says it isn't busy (`busy` false, see [`agent`](#agent-page-cap-agent-node--page) below), and nothing has come from seven for `<quiet>`. The quiet period starts once the stream is open, and every line from seven restarts it.
|
|
1161
|
+
- **A seven that doesn't report `busy`:** before sending anything, slicc opens a `watch` with `busy`. When seven's answer doesn't say whether it's busy, slicc says `this seven doesn't report when its agent is idle; update it` and exits 1. The prompt isn't sent.
|
|
1162
|
+
- **Output:** the prompt's run streams as usual. After its `end`, slicc opens `watch` with `busy`, and `since` the last event it showed, so the cone's later runs stream as they would in `watch`, with nothing shown twice.
|
|
1163
|
+
- **`--json`:** the prompt's events up to its `end` line, then the watch's events, as seven sent them. The last line is slicc's own `{"t":"settled"}`.
|
|
1164
|
+
- **Exit status:** the prompt's own run decides. An `end` with `error` or `aborted` exits 1 at once, as without `--allsettled`. Otherwise slicc exits 0 once seven has settled, whatever the later runs did.
|
|
1165
|
+
- A stream or link that ends before seven has settled exits 1 (`lost the link to seven; the run goes on there`).
|
|
1166
|
+
- Bad usage, a missing permission and Ctrl-C exit as for `prompt` above.
|
|
1167
|
+
- **No time limit of its own.** A lick that's held in seven's outbox keeps seven busy, and so does a scoop that never finishes. Bound the wait with the caller's own timeout, or with `wait --timeout`.
|
|
1168
|
+
|
|
1169
|
+
**`wait`** follows the agent without sending anything, and exits once seven has settled, as `prompt --allsettled` does. `--allsettled <quiet>` sets the quiet period (default `0s`: exit as soon as seven isn't busy).
|
|
1170
|
+
- **Output:** `slicc: seven is idle` on stderr, and nothing on stdout. With `--json`, the events as seven sent them, then `{"t":"settled"}`.
|
|
1171
|
+
- **`--timeout <limit>`:** give up after `<limit>` (default: no limit). slicc says `seven didn't settle within <limit>` and exits 124.
|
|
1172
|
+
- **Exit status:**
|
|
1173
|
+
- `0` once seven has settled;
|
|
1174
|
+
- `1` for a seven that doesn't report `busy`, and for a stream or link that ends first;
|
|
1175
|
+
- `2` for bad usage;
|
|
1176
|
+
- `3` without permission;
|
|
1177
|
+
- `124` on timeout;
|
|
1178
|
+
- `130` on Ctrl-C or `SIGTERM`.
|
|
1179
|
+
|
|
1155
1180
|
**`watch`** follows the agent until Ctrl-C or `SIGTERM`, then exits 0.
|
|
1156
1181
|
- **Output:** `user` events go to stdout as `> <text>`, on one line. Assistant text goes to stdout as for `prompt`, and a line ends at each run's end. Everything else goes to stderr, as for `prompt`, plus `run ended: <reason>` for a run that didn't end with `stop`. `--json` prints the events instead.
|
|
1157
1182
|
- **Status lines** on stderr: `slicc: watching <name>`, `slicc: lost the link to <name>; reconnecting`, and for the tray `<reason>; trying again in <wait>`.
|
|
@@ -1190,10 +1215,11 @@ Summaries are one line of at most 200 characters. Escape sequences and control c
|
|
|
1190
1215
|
- The page then delivers it. Its first line is `{"t":"delivered","delivered"}`, or it resets with `EBUSY` instead.
|
|
1191
1216
|
- **Aborting:** a RESET from the node, or a closed link, doesn't abort the run. Only `abort` does.
|
|
1192
1217
|
|
|
1193
|
-
**`watch`:** `OPEN { "kind": "agent", "op": "watch", "since"?: "<entry id>", "thinking"?: true }` on its own channel.
|
|
1194
|
-
- **Answer:** OPENED `{ "head": "<entry id>", "gap"?: true }`, then NDJSON events until either side resets.
|
|
1218
|
+
**`watch`:** `OPEN { "kind": "agent", "op": "watch", "since"?: "<entry id>", "thinking"?: true, "busy"?: true }` on its own channel.
|
|
1219
|
+
- **Answer:** OPENED `{ "head": "<entry id>", "gap"?: true, "busy"?: true | false }`, then NDJSON events until either side resets.
|
|
1195
1220
|
- **Without `since`:** the events start at the next one.
|
|
1196
1221
|
- **With `since`:** the page first replays `since`'s own entry when it's `text` or `thinking` (its whole text so far, as one `delta`), then every entry after it. `gap: true` means the transcript no longer holds `since`, and the events start at the next one.
|
|
1222
|
+
- **With `busy`** (`prompt --allsettled` and `wait`): OPENED says whether the agent has anything left to do, and a `busy` line follows each time that changes. An OPENED without `busy` means seven doesn't report it.
|
|
1197
1223
|
|
|
1198
1224
|
**`abort`:** `OPEN { "kind": "agent", "op": "abort" }`, answered OPENED `{ "aborted": true | false }` (`false` when nothing was running), then END.
|
|
1199
1225
|
|
|
@@ -1210,6 +1236,7 @@ Summaries are one line of at most 200 characters. Escape sequences and control c
|
|
|
1210
1236
|
| `{"t":"notice","id","text"}` | retries, compactions, rewinds |
|
|
1211
1237
|
| `{"t":"error","id","message","detail"?}` | an error |
|
|
1212
1238
|
| `{"t":"delivered","delivered"}` | a long prompt was taken (`prompt` only) |
|
|
1239
|
+
| `{"t":"busy","busy","why"?}` | the agent became busy or idle (`watch` with `busy` only) |
|
|
1213
1240
|
| `{"t":"end","reason","message"?}` | the last line of a `prompt` stream |
|
|
1214
1241
|
|
|
1215
1242
|
- **Ids:** `id` is the transcript entry id, and `delta` lines for one `id` arrive in order.
|
|
@@ -1261,8 +1288,9 @@ PID MODE SEVEN DEVICE STATE OFFERS
|
|
|
1261
1288
|
`slicc` also runs inside seven's kernel, so that one seven's agent or user can prompt, watch and abort another seven's agent, and see and manage this seven's own tray. That build is `slicc.wasm`, slicc-cli's client commands compiled with `GOOS=wasip1 GOARCH=wasm` and `CGO_ENABLED=0`, and it ships as the npm package `@ai-ecoverse/wasi-slicc`, at slicc-cli's own version. seven's page holds the WebRTC link; slicc only reaches the page's link facade.
|
|
1262
1289
|
|
|
1263
1290
|
```
|
|
1264
|
-
slicc <join-url> prompt [--steer | --reject] [--thinking] [--json] [--plain] <text>|@file|-
|
|
1291
|
+
slicc <join-url> prompt [--allsettled <quiet>] [--steer | --reject] [--thinking] [--json] [--plain] <text>|@file|-
|
|
1265
1292
|
slicc <join-url> watch [--thinking] [--json] [--plain]
|
|
1293
|
+
slicc <join-url> wait [--allsettled <quiet>] [--timeout <limit>] [--json]
|
|
1266
1294
|
slicc <join-url> abort
|
|
1267
1295
|
slicc tray [--json]
|
|
1268
1296
|
slicc tray url
|
|
@@ -1273,7 +1301,7 @@ slicc --version
|
|
|
1273
1301
|
slicc --help
|
|
1274
1302
|
```
|
|
1275
1303
|
|
|
1276
|
-
- **Commands:** `prompt`, `watch` and `abort` with a join URL behave as in [Remote control](#remote-control-slicc-prompt-watch-and-abort): the same flags, output, styling, `--json` events, resuming and exit codes, from the same code. The differences:
|
|
1304
|
+
- **Commands:** `prompt`, `watch`, `wait` and `abort` with a join URL behave as in [Remote control](#remote-control-slicc-prompt-watch-wait-and-abort): the same flags, output, styling, `--json` events, resuming and exit codes, from the same code. The differences:
|
|
1277
1305
|
- **Ctrl-C** ends slicc with 130 (the kernel's default for `SIGINT`), `watch` included, and a running prompt goes on in the other seven. `--abort-on-interrupt` isn't offered.
|
|
1278
1306
|
- **Exit 3** covers the facade's own refusals too. When the facade gives a message (`unlock the vault to continue`, or the other seven's refusal), slicc prints it instead of the Linked devices hint.
|
|
1279
1307
|
- **A terminal** is a standard stream that is a character device. Styling then follows `TERM`, `NO_COLOR` and `--plain` as usual.
|
|
@@ -1286,7 +1314,7 @@ slicc --help
|
|
|
1286
1314
|
- **`slicc tray retry`** reconnects the tray's links, as the Reconnect button does.
|
|
1287
1315
|
- **Not here:** choosing the exit (that's routing, not tray state), and SLICC six's `host join` and `host leave`: a seven follower runs no kernel or agent of its own, so following stays with `#follow=` and the UI's Leave.
|
|
1288
1316
|
- **Exit status:** 0, 1 on failure (`ENOTCONN` when the tray isn't connected, a facade that doesn't answer within 1 minute, or 5 minutes for `rotate` and `unlink`, which seven may ask you to approve), 2 for bad usage, 3 when seven refuses (`EACCES`).
|
|
1289
|
-
- **Everything else** exits 2 with `slicc: <command> isn't available inside seven`: `follow`, `attach`, `open`, `browsers`, the default flow, `update`, `install`, and `prompt`, `watch` or `abort` without a join URL. `--help` lists only what works there.
|
|
1317
|
+
- **Everything else** exits 2 with `slicc: <command> isn't available inside seven`: `follow`, `attach`, `open`, `browsers`, the default flow, `update`, `install`, and `prompt`, `watch`, `wait` or `abort` without a join URL. `--help` lists only what works there.
|
|
1290
1318
|
- **What the build leaves out** (build constraints): pion and the link, CDP, SSH, mounts, the kernel listener, the policy, browser discovery, telemetry and updates.
|
|
1291
1319
|
|
|
1292
1320
|
**The link facade.** slicc reads its address from `SLICC_LINK_URL` only, as `tcp://127.0.0.1:<port>` on the kernel's loopback (any `127.x` address, or `localhost`). Without it, or with another shape, slicc exits 1. Each `agent` stream (see [`agent`](#agent-page-cap-agent-node--page)) is one connection, carrying records of a `u8` type, a `u32` big-endian length and the payload, both ways:
|
|
@@ -1651,14 +1679,15 @@ On a [§1.3](#13-local-setup-without-cdp-loopback-signalling) loopback link, `un
|
|
|
1651
1679
|
|
|
1652
1680
|
- **Protected origins (PRE-1):** the node filters every `cdp` stream against `protectedOrigins` from slicc-browsers (≥ 1.4.0: `*.sliccy.ai` at any depth, any port, http and https; `vault.sliccy.ai` by name; plus the setup's extra origins). It refuses navigating to, attaching to, or driving targets on those origins, and storage, cookie and permission access for them, as **CDP errors** `{"error":{"code":-32000,"message":"slicc: refused: …"}}`, not RESETs. It detaches sessions that land on them and redacts their `url`/`title` in listings to the origin.
|
|
1653
1681
|
- **Privileged browser pages** (≥ 1.8.0) count as protected origins: every URL in `protectedSchemes` (`chrome:`, `chrome-untrusted:`, `chrome-extension:`, `devtools:`, `file:`, from 1.8.5 `chrome-search:`, `chrome-native:`, `chrome-distiller:`, `isolated-app:`, `chrome-experimental-site-token-provider:`, `externalfile:` and `content:`, `edge:`, `brave:`, `opera:`, `vivaldi:`, `arc:`) except the new tab pages in `schemeExceptions`, and never `chrome-error:`; `view-source:`, `blob:` and `filesystem:` by what they wrap; `about:` aliases as the `chrome://` URL they become (`aboutScheme`). Targets of a `targetTypes` type (`browser_ui`) are protected whatever their URL, and never listed or announced to the page. The refusal text is the same.
|
|
1682
|
+
- **URLs that don't parse** (WHATWG) count as protected wherever the node judges a URL the browser will load or has loaded: a command's destination (`Target.createTarget`, `Page.navigate`, `Fetch.continueRequest`, `Network.continueInterceptedRequest`, `Network.loadNetworkResource`, `PWA.launch`, `PWA.install`, cookie commands' `url`, history entries) is refused with `slicc: refused: slicc can't parse this URL, so it could be a protected page`, and a target, main frame, execution context, request, WebSocket or service worker the browser reports on such a URL is redacted, refused, detached or hidden like seven's. An empty URL, the opaque origins `null` and `://`, and `blob:null/…` are not affected, and URLs the node only reads (storage keys, script URLs, redaction) keep "unparseable isn't protected". Chrome canonicalises some URLs WHATWG rejects (`http://exa mple.sliccy.ai/` → `http://exa%20mple.sliccy.ai/`, U+200D → `xn--1ug`, invalid `xn--` labels), so this is what keeps those `sliccy.ai` hosts protected. The cost: pages on such exotic hosts, and Chrome's error pages for them, are cut even when they aren't protected. [`cdp` (browser control)](#cdp-browser-control) has the details.
|
|
1654
1683
|
- **In targets the stream touched** (attached to or created): the node fails every protected document load with `net::ERR_BLOCKED_BY_CLIENT`, so instrumentation installed before a navigation can never run in a protected document. That covers redirects, service-worker-served navigations and the page's own Fetch interception.
|
|
1655
1684
|
- **Waiting for that guard:** page commands on a touched target's session wait while the node sets its guard up there. The wait fails closed after 30 s without progress (any answer from the browser on the stream's socket, the node's own `Browser.getVersion` probe included, or any event for that target or its sessions) or 5 min in all, whichever comes first, and the refusal names the bound. At most 4096 commands or 64 MiB wait on a stream; more is `RESET ENOBUFS`.
|
|
1656
1685
|
- **Sessions the node doesn't know:** a page command whose `sessionId` the node hasn't seen on this stream (in a `Target.attachedToTarget`, in the answer to the page's `Target.attachToTarget` or `Target.attachToBrowserTarget`, or its own) is held, not forwarded, until the session appears, and is then decided as usual. Only messages on that session id count as progress. The same bounds and caps apply, and the refusal is `slicc: refused: slicc doesn't know which target this session belongs to: …`, naming the bound. A session that detached is refused at once, without the suffix. Commands without a `sessionId` are unaffected.
|
|
1657
1686
|
- **Auto-attached targets with no URL yet** (OOPIFs, popups) are held until the URL is known, then detached if protected. After 10 s with no URL they are treated as protected. The node's own setup connection ([§1.1](#11-local-setup-over-cdp)) isn't a `cdp` stream and is the one exception. [`cdp` (browser control)](#cdp-browser-control) has the details.
|
|
1658
1687
|
- **Protection follows the target's own effective origin. Execution contexts on a protected origin are hidden, not cut,** unless the context is the target's own main-frame default context; that one still cuts the target as above. The typical case is an extension's content-script isolated world (`chrome-extension://<id>`) on an ordinary page. The page stays usable, and the hidden world is invisible and out of reach.
|
|
1659
1688
|
- **Hidden:** the node learns every context of a touched target on its own guard session, whatever the page enabled. It drops these events from the stream: the world's `Runtime.executionContextCreated` and `executionContextDestroyed`, its `consoleAPICalled`, `exceptionThrown` and `bindingCalled`, and `Debugger.scriptParsed`/`scriptFailedToParse` for scripts in it. It also drops `Debugger.breakpointResolved` in those scripts. A `Debugger.paused` whose top frame is in the world is dropped, and the node resumes the target. The world's frames lower in the stack are removed from the call frames.
|
|
1660
|
-
- **Refused** with `slicc: refused: that execution context belongs to a browser extension`: any command that names the world through a `contextId` or `executionContextId`, `uniqueContextId`, an `executionContextName` the world has, a remote `objectId` or `*ObjectId` (call arguments included) or `callFrameId` whose injected-script part is the world, or the `scriptId` of a script in it. So `Runtime.evaluate`, `callFunctionOn`, `compileScript`, `runScript`, `globalLexicalScopeNames`, `queryObjects`, `getProperties`, `addBinding`, `Debugger.evaluateOnCallFrame`, `setVariableValue`, `setScriptSource` and `DOM.resolveNode` there are all refused. The default world, and isolated worlds the page creates itself, are unaffected. On page-like sessions, a `Runtime.addBinding` with neither `executionContextId` nor `executionContextName` is sent with `executionContextName: ""`, so it reaches every frame's main world now and after reloads, but no isolated world.
|
|
1661
|
-
- **Lifetime:** a hidden world is forgotten only when Chrome reports it gone (`executionContextDestroyed`, or `executionContextsCleared` on a session that reported it), never to make room. A target with more than 4096 live hidden worlds is refused every command there that names an execution context, object, call frame, script or context name, until its contexts are cleared.
|
|
1689
|
+
- **Refused** with `slicc: refused: that execution context belongs to a browser extension`: any command that names the world through a `contextId` or `executionContextId`, `uniqueContextId`, an `executionContextName` the world has, a remote `objectId` or `*ObjectId` (call arguments included) or `callFrameId` whose injected-script part is the world, or the `scriptId` of a script in it. So `Runtime.evaluate`, `callFunctionOn`, `compileScript`, `runScript`, `globalLexicalScopeNames`, `queryObjects`, `getProperties`, `addBinding`, `Debugger.evaluateOnCallFrame`, `setVariableValue`, `setScriptSource` and `DOM.resolveNode` there are all refused. The default world, and isolated worlds the page creates itself, are unaffected. A `uniqueContextId` on a target's session that names no live context the node has seen announced on that target, on its guard session or the page's (say one from a closed tab or another live tab, or made up), is refused with `slicc: refused: that execution context is not exposed`, rather than passed to Chrome. On page-like sessions, a `Runtime.addBinding` with neither `executionContextId` nor `executionContextName` is sent with `executionContextName: ""`, so it reaches every frame's main world now and after reloads, but no isolated world.
|
|
1690
|
+
- **Lifetime:** a hidden world is forgotten only when Chrome reports it gone (`executionContextDestroyed`, or `executionContextsCleared` on a session that reported it), never to make room. A target with more than 4096 live hidden worlds is refused every command there that names an execution context, object, call frame, script or context name, until its contexts are cleared. Seen contexts follow the same lifetime and bound; once a target passes 4096, the `uniqueContextId`s of contexts announced after that are refused as not exposed until its contexts are cleared, even if some are destroyed in between.
|
|
1662
1691
|
- **Heap profiling:** a page's heap snapshot covers its whole renderer, other worlds included. So on page, iframe, background page and webview sessions every `HeapProfiler` command except `enable`, `disable`, `collectGarbage` and `getHeapObjectId` is refused with `slicc: refused: HeapProfiler reads the page's whole renderer, browser extensions' worlds included`, whether or not an extension is there.
|
|
1663
1692
|
- **Breakpoint conditions** run in whatever world the script belongs to, and a breakpoint by URL outlives reloads. So on those sessions a `Debugger.setBreakpointByUrl` with a `condition` needs a non-empty `url`, which can't name a protected script (see above). One by `urlRegex` or `scriptHash` or with an empty `url` is refused with `slicc: refused: a breakpoint condition that could run in a browser extension's world needs a url naming the page's own script`. Breakpoints without a condition are allowed; a pause they cause in a hidden world is resumed out of sight.
|
|
1664
1693
|
- **Profiles, coverage, stacks and initiators** can name any script in the isolate. So the node scrubs every message it sends the page, events and command results alike, outside opaque values (`value`, `preview`, `customPreview`, `arguments`, `returnValue`). Any `callFrames` list loses the frames on a protected URL or in a hidden world's script. That covers console, exception, pause, async, node-creation and initiator stacks, whatever the method. A coverage or type-profile list (entries with `scriptId` and `functions` or `entries`) also loses its entries for scripts without a URL. A profile node's `callFrame` in such a script becomes `(program)` and loses its `positionTicks`. An `initiator` on a protected `url` loses that `url` and its position.
|
|
@@ -1734,14 +1763,14 @@ slicc-node's hostfs ([its README, *Host folders*](https://github.com/ai-ecoverse
|
|
|
1734
1763
|
- Paths go through `\\?\`, so device names and 8.3 names are plain names inside the folder.
|
|
1735
1764
|
|
|
1736
1765
|
#### 5.11 `agent` (page cap `agent`), node → page: remote control
|
|
1737
|
-
`slicc prompt`, `slicc watch` and `slicc abort` talk to seven's agent, the cone, which slicc-agent hosts. The page serves each stream through `remoteControl(connection)` from `@ai-ecoverse/slicc-agent/page`, on top of its `AgentConnection`, so the CLI never speaks pi's protocol.
|
|
1766
|
+
`slicc prompt`, `slicc watch`, `slicc wait` and `slicc abort` talk to seven's agent, the cone, which slicc-agent hosts. The page serves each stream through `remoteControl(connection)` from `@ai-ecoverse/slicc-agent/page`, on top of its `AgentConnection`, so the CLI never speaks pi's protocol.
|
|
1738
1767
|
|
|
1739
1768
|
- **Who may:** the page advertises `agent` only to links the user allowed to control it.
|
|
1740
1769
|
- A **local** link ([§1.1](#11-local-setup-over-cdp)) gets it by default, because a CLI holding the browser's CDP can drive the page anyway.
|
|
1741
1770
|
- A **remote** link gets it only after the user turns on *Allow remote control* for that device in Linked devices. It's off by default, and keyed on the fingerprint.
|
|
1742
1771
|
- Seven lists every device that has linked once, even one that's offline or offered no caps, so the toggle can be found after a refused `prompt`.
|
|
1743
1772
|
- Without the cap, the node doesn't open `agent` streams, and the page refuses them with `EACCES`.
|
|
1744
|
-
- **Control-only links:** `prompt`, `watch` and `abort` links advertise `caps: []`. The page gives them no `<host>.slicc.internal`, no exit entry, and opens no `kernel` streams to them.
|
|
1773
|
+
- **Control-only links:** `prompt`, `watch`, `wait` and `abort` links advertise `caps: []`. The page gives them no `<host>.slicc.internal`, no exit entry, and opens no `kernel` streams to them.
|
|
1745
1774
|
- **One device, several processes:** the node's HELLO ([§4](#4-hello)) and the [§1.1](#11-local-setup-over-cdp) hello both carry a random per-process `"node"` id.
|
|
1746
1775
|
- The page replaces an older link of the same device (local: any local link; remote: the same fingerprint) only when `node` matches.
|
|
1747
1776
|
- Over the tray, the page learns `node` at HELLO, so any replacement waits for HELLO.
|
|
@@ -1761,6 +1790,21 @@ slicc-node's hostfs ([its README, *Host folders*](https://github.com/ai-ecoverse
|
|
|
1761
1790
|
- **Without `since`,** the stream starts at the next event.
|
|
1762
1791
|
- **With `since`,** the page first replays `since`'s own entry when it's `text` or `thinking`, as one `delta` with its whole text so far. Then it replays every entry after it. Clients skip what they already printed.
|
|
1763
1792
|
- **`gap: true`** means the transcript no longer holds `since` (a new session, or a compaction). The stream then starts at the next event.
|
|
1793
|
+
- **`busy`** (`"busy": true` in the OPEN) is for `slicc prompt --allsettled` and `slicc wait`. The cone can end a run while scoops it started are still working, and run again when their results come in as `scoop-notify` licks. A client that sees only the cone's events can't tell that apart from being done.
|
|
1794
|
+
- **OPENED** carries `"busy": true | false`, the state after any replay. A page that doesn't support it leaves `busy` out, and the node then reports that seven doesn't support it.
|
|
1795
|
+
- **Then** the page sends `{"t":"busy","busy":true|false}` each time the value changes, in order with the other events. It has no `id`, and it's never replayed.
|
|
1796
|
+
- **`busy` is true** while, for the cone the stream belongs to:
|
|
1797
|
+
- the cone has a run or a queued input;
|
|
1798
|
+
- a live scoop of that cone has a run, a queued input or a feed;
|
|
1799
|
+
- a lick for the cone is queued or still to be delivered (a `scoop-notify` result, or a scoop `wait`'s delivery). That includes a lick held in the agent's outbox until its conversation's model is known. If the model never comes, `busy` stays true, so the client bounds its wait.
|
|
1800
|
+
- **It turns false** only when none of that holds. A lick from outside (a cron, a file watch) counts once it's queued, not before.
|
|
1801
|
+
- **`why`:** a `busy: true` line may carry `"why"`, a list of what keeps the agent busy, to be logged. The node doesn't use it, and it's left out when `busy` is false. The values come from a fixed list:
|
|
1802
|
+
- `"cone"`: the cone has a run or a queued input;
|
|
1803
|
+
- `"scoop:<name>"`: that live scoop (its name, as seven shows it) has a run, a queued input or a feed;
|
|
1804
|
+
- `"pending-lick"`: a lick for the cone is queued or still to be delivered.
|
|
1805
|
+
- **Read-only status:** `busy` lines carry only the boolean and `why`. They never carry prompt text, tool arguments or output, and asking for `busy` changes nothing in the agent.
|
|
1806
|
+
- **Ordering:** a `run start` never comes before the `busy: true` that covers it, and the `busy: false` comes after the last `run end`.
|
|
1807
|
+
- **Computed** from the durable documents' subscriptions (the cone's and its scoops' `pi.live`, `ScoopWorkDoc.feeds` and the licks outbox), and a line goes out only when the value flips.
|
|
1764
1808
|
- **Events:** one JSON object per line, mapped by slicc-agent from pi-durable's agent events (`watchEvents`) and handed to the page by `remoteControl(connection)` from `@ai-ecoverse/slicc-agent/page`.
|
|
1765
1809
|
- `{"t":"user","id","text","delivered"}`;
|
|
1766
1810
|
- `{"t":"text","id","delta"}`: assistant text as it streams;
|
|
@@ -1768,7 +1812,8 @@ slicc-node's hostfs ([its README, *Host folders*](https://github.com/ai-ecoverse
|
|
|
1768
1812
|
- `{"t":"tool","id","call","name","summary"}` and `{"t":"tool-result","id","call","ok","summary"}`;
|
|
1769
1813
|
- `{"t":"run","state":"start"|"end","reason"?}`. These have no `id`, so a resume doesn't replay a missed `run end`. Clients use them only for layout and notices, and the `end` line or the next `user` event is authoritative.
|
|
1770
1814
|
- `{"t":"notice","id","text"}`: retries, compactions, rewinds;
|
|
1771
|
-
- `{"t":"error","id","message","detail"?}
|
|
1815
|
+
- `{"t":"error","id","message","detail"?}`;
|
|
1816
|
+
- `{"t":"busy","busy":true|false,"why"?:[…]}`: only on `watch` streams opened with `busy` (above).
|
|
1772
1817
|
- **Ids** are opaque strings.
|
|
1773
1818
|
- `user`, `tool-result`, and a `notice` or `error` that is a transcript entry: the entry id, such as `"42"`.
|
|
1774
1819
|
- An assistant message's `text`, `thinking` and `tool` blocks: `"a<ts>.<block>"`, where `<ts>` is the message's own timestamp (set when its generation starts, and kept in the committed entry) and `<block>` its content index. An assistant message isn't an entry until it's committed, so this id is stable from the first delta to the committed entry. A second message with the same timestamp gets `"a<ts>~1.<block>"`, a third `~2`, and so on.
|
|
@@ -1840,7 +1885,7 @@ jerk ([ai-ecoverse/slicc-jerk](https://github.com/ai-ecoverse/slicc-jerk)) gets
|
|
|
1840
1885
|
|---|---|---|
|
|
1841
1886
|
| `slicc`, `slicc attach` (local) | yes, when `jerk` ≥ the minimum version is on the host's `PATH` or in slicc's data dir. `--no-jerk` turns both off. | yes, by default |
|
|
1842
1887
|
| `slicc <join> follow` (remote) | only with an explicit `--jerk` | only with an explicit `--jerk-seal`, which implies `--jerk`. A remote seven pulling this machine's tokens into its browser is a bigger grant than starting a sign-in. |
|
|
1843
|
-
| `prompt`, `watch`, `abort` | no | no |
|
|
1888
|
+
| `prompt`, `watch`, `wait`, `abort` | no | no |
|
|
1844
1889
|
| any node without host jerk | no. Host providers are missing in seven. | no |
|
|
1845
1890
|
|
|
1846
1891
|
HELLO adds `"jerk": { "version": "1.0.0" }` next to `caps`.
|
|
@@ -1931,7 +1976,7 @@ From [slicc-bios#360](https://github.com/ai-ecoverse/slicc-bios/pull/360) and [s
|
|
|
1931
1976
|
How a kernel program in seven reaches [§1.4](#14-a-seven-as-follower-leader-to-leader), and this seven's own tray. This isn't a link stream. It's seven's page serving its own kernel. The page holds the WebRTC; the program never sees the hub, the join state or the peer connection.
|
|
1932
1977
|
|
|
1933
1978
|
- **The program:** `@ai-ecoverse/wasi-slicc`, slicc-cli's client command layer built for `GOOS=wasip1` (published by slicc-cli, offered by bios's catalog).
|
|
1934
|
-
- **Commands:** `slicc <join-url> prompt|watch|abort`, with the CLI's own flags, output and `--json` events, and `slicc tray` (below).
|
|
1979
|
+
- **Commands:** `slicc <join-url> prompt|watch|wait|abort`, with the CLI's own flags, output and `--json` events, and `slicc tray` (below).
|
|
1935
1980
|
- **Anything else** exits 2 with `slicc: <command> isn't available inside seven`. A prompt without a join URL is refused the same way.
|
|
1936
1981
|
- **How it reaches the facade:** through its host module, at `SLICC_LINK_URL` (below).
|
|
1937
1982
|
- **Where it's served:** a page-served kernel facade with the caller's stamp on each connection, mirroring the CDP facade on `127.0.0.1:9222`. The mechanism is [slicc-kernel#526](https://github.com/ai-ecoverse/slicc-kernel/issues/526), shipped in [slicc-kernel 1.90.0](https://github.com/ai-ecoverse/slicc-kernel/tree/v1.90.0#page-facades) ([#556](https://github.com/ai-ecoverse/slicc-kernel/pull/556)):
|
|
@@ -2088,9 +2133,9 @@ semantic-release cuts releases from `main` in `.github/workflows/release.yml`, o
|
|
|
2088
2133
|
6. `scripts/go-warm.sh <version>`, once the tag is on `origin`, asks `proxy.golang.org` for the module at `v<version>` (`go list -m` with a scratch module cache) and asks `pkg.go.dev` to fetch it. The proxy fetch is retried briefly; the `pkg.go.dev` fetch is one attempt of at most 10 s, since the proxy fetch already gets the version indexed. Both only warn, and the step can't fail the release.
|
|
2089
2134
|
|
|
2090
2135
|
**Certification in the pull request** (`.github/workflows/cert-review-pr.yml`, `tools/cert-review/`). Every same-repo pull request gets the commit status `cert-review` on its head, which the merge queue requires beside `ci`. Fork pull requests get none: only Lars merges one. Every tool runs from the pull request's base commit, main's copy, never from the code under test, which is only built and tested; the review uses `refs/pull/N/merge` and records its first parent and the head.
|
|
2091
|
-
- **plan** (light runner) runs on opened, synchronize, reopened,
|
|
2136
|
+
- **plan** (light runner) runs on opened, synchronize, reopened, ready_for_review, converted_to_draft, and `cert-review-approved` being added or removed, and plans the whole run again, since such an event cancels a run in progress; other labels neither start nor cancel anything. **Draft status replaces the old `merge-ok` label:** a draft is neither built nor reviewed and its `cert-review` is red `draft: not reviewed, mark it ready for review`, so an older result on the same head can't satisfy the check; **mark ready = reviewed, and merges on green**. With the hold rule (held = draft) the order for a PR that needs the coordinator's security or link-spec read is: the coordinator reviews the draft, it is marked ready, the cert runs (with its Claude review), then the queue; a cert finding means a new head, back to draft and a re-read. Renovate's pull requests aren't drafts, so they're reviewed by themselves. A `pending` status left on the head by a run that ended without a result becomes `error` (re-run the failed jobs), so the check never waits forever. The shared self-guard (`cert-self-guard`, pinned) holds a change to the reviewer's own paths (`REVIEWER_GLOBS` in `tools/cert-review/lib.mjs`: all of `.github/**`, every workflow and action, so no pull request's own workflow can post `cert-review`, and `tools/cert-review/**`) until a coordinator puts `cert-review-approved` on that head. Such pull requests always go to the coordinator before queueing.
|
|
2092
2137
|
- **build** (hosted `ubuntu-latest`, no secrets) builds the merge commit and its first parent the release's way, each in a full clone with its tags: `SLICC_SIGN=0 scripts/package.sh <v>`, `npm-stage.mjs` for every package, and `npm pack`, with one version `X.Y.(Z+1)-pr.N.<run>` on both sides. `outputs.mjs` hashes every release file and tarball.
|
|
2093
|
-
- **classify** decides by output where the build can see it: a pull request is behaviour when a binary, the wasm, `SHA256SUMS` or an npm tarball differs from main's build. Paths whose effect the unsigned build never shows are behaviour whatever it outputs: `scripts/**` (signing and notarization, publishing, the release plan, `go-*`, `sliccy-next.mjs`), `install.sh`, `npm/**`, `package.json` and `package-lock.json` (they choose the semantic-release code the release runs), `.releaserc*`, and the reviewer's paths. Otherwise the status is `not behaviour: identical build outputs` (success), so a docs or test change that ships nothing new needs nothing more. Renovate
|
|
2138
|
+
- **classify** decides by output where the build can see it: a pull request is behaviour when a binary, the wasm, `SHA256SUMS` or an npm tarball differs from main's build. Paths whose effect the unsigned build never shows are behaviour whatever it outputs: `scripts/**` (signing and notarization, publishing, the release plan, `go-*`, `sliccy-next.mjs`), `install.sh`, `npm/**`, `package.json` and `package-lock.json` (they choose the semantic-release code the release runs), `.releaserc*`, and the reviewer's paths. Otherwise the status is `not behaviour: identical build outputs` (success), so a docs or test change that ships nothing new needs nothing more. Renovate's pull requests aren't drafts, so a dev-pin bump is reviewed by itself and merges on green. A behaviour change on a draft is `draft: not reviewed, mark it ready for review` (failure); once it's ready, the review starts.
|
|
2094
2139
|
- **rebuild** (heavy runner) runs [the recipe](#reproducing-a-release) on a `git archive` of the merge commit, in another path on another machine; every release file must be byte-identical to build's.
|
|
2095
2140
|
- **delta** names the Go tests the pull request adds or changes in `test/integration/*_test.go` (the `func Test…` a hunk falls in). A changed helper counts as changing every test in its file; a helper in a file with no tests is a test gap (`helper <name>`), never a guess.
|
|
2096
2141
|
- **suite** (heavy runner): the candidate leg runs the whole integration suite on the merge commit on Linux (`go test -json`); the base leg is the NEGATIVE: main's tree with the pull request's whole `test/` diff applied, running only its tests, against main's own binary. A fix whose test fails there and passes on the candidate is `negative`; passing on both is `no-negative`; not compiling or skipping on main is `prev-not-run`. Gaps are known issues, never a FAIL by themselves.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.1",
|
|
4
4
|
"description": "SLICC's command line for seven: links a machine's network, compute and browsers to seven over WebRTC",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"node": ">=18"
|
|
19
19
|
},
|
|
20
20
|
"optionalDependencies": {
|
|
21
|
-
"@ai-ecoverse/slicc-darwin-arm64": "1.
|
|
22
|
-
"@ai-ecoverse/slicc-darwin-amd64": "1.
|
|
23
|
-
"@ai-ecoverse/slicc-linux-arm64": "1.
|
|
24
|
-
"@ai-ecoverse/slicc-linux-amd64": "1.
|
|
25
|
-
"@ai-ecoverse/slicc-windows-arm64": "1.
|
|
26
|
-
"@ai-ecoverse/slicc-windows-amd64": "1.
|
|
21
|
+
"@ai-ecoverse/slicc-darwin-arm64": "1.46.1",
|
|
22
|
+
"@ai-ecoverse/slicc-darwin-amd64": "1.46.1",
|
|
23
|
+
"@ai-ecoverse/slicc-linux-arm64": "1.46.1",
|
|
24
|
+
"@ai-ecoverse/slicc-linux-amd64": "1.46.1",
|
|
25
|
+
"@ai-ecoverse/slicc-windows-arm64": "1.46.1",
|
|
26
|
+
"@ai-ecoverse/slicc-windows-amd64": "1.46.1",
|
|
27
27
|
"@ai-ecoverse/slicc-jerk": "^1.0.0"
|
|
28
28
|
}
|
|
29
29
|
}
|