@ai-ecoverse/slicc-capture 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,7 +76,7 @@ Short options may be grouped (`-xc`), an option's value may be attached or separ
76
76
 
77
77
  - **The file:** written as PNG, JPEG or WebP: `-t` decides, else the file's extension (`.png`, `.jpg` or `.jpeg`, `.webp`), else PNG. JPEG and WebP use quality 0.92. On success it prints `captured <n> KB to <file>`.
78
78
  - **`-c`:** captures a PNG and copies it to the clipboard as `image/png`, with a `clipboard.write` request on `/dev/embedder`, which seven's embedder (slicc-bios) answers; [slicc-clipboard](https://github.com/ai-ecoverse/slicc-clipboard)'s `/dev/clipboard` stays text only. It prints `captured <n> KB to clipboard`. A file named with `-c` is ignored, as with macOS's `-c`, and so is `-t`. The `clipboard.write` request is sent before the prompt, so a page that doesn't answer it fails at once, without a capture.
79
- - **`-v`:** shows the capture inline in the agent's tool result, by printing one line `<img:<absolute path>>` on stdout, the marker agreed in [ai-ecoverse/slicc-agent#713](https://github.com/ai-ecoverse/slicc-agent/issues/713): the agent reads that file, detects PNG, JPEG, GIF or WebP by its magic bytes, fits the image to 1600 px wide and 1 MB of base64, and replaces the line with `<path> (<mime>, <bytes> bytes)` and the image in the tool result (at most 4 per command). With a file, `-v` writes it and prints only the marker for it; without one, it writes the capture to a new `${TMPDIR:-/tmp}/screencapture-XXXXXX.<type>`, which it leaves there for the agent, and prints the marker for that; with `-c`, it copies, prints `captured <n> KB to clipboard`, and then the marker of such a file. slicc 6's `<img:data:<type>;base64,<data>>` is gone: base64 on stdout is scrubbed and cut by the output tail. The agent's side of #713 isn't shipped yet; until it is, the marker shows as the line itself. macOS's `-v` (record a video) is out of scope everywhere.
79
+ - **`-v`:** shows the capture inline in the agent's tool result, by printing one line `<img:<absolute path>>` on stdout, the marker of [ai-ecoverse/slicc-agent#713](https://github.com/ai-ecoverse/slicc-agent/issues/713), which needs `@ai-ecoverse/slicc-agent` 7.7.0 or later (see its README's ["Images from command output"](https://github.com/ai-ecoverse/slicc-agent#readme)): the agent reads that file with the caller's own permissions, detects PNG, JPEG, GIF or WebP by its magic bytes, fits the image to 1600 px wide and at most 1 MB of base64, and replaces the line with `<path> (<mime>, <bytes> bytes)` and the image in the tool result, at most 4 images per command. It doesn't honour relative paths, markers on stderr, lines over 4 KB, or markers from runs that a guest started (or that inherited guest or lick taint); each of those gets a one-line note instead of the image. With a file, `-v` writes it and prints only the marker for it; without one, it writes the capture to a new `${TMPDIR:-/tmp}/screencapture-XXXXXX.<type>`, which it leaves there for the agent, and prints the marker for that; with `-c`, it copies, prints `captured <n> KB to clipboard`, and then the marker of such a file. slicc 6's `<img:data:<type>;base64,<data>>` is gone: base64 on stdout is scrubbed and cut by the output tail. With an older agent, the marker shows as the line itself. macOS's `-v` (record a video) is out of scope everywhere.
80
80
  - **No file:** without a file, `-c` or `-v`: `screencapture: output file required (or use -c for clipboard)` and the usage to stderr, exit 2.
81
81
 
82
82
  Errors, on stderr, from slicc 6 where they still apply:
@@ -92,6 +92,8 @@ Errors, on stderr, from slicc 6 where they still apply:
92
92
  | `screencapture: the page sent no image` (an empty reply) | 1 |
93
93
  | `screencapture: interrupted` (`SIGHUP`, `SIGINT` or `SIGTERM` during the request: the command stops the reader, so the page's `signal` aborts with `interrupted`, removes its temporary files and writes no file) | `128 + n` |
94
94
  | `screencapture: failed to write file: <file>: <message>` | 1 |
95
+ | `screencapture: failed to create a temporary directory in <dir>` (before the request: `mktemp -d` failed in `$TMPDIR`, else `/tmp`; nothing is sent or written) | 1 |
96
+ | `screencapture: failed to create a temporary file in <dir>` (`-v` without a file, after the capture: `mktemp` failed; the image is dropped and nothing is written) | 1 |
95
97
  | `screencapture: failed to copy to clipboard: this page does not copy images (no clipboard.write)` (`ENOTSUP`: no page answers `clipboard.write`) | 1 |
96
98
  | `screencapture: failed to copy to clipboard: <message>` (the page's message, else the errno's text) | 1 |
97
99
  | `screencapture: /dev/embedder not available (needs slicc-kernel >= 1.153.0)` (a kernel that runs the commands without the device) | 1 |
@@ -177,7 +179,7 @@ Every option of macOS's `screencapture`, and what it does in SLICC and with `scc
177
179
  | `-T <seconds>` | wait before capturing | waits after the picker | passed | `sccapture` waits, then runs the tool | `sccapture` waits, then captures |
178
180
  | `-u` | show the UI afterwards, file ignored | not supported | passed | not supported | not supported |
179
181
  | `-U` | the interactive toolbar | not supported | passed | not supported | not supported |
180
- | `-v` | record a video | inline in the tool result, as an `<img:<path>>` line ([slicc-agent#713](https://github.com/ai-ecoverse/slicc-agent/issues/713)) | not supported | not supported | not supported |
182
+ | `-v` | record a video | inline in the tool result, as an `<img:<path>>` line ([slicc-agent#713](https://github.com/ai-ecoverse/slicc-agent/issues/713), slicc-agent 7.7.0 or later) | not supported | not supported | not supported |
181
183
  | `-V <seconds>` | record a video for that long | not supported | not supported | not supported | not supported |
182
184
  | `-w` | window selection only | prefers `displaySurface: 'window'` | passed | see [Linux](#linux) | not supported |
183
185
  | `-W` | start in window selection | prefers `displaySurface: 'window'` | passed | as `-w` | not supported |
package/bin/screencapture CHANGED
@@ -268,7 +268,7 @@ request="$request,\"cursor\":\"$cursor\""
268
268
  [ -z "$wait" ] || request="$request,\"delay\":$(num "${wait%%.*}")${wait#"${wait%%.*}"}"
269
269
  [ -z "$area" ] || request="$request,\"rect\":{\"x\":$(num "$rx"),\"y\":$(num "$ry"),\"width\":$(num "$rw"),\"height\":$(num "$rh")}"
270
270
  request="$request}"
271
- work=$(mktemp -d)
271
+ work=$(mktemp -d 2>/dev/null) || die "failed to create a temporary directory in ${TMPDIR:-/tmp}"
272
272
  trap cleanup EXIT
273
273
  trap 'stop 1' HUP
274
274
  trap 'stop 2' INT
@@ -300,7 +300,7 @@ if [ -n "$clip" ]; then
300
300
  fi
301
301
  if [ -z "$file" ]; then
302
302
  [ -n "$view" ] || exit 0
303
- file=$(mktemp "${TMPDIR:-/tmp}/screencapture-XXXXXX.$mime")
303
+ file=$(mktemp "${TMPDIR:-/tmp}/screencapture-XXXXXX.$mime" 2>/dev/null) || die "failed to create a temporary file in ${TMPDIR:-/tmp}"
304
304
  fi
305
305
  err=$(tee -- "$file" <"$work/image" 2>&1 >/dev/null) || die "failed to write file: ${err#tee: }"
306
306
  if [ -n "$view" ]; then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-capture",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "screencapture for SLICC, and sccapture for SLICC and any host",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/page/index.mjs CHANGED
@@ -93,7 +93,17 @@ async function pick(display, constraints, signal, timeout) {
93
93
  async function grab(stream, track, env, signal) {
94
94
  const ImageCapture = env('ImageCapture');
95
95
  if (ImageCapture) {
96
- const bitmap = await race(new ImageCapture(track).grabFrame(), signal);
96
+ const pending = Promise.resolve(new ImageCapture(track).grabFrame());
97
+ let bitmap;
98
+ try {
99
+ bitmap = await race(pending, signal);
100
+ } catch (error) {
101
+ pending.then(
102
+ (late) => late?.close?.(),
103
+ () => {}
104
+ );
105
+ throw error;
106
+ }
97
107
  return {
98
108
  source: bitmap,
99
109
  width: bitmap.width,