@ai-ecoverse/slicc 1.23.0 → 1.25.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.
Files changed (2) hide show
  1. package/README.md +116 -10
  2. 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.
4
4
 
5
- **Status:** being built. `slicc` (the default flow), `slicc attach` (with the `cdp` capability), `slicc <join-url> follow`, host folders with `--mount`, `slicc browsers`, `slicc launch`, `update`, `--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 drafted alongside seven's link exit and moves into this README once both sides pass a shared test.
5
+ **Status:** being built. `slicc` (the default flow), `slicc attach` (with the `cdp` capability), `slicc <join-url> follow`, remote control with `prompt`, `watch` and `abort`, host folders with `--mount`, `slicc browsers`, `slicc launch`, `update`, `--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 drafted alongside seven's link exit and moves into this README once both sides pass a shared test.
6
6
 
7
7
  ## Commands (planned)
8
8
 
@@ -12,6 +12,7 @@
12
12
  | `slicc attach --cdp <url>` | link a seven that is open in an already-running CDP browser (works now; see [Local setup](#local-setup-slicc-attach)) |
13
13
  | `slicc launch` | launch a browser with CDP in a separate SLICC profile and print its CDP URL |
14
14
  | `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)) |
15
+ | `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)) |
15
16
  | `slicc browsers --json` | list running CDP endpoints and installed browsers, ranked |
16
17
  | `slicc update [--check]` | replace this binary with the latest release (works now; see [Updates](#updates)) |
17
18
 
@@ -39,7 +40,7 @@ Release builds outside npm and app bundles print a notice on stderr when a newer
39
40
  ## Telemetry
40
41
 
41
42
  Release builds 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):
42
- - `enter`, with the subcommand as `source`, from a fixed list (`attach`, `browsers`, `follow`, `launch`, `prompt`, `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.
43
+ - `enter`, with the subcommand as `source`, from a fixed list (`abort`, `attach`, `browsers`, `follow`, `launch`, `prompt`, `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.
43
44
  - `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.
44
45
 
45
46
  `--version` and `--help` send nothing, and development builds never configure a client.
@@ -247,7 +248,7 @@ slicc attach --cdp <url> [--cdp-extra <url>]... [--origin <origin>]... [--signal
247
248
  **Setup over CDP.**
248
249
  1. slicc picks the first page tab whose URL has an allowed origin. Until there is one it says `waiting for a seven tab` and watches for new tabs.
249
250
  2. It attaches, grants the tab's origin `local-network-access`, `local-network` and `loopback-network` with `Browser.setPermission` (best effort), calls `Runtime.addBinding { name: "sliccLinkSend" }`, then `Runtime.enable`.
250
- 3. For each new default execution context of the main frame whose origin is allowed, slicc mints a nonce (16 random bytes, base64url). It then calls `globalThis.sliccLinkReceive({ "t": "hello", "v": 1, "nonce" })` in that context. The call is retried every 100 ms to 1 s until `sliccLinkReceive` is a function.
251
+ 3. For each new default execution context of the main frame whose origin is allowed, slicc mints a nonce (16 random bytes, base64url). It then calls `globalThis.sliccLinkReceive({ "t": "hello", "v": 1, "nonce", "node" })` in that context. `node` is a random id per `slicc` process (16 random bytes, base64url), the same in every hello and HELLO of that process, so seven can tell a second `slicc` on the same browser (a `slicc prompt --cdp …` next to the bridge) from a restart of the same one. The call is retried every 100 ms to 1 s until `sliccLinkReceive` is a function.
251
252
  4. seven answers through `sliccLinkSend(JSON.stringify(message))`:
252
253
  - `{ "t": "offer", "nonce", "sdp" }`;
253
254
  - `{ "t": "candidate", "nonce", "candidate" }`, where `candidate` is `RTCIceCandidate.toJSON()`, or `null` at the end of gathering;
@@ -283,7 +284,7 @@ One WebRTC peer connection. seven offers and the node answers. The node:
283
284
  - **Resets with `EOPNOTSUPP`:** an OPEN for a kind it doesn't serve.
284
285
  - **Closes the link:** an unknown frame type, a short or malformed frame (END with a payload, CREDIT that isn't 4 bytes), stream id 0, a reused id, an id with the wrong parity (page streams are odd, node streams even), or a second OPEN on a stream channel.
285
286
 
286
- HELLO from `attach`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "local", "caps": ["net", "http", "cdp"], "routes": { "prefixes": [], "exit": true }, "policy": { "allow", "deny", "summary" }, "browsers": [ … ] }`. `cdp` and `browsers` are there when at least one browser is listed (see [`cdp`](#cdp-browser-control)). With `--runner`, `caps` adds `"ssh"` and HELLO adds `"sshHostKey": "ssh-ed25519 AAAA…"`, the host key in `authorized_keys` form, so the page can write `<host>.slicc.internal <key>` into the kernel's `known_hosts`. With `--mount`, `caps` adds `"fs"` and HELLO adds `"mounts"` (see [Host folders](#host-folders)).
287
+ HELLO from `attach`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "local", "node", "caps": ["net", "http", "cdp"], "routes": { "prefixes": [], "exit": true }, "policy": { "allow", "deny", "summary" }, "browsers": [ … ] }`. `cdp` and `browsers` are there when at least one browser is listed (see [`cdp`](#cdp-browser-control)). With `--runner`, `caps` adds `"ssh"` and HELLO adds `"sshHostKey": "ssh-ed25519 AAAA…"`, the host key in `authorized_keys` form, so the page can write `<host>.slicc.internal <key>` into the kernel's `known_hosts`. With `--mount`, `caps` adds `"fs"` and HELLO adds `"mounts"` (see [Host folders](#host-folders)).
287
288
 
288
289
  **`ssh`** (cap `ssh`), page → node, with `--runner` only:
289
290
  - OPEN `{ "kind": "ssh" }`, OPENED `{}` at once. The stream's bytes are one SSH connection to the node's SSH server.
@@ -347,7 +348,7 @@ HELLO from `attach`: `{ "v": 1, "role": "node", "name", "host", "version", "mode
347
348
 
348
349
  **`browsers` updates** (page cap `browsers`), node → page. When the list changes while a link is up and the page's HELLO has `browsers` in `caps`, the node opens `OPEN { "kind": "browsers", "browsers": [ … ] }` on the control channel with the full current list in HELLO's shape. It replaces the previous list; there are no deltas. The page answers OPENED `{}` and END, and the node sends END. Updates are sent one at a time per link, a change that comes while one is in flight is sent after it, with the list as it is then, and an update the page doesn't finish within 10 s is reset with `ETIMEDOUT`. A change between the HELLO and the link coming up is sent as an update right away.
349
350
 
350
- `test/integration/testdata/link/link.js` is a page-side implementation of the link (framing, credit, both channel layouts, the violation rules, and `resolve` and raw-fetch helpers) that the integration tests run in Chrome against `slicc attach`. `cdp.js` next to it is a CDP client over `cdp` streams, `fs.js` an op-shaped client for `fs` streams (`call`, `list`, `read`, `write`, `watch`), and `page.js` answers `browsers` and `mounts` updates. Loaded with `?kernel`, the test page lists `kernel-in` and answers `kernel` OPENs with `kernel.js`, a small HTTP and WebSocket echo server in the page.
351
+ `test/integration/testdata/link/link.js` is a page-side implementation of the link (framing, credit, both channel layouts, the violation rules, and `resolve` and raw-fetch helpers) that the integration tests run in Chrome against `slicc attach`. `cdp.js` next to it is a CDP client over `cdp` streams, `fs.js` an op-shaped client for `fs` streams (`call`, `list`, `read`, `write`, `watch`), and `page.js` answers `browsers` and `mounts` updates. `page.js` keeps one link per `node` id from the hello. For tray links (no hello `node`) it replaces an older link with the same fingerprint only when HELLO's `node` matches, as seven does. `agent.js` is a fake agent behind the page's `agent` cap: the tests queue scripted runs, emit transcript events, hold and release a run, reset watch streams, and turn the cap off. Loaded with `?kernel`, the test page lists `kernel-in` and answers `kernel` OPENs with `kernel.js`, a small HTTP and WebSocket echo server in the page.
351
352
 
352
353
  ### Kernel services
353
354
 
@@ -586,7 +587,7 @@ slicc <join-url> follow [--exit] [--allow <rule>]... [--deny <rule>]... [--name
586
587
  - `--cdp <url>`: let seven drive this browser over the link (repeatable, in any form `slicc browsers --cdp` takes; each must answer when `follow` starts). See [`cdp`](#cdp-browser-control), and its warning: the seven on the other machine gets full control of every browser listed. No browser is `seven: true`. Without `--cdp`, `follow` doesn't offer `cdp`, and a `cdp` OPEN is refused with `EOPNOTSUPP`. Each browser's debugging port and its own endpoint addresses are [denied](#network-policy) to `tcp`, `http` and `ssh` forwarding.
587
588
  - `--mount <path>[:<name>][:ro]`: share this folder with the seven on the other machine (cap `fs`, repeatable); see [Host folders](#host-folders). It can read the folder, and change it unless `:ro`.
588
589
 
589
- HELLO from `follow`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "remote", "caps", "routes": { "prefixes": [], "exit" }, "policy" }`. `caps` holds `net` and `http` with `--exit`, `ssh` with `--runner` (plus `sshHostKey`), `cdp` (and HELLO `browsers`) with `--cdp`, `fs` (and HELLO `mounts`) with `--mount`, and always `join`.
590
+ HELLO from `follow`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "remote", "node", "caps", "routes": { "prefixes": [], "exit" }, "policy" }`. `caps` holds `net` and `http` with `--exit`, `ssh` with `--runner` (plus `sshHostKey`), `cdp` (and HELLO `browsers`) with `--cdp`, `fs` (and HELLO `mounts`) with `--mount`, and always `join`.
590
591
 
591
592
  **Identity.** The device is its DTLS certificate. `follow` keeps one ECDSA P-256 certificate per hub origin (`scheme://host:port`), valid for 20 years, in `<config>/slicc/tray-certs.json` (mode `0600`). Every link to that hub uses it, so the fingerprint stays the same across reconnects, restarts and updates. The first run on a hub mints it and says `new device, fingerprint sha-256 …`; later runs say `device, fingerprint …`. Every dial attaches with a fresh `controllerId`, which is only a routing handle.
592
593
 
@@ -598,6 +599,109 @@ HELLO from `follow`: `{ "v": 1, "role": "node", "name", "host", "version", "mode
598
599
 
599
600
  **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.
600
601
 
602
+ ## Remote control: `slicc prompt`, `watch` and `abort`
603
+
604
+ ```
605
+ slicc <join-url> prompt [--steer | --reject] [--thinking] [--json] [--plain] [--abort-on-interrupt] <text>|@file|-
606
+ slicc <join-url> watch [--thinking] [--json] [--plain]
607
+ slicc <join-url> abort
608
+ slicc prompt --cdp <url> [--origin <origin>]... [flags] <text>|@file|-
609
+ slicc watch --cdp <url> [--origin <origin>]... [flags]
610
+ slicc abort --cdp <url> [--origin <origin>]...
611
+ slicc prompt|watch|abort --signal stdio [flags] …
612
+ ```
613
+
614
+ These commands talk to seven's agent over a link that offers nothing to seven (`caps: []`).
615
+ - **With a join URL:** slicc dials the tray as `follow` does (see [Remote setup](#remote-setup-slicc-join-url-follow)), with the same device certificate, so seven sees the same device. A `follow` already running on this machine keeps its link, because the two processes have different `node` ids. These commands never handle `join` or `unlink`. When seven has unlinked the device they say `seven unlinked this device` and exit 1, and they leave the join state and the certificate alone.
616
+ - **With `--cdp`:** slicc links to the seven tab in that browser as `attach` does (see [Local setup](#local-setup-slicc-attach)), with `--origin` as there. A running `slicc` or `attach` on that browser keeps its link.
617
+ - **With `--signal stdio`** (for a test harness that owns CDP itself): the local setup messages go as NDJSON on stdin and stdout, exactly as for `attach --signal stdio`, and `--cdp` isn't needed.
618
+ - stdout also carries the events, as with `--json`. A line with a `nonce` is a setup message, and every other line is an event.
619
+ - `prompt` can't read its text from stdin (`-` exits 2).
620
+ - **Setup:** slicc waits up to 1 minute for seven's HELLO, then gives up with exit 1.
621
+ - **No permission:** without `agent` in seven's HELLO, slicc says `this seven doesn't allow remote control from this device; turn it on in seven's Linked devices` and exits 3. A local link gets `agent` by default. A remote one gets it once *Allow remote control* is on for this device.
622
+ - **Privacy:** prompt text and event contents never go to telemetry or logs, and the join URL is never printed.
623
+
624
+ **`prompt`** sends one prompt and streams the run it belongs to.
625
+ - **Prompt text:** the words after the flags, joined with spaces. `@file` reads a file, and `-` or `@-` reads stdin. Trailing newlines are dropped.
626
+ - An empty prompt, text that isn't UTF-8, or a prompt over 16 MiB exits 2.
627
+ - A prompt up to 60 KiB goes in the OPEN as `text`. A longer one goes as DATA after it (see `agent` below).
628
+ - **When seven is busy:** by default the prompt is queued as a follow-up (`whenBusy: "followUp"`). `--steer` steers the running turn, and `--reject` doesn't send it at all: slicc says `seven is busy` and exits 1. `--steer` and `--reject` can't be combined.
629
+ - **Output:** the assistant's text goes to stdout as it streams. Separate text entries are separated by a blank line, and stdout ends with a newline.
630
+ - Tool calls, tool results, notices and errors go to stderr, and so does thinking with `--thinking`.
631
+ - The prompt's own `user` event isn't shown.
632
+ - **`--json`:** the events are printed on stdout instead, one NDJSON line each, exactly as seven sent them, including `delivered` and the final `end`. Nothing is rendered.
633
+ - **Exit status:**
634
+ - `0` when the run ends with `end` `stop`;
635
+ - `1` for `end` `error` (`the run failed: <message>`), for `end` `aborted` (`the run was aborted`), and for a stream or link that ends before `end` (`lost the link to seven; the run goes on there`);
636
+ - `2` for bad usage;
637
+ - `3` without permission;
638
+ - `130` on Ctrl-C or `SIGTERM`.
639
+ - **Ctrl-C** leaves the run going in seven. With `--abort-on-interrupt`, slicc first opens `abort`.
640
+
641
+ **`watch`** follows the agent until Ctrl-C or `SIGTERM`, then exits 0.
642
+ - **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.
643
+ - **Status lines** on stderr: `slicc: watching <name>`, `slicc: lost the link to <name>; reconnecting`, and for the tray `<reason>; trying again in <wait>`.
644
+ - **Reconnects:** when the stream ends or is reset, slicc opens a new `watch` on the same link. When the link goes, it sets up a new one, through the tray again or by waiting for seven over CDP. Waits start at 1 s, double up to 30 s with ±25 % jitter, and go back to 1 s once a stream opens.
645
+ - **Resuming:** each new stream asks for `since`, the id of the last event slicc saw, so nothing still in the transcript is lost. Nothing is shown twice either. For `text` and `thinking`, slicc counts the bytes it has shown per entry and skips that many from the entry's replay. Any other entry is skipped when its id was already seen. `run` events have no id and aren't replayed. When seven answers `gap: true`, slicc prints `some events were missed`.
646
+ - **Exit status:** `1` when the link can't be set up for good (a terminal tray failure, or the CDP connection closing), `2` for bad usage, `3` without permission.
647
+
648
+ **`abort`** aborts the agent's current run. It prints `slicc: aborted the run`, or `slicc: nothing was running`, and exits 0. Otherwise it exits 1 on errors, 3 without permission and 130 on Ctrl-C.
649
+
650
+ **Styling.** When a stream is a terminal (and `TERM` isn't `dumb`), its lines are styled:
651
+ - tool calls `⚙ <name> <summary>`;
652
+ - results ` ↳ <summary>`, or ` ✗ <summary>` for a failure;
653
+ - notices `• <text>`, and errors `✗ <message> <detail>`;
654
+ - thinking dim and italic, and prompts in `watch` bold.
655
+
656
+ `NO_COLOR` keeps the layout without colors. When stdout and stderr are the same terminal, a line on one first ends an unfinished line on the other.
657
+
658
+ Otherwise, or with `--plain`, there are no escape codes:
659
+ - `tool <name>: <summary>`, `tool <name> ok: <summary>`, `tool <name> failed: <summary>`;
660
+ - `notice: <text>`, `error: <message> (<detail>)`;
661
+ - `thinking: <text>`.
662
+
663
+ Summaries are one line of at most 200 characters. Escape sequences and control characters other than newline and tab are removed from everything seven sends before it's shown.
664
+
665
+ ### `agent` (page cap `agent`), node → page
666
+
667
+ - **Who may:** the node opens `agent` streams only to a page whose HELLO lists `agent`, and the page refuses them with `EACCES` otherwise.
668
+ - **Several processes, one device:** the hello and HELLO carry the process's `node` id. seven replaces an older link of the same device (any local link, or the same fingerprint over the tray) only when `node` matches. Over the tray it decides once HELLO arrives.
669
+
670
+ **`prompt`:** `OPEN { "kind": "agent", "op": "prompt", "text", "whenBusy": "followUp" | "steer" | "reject", "thinking"?: true }` on its own channel.
671
+ - **Answer:** OPENED `{ "delivered": "run" | "steer" | "follow-up" }` once the agent took it. A `reject` while busy is `RESET EBUSY`.
672
+ - **Then DATA:** NDJSON events, starting at this prompt's own `user` event, until the run that includes it ends. The last line is `{"t":"end","reason":"stop"|"aborted"|"error","message"?}`, then END. The node sends END right after OPENED.
673
+ - **Long prompts:** a prompt over 60 KiB goes as `"length": <bytes>` instead of `text`.
674
+ - The page answers OPENED `{}` at once.
675
+ - The node sends exactly that many bytes of UTF-8 as DATA, then END. A different count is `RESET EPROTO`.
676
+ - The page then delivers it. Its first line is `{"t":"delivered","delivered"}`, or it resets with `EBUSY` instead.
677
+ - **Aborting:** a RESET from the node, or a closed link, doesn't abort the run. Only `abort` does.
678
+
679
+ **`watch`:** `OPEN { "kind": "agent", "op": "watch", "since"?: "<entry id>", "thinking"?: true }` on its own channel.
680
+ - **Answer:** OPENED `{ "head": "<entry id>", "gap"?: true }`, then NDJSON events until either side resets.
681
+ - **Without `since`:** the events start at the next one.
682
+ - **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.
683
+
684
+ **`abort`:** `OPEN { "kind": "agent", "op": "abort" }`, answered OPENED `{ "aborted": true | false }` (`false` when nothing was running), then END.
685
+
686
+ **Events,** one JSON object per line:
687
+
688
+ | event | meaning |
689
+ | --- | --- |
690
+ | `{"t":"user","id","text","delivered"}` | a prompt |
691
+ | `{"t":"text","id","delta"}` | assistant text as it streams |
692
+ | `{"t":"thinking","id","delta"}` | thinking, only on streams opened with `thinking` |
693
+ | `{"t":"tool","id","call","name","summary"}` | a tool call, with a one-line summary such as the bash command |
694
+ | `{"t":"tool-result","id","call","ok","summary"}` | its result |
695
+ | `{"t":"run","state":"start"\|"end","reason"?}` | a run starts or ends |
696
+ | `{"t":"notice","id","text"}` | retries, compactions, rewinds |
697
+ | `{"t":"error","id","message","detail"?}` | an error |
698
+ | `{"t":"delivered","delivered"}` | a long prompt was taken (`prompt` only) |
699
+ | `{"t":"end","reason","message"?}` | the last line of a `prompt` stream |
700
+
701
+ - **Ids:** `id` is the transcript entry id, and `delta` lines for one `id` arrive in order.
702
+ - **Limits:** `summary` is at most 200 characters. Credentials and tool output beyond the summary are never sent.
703
+ - **Unknown events:** the node ignores events and fields it doesn't know.
704
+
601
705
  ## Tray hub signaling (remote setup)
602
706
 
603
707
  A node on another machine sets up its link through the tray hub, the `slicc-tray-hub` worker on `www.sliccy.ai`. seven is the tray leader and the node is a follower. The wire contract is six's `packages/shared-ts/src/tray-signaling.ts`. The node only signals over it and never speaks six's tray-sync messages.
@@ -640,15 +744,17 @@ The real-Chrome tests in `test/integration/` launch headless, so they run the ex
640
744
  semantic-release cuts releases from `main` in `.github/workflows/release.yml`, on a macOS runner:
641
745
  1. `scripts/release-plan.mjs` asks semantic-release (dry run) for the next version, and stops when there is none.
642
746
  2. `scripts/package.sh <version>` builds `darwin`, `linux` and `windows` × `amd64`, `arm64` with `CGO_ENABLED=0`, `-trimpath` and `-X main.version=<version>`. It signs and notarizes the darwin binaries, signs the windows binaries with jsign against Azure Trusted Signing, and writes `SHA256SUMS`. Without the signing secrets (forks, pull requests) it warns and leaves those binaries unsigned.
643
- 3. `scripts/npm-stage.mjs` stages `@ai-ecoverse/slicc` and the six platform packages. `--name sliccy` stages the same launcher as `sliccy`, with a `sliccy` bin.
747
+ 3. `scripts/npm-stage.mjs` stages `@ai-ecoverse/slicc` and the six platform packages into `dist/npm/`. It also stages the same launcher as `sliccy` (with a `sliccy` bin and a short preview README) into `dist/npm-next/`, as version `7.0.0-next.<version>`, with exact `optionalDependencies` on this release's platform packages.
644
748
  4. `actions/attest-build-provenance` attests every binary.
645
- 5. semantic-release checks the version again, tags, creates the GitHub release with every binary and `SHA256SUMS`, then `scripts/npm-publish.mjs` publishes the platform packages and the launcher through npm trusted publishing (OIDC, with provenance). Versions already on npm are skipped.
749
+ 5. semantic-release checks the version again, tags, creates the GitHub release with every binary and `SHA256SUMS`, then `scripts/npm-publish.mjs` publishes the platform packages and the launcher through npm trusted publishing (OIDC, with provenance), and then `sliccy` with `--tag next`. Versions already on npm are skipped.
646
750
 
647
- On pull requests the same workflow runs as a dry run: an unsigned build of all six targets, the npm packages packed with `--dry-run`, and each binary run with `--version` on its own OS and CPU.
751
+ On pull requests the same workflow runs as a dry run: an unsigned build of all six targets, the npm packages and `sliccy` (with `--tag next`) packed with `--dry-run`, and each binary run with `--version` on its own OS and CPU.
648
752
 
649
753
  The workflow reads these repository secrets. Each group is optional, and a missing group leaves its binaries unsigned:
650
754
  - macOS signing: `APPLE_CERTIFICATE_BASE64`, `APPLE_DEVELOPER_CERTIFICATE_PASSWORD`;
651
755
  - notarization: `APPLE_API_KEY_ID`, `APPLE_API_KEY_ISSUER_ID`, `APPLE_API_KEY_P8_BASE64`;
652
756
  - Windows signing: `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_TRUSTED_SIGNING_ENDPOINT`, `AZURE_TRUSTED_SIGNING_ACCOUNT`, `AZURE_TRUSTED_SIGNING_PROFILE`, and `AZURE_CLIENT_SECRET` unless the app registration trusts this workflow through a federated credential (OIDC).
653
757
 
654
- npm needs no token. `npm run trust` (fledgling) configures trusted publishing for the seven packages listed under `fledgling.include` in `package.json`. Publishing to npm is off until the repository variable `SLICC_NPM_PUBLISH` is `true`; until then a release only warns.
758
+ npm needs no token. `npm run trust` (fledgling) configures trusted publishing for the seven packages listed under `fledgling.include` in `package.json`. Publishing to npm is off until the repository variable `SLICC_NPM_PUBLISH` is `true`, and `sliccy` stays off until `SLICCY_NEXT_PUBLISH` is `true`; until then a release skips them with a notice.
759
+
760
+ `sliccy` only ever goes to the `next` dist-tag, so `npx sliccy` keeps running SLICC six and `npx sliccy@next` runs this binary. `npm-publish.mjs` refuses, even in a dry run, to publish `sliccy` with any tag but `next` or with a version that doesn't match `^7\.0\.0-next\.`. Nothing here changes `sliccy`'s other dist-tags.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc",
3
- "version": "1.23.0",
3
+ "version": "1.25.0",
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,11 +18,11 @@
18
18
  "node": ">=18"
19
19
  },
20
20
  "optionalDependencies": {
21
- "@ai-ecoverse/slicc-darwin-arm64": "1.23.0",
22
- "@ai-ecoverse/slicc-darwin-amd64": "1.23.0",
23
- "@ai-ecoverse/slicc-linux-arm64": "1.23.0",
24
- "@ai-ecoverse/slicc-linux-amd64": "1.23.0",
25
- "@ai-ecoverse/slicc-windows-arm64": "1.23.0",
26
- "@ai-ecoverse/slicc-windows-amd64": "1.23.0"
21
+ "@ai-ecoverse/slicc-darwin-arm64": "1.25.0",
22
+ "@ai-ecoverse/slicc-darwin-amd64": "1.25.0",
23
+ "@ai-ecoverse/slicc-linux-arm64": "1.25.0",
24
+ "@ai-ecoverse/slicc-linux-amd64": "1.25.0",
25
+ "@ai-ecoverse/slicc-windows-arm64": "1.25.0",
26
+ "@ai-ecoverse/slicc-windows-amd64": "1.25.0"
27
27
  }
28
28
  }