@ai-ecoverse/slicc-capture 1.3.2 → 1.3.3

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
@@ -244,7 +244,7 @@ This section is the installer contract that slicc-open, slicc-capture, slicc-aud
244
244
 
245
245
  ### Release assets
246
246
 
247
- semantic-release's `@semantic-release/npm` packs the package into `release/` (`tarballDir`). `@semantic-release/exec` then runs `node scripts/assets.mjs release <version>`, which renames the tarball to `<pkg>-<version>.tgz`, refuses (exit 1, writing nothing) when the tarball's `package.json` has no `bin` or lacks a file a `bin` entry names, copies `install.sh` and `install.ps1` next to it, and writes `SHA256SUMS`: one `<sha256> <name>` line each for the tarball, `install.sh` and `install.ps1`, in that order. `@semantic-release/github` attaches all four files to the release. `ci.yml` needs no release step of its own.
247
+ semantic-release's `@semantic-release/npm` packs the package into `release/` (`tarballDir`). `@semantic-release/exec` then runs `node scripts/assets.mjs release <version>`, which refuses (exit 1, leaving `release/` as it was, npm's tarball name included) when the tarball's `package.json` has no `bin` or lacks a file a `bin` entry names, and otherwise renames the tarball to `<pkg>-<version>.tgz`, copies `install.sh` and `install.ps1` next to it, and writes `SHA256SUMS`: one `<sha256> <name>` line each for the tarball, `install.sh` and `install.ps1`, in that order. `@semantic-release/github` attaches all four files to the release. `ci.yml` needs no release step of its own.
248
248
 
249
249
  ### Options and exit codes
250
250
 
@@ -254,11 +254,11 @@ semantic-release's `@semantic-release/npm` packs the package into `release/` (`t
254
254
  | `--dir DIR` (or `--dir=DIR`) | `-Dir DIR` | where the launchers go (default: `~/.local/bin`; on Windows `%LOCALAPPDATA%\<pkg>\bin`) |
255
255
  | `--help` (or `-h`) | `-Help` | print the usage to stdout and exit 0 |
256
256
 
257
- Only the flags select anything: no environment variable stands in for `--version` or `--dir`. `install.sh` handles its options (`--help` and the usage errors included) before it works out any directory, so they work without `HOME`. `HOME` is needed only for the defaults: without it, and without both `--dir` and `XDG_DATA_HOME`, `install.sh` exits 1 with `install.sh: HOME is not set; give --dir and set XDG_DATA_HOME`. `install.sh` exits **0** when it installed, **1** when something failed (a download, a checksum, no Node and no way to get one), with `install.sh: <what>` on stderr, and **2** for an unknown option or a missing value, with the usage on stderr. `install.ps1` exits 0 or 1 the same way when it is run as a file, and its parameters are PowerShell's own, so an unknown one is PowerShell's error. Run through `irm … | iex` or a script block, it prints the error and returns instead of calling `exit`, so it never closes the user's PowerShell.
257
+ Only the flags select anything: no environment variable stands in for `--version` or `--dir`. `install.sh` handles its options (`--help` and the usage errors included) before it works out any directory, so they work without `HOME`. `HOME` is needed only for the defaults: without it, and without both `--dir` and `XDG_DATA_HOME`, `install.sh` exits 1 with `install.sh: HOME is not set; give --dir and set XDG_DATA_HOME`. `install.sh` exits **0** when it installed, **1** when something failed (a download, a checksum, an archive that doesn't unpack, no Node and no way to get one), with `install.sh: <what>` on stderr, and **2** for an unknown option or a missing value, with the usage on stderr. `install.ps1` exits 0 or 1 the same way when it is run as a file, and its parameters are PowerShell's own, so an unknown one is PowerShell's error. Run through `irm … | iex` or a script block, it prints the error and returns instead of calling `exit`, so it never closes the user's PowerShell. It sets `$PSNativeCommandUseErrorActionPreference = $false` in its own scope, so a caller's `$true` (pwsh 7.4 and later) can't turn the exit code of `node`, `tar` or `npm` into an error that stops the install. It runs `node --version`, `tar` and `npm` with `$ErrorActionPreference = 'Continue'` in a child scope, because Windows PowerShell 5.1 turns each line a native command writes to a redirected stderr into an error, and under `'Stop'` the first one would end the install before its `install.ps1:` message.
258
258
 
259
259
  ### Node
260
260
 
261
- The launchers run the package with Node 24 or later. The installer uses the first `node` on `PATH` when it is new enough, otherwise one it downloaded before, into `<data>/node`. Failing both, it downloads the newest LTS release of 24 or later (or the newest release, when no LTS qualifies) from `index.json`. That download is `node-<version>-<os>-<arch>.tar.gz` (`darwin` or `linux`, `x64` or `arm64`), or `node-<version>-win-<arch>.zip` on Windows, checked against that release's `SHASUMS256.txt`. `.tar.gz` is used because `xz` isn't on every minimal Linux. On musl Linux, where nodejs.org has no build, the installer says to install Node with the package manager and exits 1.
261
+ The launchers run the package with Node 24 or later. The installer uses the first `node` on `PATH` when it is new enough, otherwise one it downloaded before, into `<data>/node`. Failing both, it downloads the newest LTS release of 24 or later (or the newest release, when no LTS qualifies) from `index.json`. That download is `node-<version>-<os>-<arch>.tar.gz` (`darwin` or `linux`, `x64` or `arm64`), or `node-<version>-win-<arch>.zip` on Windows, checked against that release's `SHASUMS256.txt`. An archive that doesn't unpack exits 1 with `install.sh: could not unpack node-<version>-<os>-<arch>.tar.gz` (or `install.ps1: could not unpack node-<version>-win-<arch>.zip`), and leaves neither its temporary directory nor a partial `<data>/node` behind. `.tar.gz` is used because `xz` isn't on every minimal Linux. On musl Linux, where nodejs.org has no build, the installer says to install Node with the package manager and exits 1.
262
262
 
263
263
  ### Downloads
264
264
 
@@ -271,19 +271,19 @@ The launchers run the package with Node 24 or later. The installer uses the firs
271
271
 
272
272
  ### Files
273
273
 
274
- The tarball is unpacked (with `tar`, `%SystemRoot%\System32\tar.exe` on Windows) into a temporary directory next to the versioned data directory `<data>/<version>`. When its `package.json` has a non-empty `dependencies` or `optionalDependencies`, the installer removes `devDependencies` from that copy of `package.json` (npm would still resolve them against the registry, `--omit=dev` or not), then runs `npm install --omit=dev --ignore-scripts --no-audit --no-fund` there. It uses the npm that comes with the Node it picked, run by that Node (`<node dir>/../lib/node_modules/npm`, or `node_modules\npm` next to `node.exe`; `install.sh` falls back to `npm` on `PATH`). npm's output goes to stderr. Without such dependencies the step is skipped, so it needs neither npm nor the network. A failed `npm install`, or a missing npm, exits 1 and removes the partial directory. Only then does the directory replace `<data>/<version>`, so a failed install never leaves a broken version behind. `<data>` is `${XDG_DATA_HOME:-~/.local/share}/<pkg>`, or `%LOCALAPPDATA%\<pkg>` on Windows. Other versions stay where they are, and there is no `current` link. Each launcher names its version's entry script, `<data>/<version>/host/<cmd>.mjs`, and the Node it was installed with, by absolute path.
274
+ The tarball is unpacked (with `tar`, `%SystemRoot%\System32\tar.exe` on Windows) into a temporary directory next to the versioned data directory `<data>/<version>`. A tarball that doesn't unpack exits 1 with `install.sh: could not unpack <pkg>-<version>.tgz` (or `install.ps1: could not unpack <pkg>-<version>.tgz`) and removes the partial directory. When its `package.json` has a non-empty `dependencies` or `optionalDependencies`, the installer removes `devDependencies` from that copy of `package.json` (npm would still resolve them against the registry, `--omit=dev` or not), then runs `npm install --omit=dev --ignore-scripts --no-audit --no-fund` there. It uses the npm that comes with the Node it picked, run by that Node (`<node dir>/../lib/node_modules/npm`, or `node_modules\npm` next to `node.exe`; `install.sh` falls back to `npm` on `PATH`). npm's output goes to stderr. Without such dependencies the step is skipped, so it needs neither npm nor the network. A failed `npm install`, or a missing npm, exits 1 and removes the partial directory. Only then does the directory replace `<data>/<version>`, so a failed install never leaves a broken version behind. `<data>` is `${XDG_DATA_HOME:-~/.local/share}/<pkg>`, or `%LOCALAPPDATA%\<pkg>` on Windows. Other versions stay where they are, and there is no `current` link. Each launcher names its version's entry script, `<data>/<version>/host/<cmd>.mjs`, and the Node it was installed with, by absolute path.
275
275
 
276
276
  | platform | launchers in `DIR` | what they do |
277
277
  | --- | --- | --- |
278
278
  | macOS, Linux | `<cmd>`, a POSIX sh script | sets and exports `<CMD>_INSTALL_DIR='<DIR>'`, exports `NODE_USE_ENV_PROXY=1` unless it is already set, then `exec '<node>' '<entry>' "$@"`; every path is single-quoted, so no path is ever evaluated |
279
- | Windows | `<cmd>.ps1` (UTF-8 with a BOM) | saves the caller's `$env:<CMD>_INSTALL_DIR` and sets it, sets `$env:NODE_USE_ENV_PROXY = '1'` when it is unset, runs `& '<node.exe>' '<entry>' @sccaptureArgs` in `try`, restores the old `<CMD>_INSTALL_DIR` in `finally` (or removes it when it was unset) and removes a `NODE_USE_ENV_PROXY` it set, then exits with node's exit code. A `.ps1` runs inside the caller's PowerShell session, and this keeps the variable from leaking into that session. `@sccaptureArgs` is `@args` with each array argument (`a,b`) flattened into separate arguments, as PowerShell passes them to a program, and each argument as text. When PowerShell passes arguments to programs the legacy way, which drops empty arguments and doesn't escape `"` (Windows PowerShell 5.1 whatever `$PSNativeCommandArgumentPassing` says, `$PSNativeCommandArgumentPassing = 'Legacy'`, or pwsh before 7.3 without the variable; pwsh 7.3 and later without it pass the standard way), then each `"` becomes `\"` (doubling the backslashes before it), an empty argument becomes `""`, and on Windows PowerShell an argument with whitespace gets its trailing backslashes doubled, so `node.exe` gets the arguments it was given |
279
+ | Windows | `<cmd>.ps1` (UTF-8 with a BOM) | saves the caller's `$env:<CMD>_INSTALL_DIR` and sets it, sets `$env:NODE_USE_ENV_PROXY = '1'` when it is unset, runs `& '<node.exe>' '<entry>' @sccaptureArgs` in `try`, restores the old `<CMD>_INSTALL_DIR` in `finally` (or removes it when it was unset) and removes a `NODE_USE_ENV_PROXY` it set, then exits with node's exit code. A `.ps1` runs inside the caller's PowerShell session, and this keeps the variable from leaking into that session. `@sccaptureArgs` is `@args` with each array argument (`a,b`) flattened into separate arguments, as PowerShell passes them to a program, and each argument as text. When PowerShell passes arguments to programs the legacy way, which drops empty arguments and doesn't escape `"` (Windows PowerShell 5.1 whatever `$PSNativeCommandArgumentPassing` says, `$PSNativeCommandArgumentPassing = 'Legacy'`, or pwsh before 7.3 without the variable; pwsh 7.3 and later without it pass the standard way), then each `"` becomes `\"` (doubling the backslashes before it), an empty argument becomes `""`, and on Windows PowerShell an argument with whitespace gets its trailing backslashes doubled, so `node.exe` gets the arguments it was given. Since PowerShell reads an unquoted `a,b` as an array, `sccapture -R 0,0,800,600 shot.png` reaches `sccapture` as four arguments, so quote any argument with a comma in it (`sccapture -R '0,0,800,600' shot.png`). It also sets `$PSNativeCommandUseErrorActionPreference = $false` and `$ErrorActionPreference = 'Continue'` in its own scope, so neither a caller's `$true` (pwsh 7.4 and later) nor, on Windows PowerShell 5.1, a caller's `'Stop'` with stderr redirected can turn node's exit code or its stderr into an error |
280
280
  | Windows | `<cmd>.cmd` (UTF-8, code page 65001 while it runs) | sets `<CMD>_INSTALL_DIR` and, when it is undefined, `NODE_USE_ENV_PROXY=1` (both local to the `.cmd` through `setlocal`), then runs `"<node.exe>" "<entry>" %* & call :done %%ERRORLEVEL%% & call exit /b %%ERRORLEVEL%%` as one line, so a `)` in an argument can't end anything early, and a launcher that `--upgrade` rewrites mid-run is never read again; `:done` restores the code page and returns node's status, and `call exit /b` exits with it explicitly, because a bare `exit /b` leaves the exit code of `cmd /c` (which PowerShell and every other program uses to run a `.cmd`) at 0. Arguments reach it through cmd's own parsing: `%`, `^`, `&` and `)` are safe inside `"…"`, and a `\"` inside one counts as a quote to cmd, so the quotes in an argument have to pair up |
281
281
 
282
282
  Both Windows launchers only start `node.exe` with the entry script and the arguments, and `<cmd>` itself never runs `cmd.exe`. `NODE_USE_ENV_PROXY=1` makes Node's `fetch` (and so `--upgrade`) honour `HTTPS_PROXY`, `HTTP_PROXY` and `NO_PROXY` the way curl does. On Windows the installer adds `DIR` to the user's `PATH` when it isn't there already, and says so, along with the PowerShell command that removes it again. When `Get-ExecutionPolicy` is `Restricted`, `AllSigned` or `Undefined`, PowerShell won't run `<cmd>.ps1`, so `install.ps1` prints to stderr that `<cmd>` needs `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`, or `<cmd>.cmd` instead; it never changes the policy itself. elsewhere it prints the `export PATH=…` line to add when `DIR` isn't on `PATH`. After writing the launchers, the installer runs each command's `--version` and requires the version it installed, either alone (`1.2.0`) or in the older `<cmd> 1.2.0` form, so that a `--version` naming an older release still installs. Then it prints `<cmd> <version> installed to <launcher>` to stdout for each command.
283
283
 
284
284
  ### How `--upgrade` uses it
285
285
 
286
- `<CMD>_INSTALL_DIR` is how a command knows the installer put it there. When it is set, `--upgrade` uses Node's `fetch` to download `install.sh` (or `install.ps1` on Windows) from `SLICC_INSTALL_BASE_URL`, or the latest release without it, into a temporary directory. The download has 60 seconds (`AbortSignal.timeout`); after that it prints `<cmd>: download timed out` to stderr and exits 1. It runs `sh install.sh --dir <CMD>_INSTALL_DIR`, or `powershell.exe` (else `pwsh.exe`) `-NoProfile -NonInteractive -ExecutionPolicy Bypass -File install.ps1 -Dir <CMD>_INSTALL_DIR` without `PSModulePath` in its environment, with the installer's stderr passed through. (Run from PowerShell 7, the command inherits pwsh's `PSModulePath`, and Windows PowerShell started with it loses `Get-FileHash`.) The new version is the one in the installer's `<cmd> <version> installed to` line. A download that fails, an installer that exits non-zero or doesn't print that line, or a missing `sh` or PowerShell makes `--upgrade` exit 1. Without `<CMD>_INSTALL_DIR`, the command counts as installed with npm. Commands remove `<CMD>_INSTALL_DIR` from the environment of everything they start.
286
+ `<CMD>_INSTALL_DIR` is how a command knows the installer put it there. When it is set, `--upgrade` uses Node's `fetch` to download `install.sh` (or `install.ps1` on Windows) from `SLICC_INSTALL_BASE_URL`, or the latest release without it, into a temporary directory. The download has 60 seconds (`AbortSignal.timeout`); after that it prints `<cmd>: download timed out` to stderr and exits 1. It runs `sh install.sh --dir <CMD>_INSTALL_DIR`, or `powershell.exe` (else `pwsh.exe`) `-NoProfile -NonInteractive -ExecutionPolicy Bypass -File install.ps1 -Dir <CMD>_INSTALL_DIR` without `PSModulePath` in its environment, with the installer's stderr passed through. (Run from PowerShell 7, the command inherits pwsh's `PSModulePath`, and Windows PowerShell started with it loses `Get-FileHash`.) The new version is the one in the installer's `<cmd> <version> installed to` line. A download that fails (an HTTP error status prints `<cmd>: could not download <url>: HTTP <status>`, and its body is cancelled, not left open), an installer that exits non-zero or doesn't print that line, or a missing `sh` or PowerShell makes `--upgrade` exit 1. Without `<CMD>_INSTALL_DIR`, the command counts as installed with npm. Commands remove `<CMD>_INSTALL_DIR` from the environment of everything they start.
287
287
 
288
288
  ## Development
289
289
 
@@ -296,8 +296,8 @@ npm run test:unit
296
296
 
297
297
  - `npm install` also installs the git hooks into this worktree's own `node_modules/` through slicc-shared-web's `slicc-install-hooks` and the committed `.githooks/`.
298
298
  - `npm run lint`: Biome, the no-comment check and the other [slicc-shared-web](https://github.com/ai-ecoverse/slicc-shared-web) checks, then `shellcheck -s sh` and `dash -n` on `install.sh` and `bin/*`.
299
- - `npm test`: the integration tests in `test/integration/`. `commands.test.mjs` runs `screencapture` and `sccapture` on `@ai-ecoverse/slicc-kernel/node` (the newest kernel, pinned exactly) with wasm-bash and wasm-coreutils, and a fake `capture.screen` and `clipboard.write` handler (`createNodeKernel({ requests })`): every option's header, the bytes written unchanged, the errnos and their messages, `-c`, `-v`, and slicc-kernel 1.152.2, which has no `/dev/embedder`. `test/integration/repo.test.mjs` checks the workflow, the release config, the pinned devDependencies and what `npm pack` ships. The host tests run `host/` against fake `screencapture`, `grim`, `slurp`, `gnome-screenshot`, `import`, `scrot`, `wl-copy`, `xclip`, `xdg-open`, `powershell.exe` and `pwsh.exe` on a temporary `PATH`, and `--upgrade` against installers served from a local HTTP server, with the platform forced, so each branch is checked on any machine; only CI touches a real screen. `install.test.mjs` runs `install.sh` on a tarball packed from the tree, with the Node on `PATH` and with a Node download from a fake `nodejs.org`, and `--upgrade` against a release served from a local directory; `install.ps1` is checked statically, and run when `pwsh` is on `PATH`. On Windows the host tests fake a program with a copy of a small `.exe` that `csc.exe` builds from C# (`fake-windows.mjs`), which runs the fake's script with Node, so the Windows branches run for real; the macOS and Linux branches and the `sh`-based `--upgrade` tests are skipped there.
300
- - `npm run test:windows`: on Windows, the host tests and `windows.test.mjs`, which installs a tarball packed from the tree with `install.ps1` under both Windows PowerShell and `pwsh`, from a local HTTP server into a temporary `-Dir` named `my 'bin' (x86) & 100%`; runs `sccapture.cmd` and `sccapture.ps1` with `--version`, `--help` and a usage error; checks the arguments `node` gets through both launchers (full of `)`, `&`, `%`, `^`, spaces, quotes, trailing backslashes and empty ones, in pwsh's `Standard` and `Legacy` argument passing and with `$PSNativeCommandArgumentPassing` removed, plus a comma list `a,'b c'`, through copies of the launchers that run a script printing its argv), and through them the `SCCAPTURE_*` data a fake `powershell.exe` gets for a file named `a ) & ^ 'f' b.png`; checks that neither launcher leaks `SCCAPTURE_INSTALL_DIR` or `NODE_USE_ENV_PROXY`, that the `.cmd` restores the code page, and that the printed PATH undo works; captures the real screen to a PNG through `sccapture.cmd` (also with pwsh's `PSModulePath`) and through `sccapture.ps1` from Windows PowerShell and from `pwsh`, checked by its magic bytes and its size; upgrades in place with `--upgrade` from `sccapture.cmd`, `sccapture.ps1` and `pwsh`; and downloads Node as a `.zip` from a fake `nodejs.org`. CI runs it on `windows-latest` (`windows-test` in `ci.yml`); elsewhere `windows.test.mjs` is skipped.
299
+ - `npm test`: the integration tests in `test/integration/`. `commands.test.mjs` runs `screencapture` and `sccapture` on `@ai-ecoverse/slicc-kernel/node` (the newest kernel, pinned exactly) with wasm-bash and wasm-coreutils, and a fake `capture.screen` and `clipboard.write` handler (`createNodeKernel({ requests })`): every option's header, the bytes written unchanged, the errnos and their messages, `-c`, `-v`, and slicc-kernel 1.152.2, which has no `/dev/embedder`. `test/integration/repo.test.mjs` checks the workflow, the release config, the pinned devDependencies and what `npm pack` ships. The host tests run `host/` against fake `screencapture`, `grim`, `slurp`, `gnome-screenshot`, `import`, `scrot`, `wl-copy`, `xclip`, `xdg-open`, `powershell.exe` and `pwsh.exe` on a temporary `PATH`, and `--upgrade` against installers served from a local HTTP server (a 500 whose body never ends has to be closed within 2 seconds), with the platform forced, so each branch is checked on any machine; only CI touches a real screen. `install.test.mjs` runs `install.sh` on a tarball packed from the tree, with the Node on `PATH` and with a Node download from a fake `nodejs.org`, a truncated tarball and Node archive whose checksums match, and `--upgrade` against a release served from a local directory; `install.ps1` is checked statically, and run when `pwsh` is on `PATH`, also with `$PSNativeCommandUseErrorActionPreference = $true` and `$ErrorActionPreference = 'Stop'` (an install, a failed npm and the launcher's exit 2), and on a truncated tarball. `scripts/assets.mjs` has to leave a rejected tarball under npm's name and take one already renamed. On Windows the host tests fake a program with a copy of a small `.exe` that `csc.exe` builds from C# (`fake-windows.mjs`), which runs the fake's script with Node, so the Windows branches run for real; the macOS and Linux branches and the `sh`-based `--upgrade` tests are skipped there.
300
+ - `npm run test:windows`: on Windows, the host tests and `windows.test.mjs`, which installs a tarball packed from the tree with `install.ps1` under both Windows PowerShell and `pwsh`, from a local HTTP server into a temporary `-Dir` named `my 'bin' (x86) & 100%`; runs `sccapture.cmd` and `sccapture.ps1` with `--version`, `--help` and a usage error; checks the arguments `node` gets through both launchers (full of `)`, `&`, `%`, `^`, spaces, quotes, trailing backslashes and empty ones, in pwsh's `Standard` and `Legacy` argument passing and with `$PSNativeCommandArgumentPassing` removed, plus a comma list `a,'b c'`, through copies of the launchers that run a script printing its argv), and through them the `SCCAPTURE_*` data a fake `powershell.exe` gets for a file named `a ) & ^ 'f' b.png`; checks that neither launcher leaks `SCCAPTURE_INSTALL_DIR` or `NODE_USE_ENV_PROXY`, that the `.cmd` restores the code page, and that the printed PATH undo works; captures the real screen to a PNG through `sccapture.cmd` (also with pwsh's `PSModulePath`) and through `sccapture.ps1` from Windows PowerShell and from `pwsh`, checked by its magic bytes and its size; installs again with `$PSNativeCommandUseErrorActionPreference = $true` and `$ErrorActionPreference = 'Stop'`, where `sccapture.ps1 --nope` exits 2 and leaves both preferences as they were, and a truncated tarball, with `2>&1`, exits 1 with `could not unpack`; upgrades in place with `--upgrade` from `sccapture.cmd`, `sccapture.ps1` and `pwsh`; and downloads Node as a `.zip` from a fake `nodejs.org`, after refusing a truncated one. CI runs it on `windows-latest` (`windows-test` in `ci.yml`); elsewhere `windows.test.mjs` is skipped.
301
301
  - `page.test.mjs` registers [the page module](#the-page-module) through `createNodeKernel({ requests })`, with a fake `display` and fake `ImageCapture`, `OffscreenCanvas` and `<video>` injected through `create`, and runs the real `screencapture`: the constraints, the crop, the type and quality, the delay and its progress, an interrupt in the picker and in the delay, **Stop sharing**, the picker's timeout, the errnos and their messages end to end, and that every track is stopped. `browser.test.mjs` runs the module in Chrome, through slicc-shared-web's harness, with a `display` that returns a canvas's `captureStream()`: PNG, JPEG and WebP, the crop, the `<video>` fallback, an abort and the stopped track. It runs on CI only, and is skipped without `CI`.
302
302
  - `npm run test:unit`: the unit tests in the gitignored `test/unit/`, with coverage in `coverage/unit/lcov.info`. `npm run test:sh` runs the `test/unit/*.sh.mjs` ones, which trace `bin/` with `set -x` in the node kernel, and writes `coverage/sh/lcov.info`. The pre-commit hook wants 100% coverage of the changed lines of both, and runs `diff-cover` through `uvx`, so install [uv](https://docs.astral.sh/uv/) once.
303
303
 
package/host/upgrade.mjs CHANGED
@@ -18,7 +18,10 @@ function version(entry) {
18
18
  async function download(url, timeout) {
19
19
  try {
20
20
  const response = await fetch(url, { redirect: 'follow', signal: AbortSignal.timeout(timeout) });
21
- if (!response.ok) return { error: `could not download ${url}: HTTP ${response.status}` };
21
+ if (!response.ok) {
22
+ await response.body?.cancel().catch(() => {});
23
+ return { error: `could not download ${url}: HTTP ${response.status}` };
24
+ }
22
25
  return { text: await response.text() };
23
26
  } catch (error) {
24
27
  if (error.name === 'TimeoutError') return { error: 'download timed out' };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-capture",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "screencapture for SLICC, and sccapture for SLICC and any host",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -62,8 +62,8 @@
62
62
  "release": "semantic-release"
63
63
  },
64
64
  "devDependencies": {
65
- "@ai-ecoverse/slicc-cdp": "1.41.0",
66
- "@ai-ecoverse/slicc-kernel": "1.156.0",
65
+ "@ai-ecoverse/slicc-cdp": "1.41.1",
66
+ "@ai-ecoverse/slicc-kernel": "1.157.1",
67
67
  "@ai-ecoverse/slicc-shared-web": "2.12.0",
68
68
  "@ai-ecoverse/wasm-bash": "5.3.0-23",
69
69
  "@ai-ecoverse/wasm-coreutils": "9.12.0-15",