@remcp/runtime 0.2.80 → 0.2.81
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/extended/catalog.mjs +2 -2
- package/src/extended/diagnostics.mjs +22 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.2.81 — 2026-09-21
|
|
6
|
+
|
|
7
|
+
- `record_screen` is advertised only when the current OS/session has a recorder backend the runtime can actually invoke.
|
|
8
|
+
- macOS/Windows require `ffmpeg`; Linux Wayland requires `wf-recorder + timeout`; Linux X11 requires `ffmpeg`.
|
|
9
|
+
- Availability errors are platform-specific, and regression coverage locks the capability matrix.
|
|
10
|
+
- Lockstep patch release with the ReMCP client/server at `0.2.81`.
|
|
11
|
+
|
|
5
12
|
## 0.2.80 — 2026-09-21
|
|
6
13
|
|
|
7
14
|
- Wayland `type_text` can replace text in an inactive explicitly targeted native window without compositor focus when exactly one editable accessibility control is present.
|
package/package.json
CHANGED
package/src/extended/catalog.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { isWaylandSession } from '../screenshot-portal.mjs';
|
|
|
9
9
|
import { waylandPortalCandidate } from '../wayland-remote-desktop.mjs';
|
|
10
10
|
import { commandExists, runFile } from './common.mjs';
|
|
11
11
|
import { desktopHandlers } from './desktop.mjs';
|
|
12
|
-
import { diagnosticHandlers } from './diagnostics.mjs';
|
|
12
|
+
import { diagnosticHandlers, recordScreenAvailable } from './diagnostics.mjs';
|
|
13
13
|
import { documentHandlers } from './documents.mjs';
|
|
14
14
|
|
|
15
15
|
const readOnly = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
@@ -623,7 +623,7 @@ export async function capabilitySnapshot() {
|
|
|
623
623
|
apps: win || mac || commandExists('dpkg-query') || commandExists('rpm'),
|
|
624
624
|
audio: win || mac || commandExists('wpctl') || commandExists('pactl') || commandExists('amixer'),
|
|
625
625
|
power: win || mac || commandExists('systemctl') || commandExists('loginctl'),
|
|
626
|
-
record:
|
|
626
|
+
record: recordScreenAvailable({ platform:process.platform, wayland }),
|
|
627
627
|
ooxml: win || (commandExists('zip') && commandExists('unzip')),
|
|
628
628
|
};
|
|
629
629
|
}
|
|
@@ -5,6 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import process from 'node:process';
|
|
6
6
|
import { stat } from 'node:fs/promises';
|
|
7
7
|
import { assertAllowedCommand } from '../policy.mjs';
|
|
8
|
+
import { isWaylandSession } from '../screenshot-portal.mjs';
|
|
8
9
|
import { resolveSafePath, text } from '../util.mjs';
|
|
9
10
|
import {
|
|
10
11
|
clamp,
|
|
@@ -243,6 +244,19 @@ export async function powerAction(args) {
|
|
|
243
244
|
return text(`${policy.note ? `${policy.note}\n` : ''}Power action ${action} requested.`);
|
|
244
245
|
}
|
|
245
246
|
|
|
247
|
+
export function recordScreenAvailable({
|
|
248
|
+
platform = process.platform,
|
|
249
|
+
wayland = platform === 'linux' ? isWaylandSession() : false,
|
|
250
|
+
commandExistsFn = commandExists,
|
|
251
|
+
} = {}) {
|
|
252
|
+
if (platform === 'linux') {
|
|
253
|
+
if (wayland) return commandExistsFn('wf-recorder') && commandExistsFn('timeout');
|
|
254
|
+
return commandExistsFn('ffmpeg');
|
|
255
|
+
}
|
|
256
|
+
if (platform === 'darwin' || platform === 'win32') return commandExistsFn('ffmpeg');
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
|
|
246
260
|
export async function recordScreen(args) {
|
|
247
261
|
const seconds = clamp(args.duration_seconds, 5, 1, 120);
|
|
248
262
|
const fps = clamp(args.fps, 15, 1, 60);
|
|
@@ -251,7 +265,14 @@ export async function recordScreen(args) {
|
|
|
251
265
|
const result = await runFile('timeout', ['--signal=INT', `${seconds}s`, 'wf-recorder', '-f',destination,'-r',String(fps),'-c','libx264'], { label:'screen recording', timeout:(seconds+10)*1000, allowFailure:true });
|
|
252
266
|
if (![0, 124, 130].includes(Number(result.code))) throw new Error(result.stderr.trim() || `wf-recorder exited ${result.code}`);
|
|
253
267
|
} else {
|
|
254
|
-
if (
|
|
268
|
+
if (process.platform === 'linux' && isWaylandSession()) {
|
|
269
|
+
unavailable('Screen recording', 'wf-recorder and timeout are required on Wayland');
|
|
270
|
+
}
|
|
271
|
+
if (!commandExists('ffmpeg')) {
|
|
272
|
+
if (process.platform === 'darwin') unavailable('Screen recording', 'ffmpeg is required on macOS');
|
|
273
|
+
if (process.platform === 'win32') unavailable('Screen recording', 'ffmpeg is required on Windows');
|
|
274
|
+
unavailable('Screen recording', 'ffmpeg is required on X11');
|
|
275
|
+
}
|
|
255
276
|
let argv;
|
|
256
277
|
if (process.platform === 'win32') argv=['-y','-f','gdigrab','-framerate',String(fps),'-i','desktop','-t',String(seconds),'-pix_fmt','yuv420p',destination];
|
|
257
278
|
else if (process.platform === 'darwin') argv=['-y','-f','avfoundation','-framerate',String(fps),'-i','1:none','-t',String(seconds),'-pix_fmt','yuv420p',destination];
|