@remcp/runtime 0.2.137 → 0.2.139

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.139 — 2026-10-02
4
+
5
+ - `create_archive` and `extract_archive` are now advertised on macOS in addition to Linux.
6
+ - The tar verbose-output parser accepts native bsdtar month/day/time rows that omit the year for current-year entries, while retaining the existing archive expanded-size safety checks.
7
+ - Public macOS release validation performs a real archive create/extract round trip. Windows archive tools remain intentionally hidden until a separately validated backend exists.
8
+ - Tool names and MCP schemas are unchanged; macOS parity rises from 81 to 83 advertised tools on a fully capable host.
9
+
10
+ ## 0.2.138 — 2026-10-02
11
+
12
+ - `browser_tabs`, `browser_snapshot`, `browser_find`, and `browser_wait` now set `openWorldHint=true` while retaining `readOnlyHint=true` and `idempotentHint=true`.
13
+ - This matches MCP 2026-07-28 ToolAnnotations semantics: browser inspection can observe an open world of external web entities even when it does not mutate them.
14
+ - The hosted compact browser lane was already open-world because it also contains navigation/action/evaluation operations. The 83 runtime tool names and schemas are unchanged; the annotation digest changes intentionally.
15
+
3
16
  ## 0.2.137 — 2026-10-02
4
17
 
5
18
  - `environment.outputSchema` now matches the real stable runtime payload: `platform`, `arch`, `node`, `cwd`, `home`, `temp`, nullable `shell`, `path_entries[]`, and opt-in sanitized `environment`.
package/README.md CHANGED
@@ -40,7 +40,7 @@ support and emits `notifications/tools/list_changed` when that capability set ch
40
40
  | --- | --- |
41
41
  | Read | `read_file`, `read_files`, `read_multiple_files`, `read_image`, `read_binary`, `list_directory`, `get_file_info`, `hash_file`, `diff_files` |
42
42
  | Write / edit | `write_file`, `write_files`, `write_binary`, `apply_patch`, `set_permissions`, `edit_block`, `replace_lines`, `replace_in_files` |
43
- | Organise | `create_directory`, `move_file`, `copy_file`, `copy_paths`, `move_paths`, `move_to_trash`, `create_archive`, `extract_archive` |
43
+ | Organise | `create_directory`, `move_file`, `copy_file`, `copy_paths`, `move_paths`, `move_to_trash`, `create_archive`, `extract_archive` (Linux/macOS; tar/zip backends are validated before use) |
44
44
  | Delete | `delete_path`, `delete_paths` |
45
45
  | Transfer | `read_binary` / `write_binary` stream any file as base64 chunks in both directions; `create_archive` / `extract_archive` move whole trees |
46
46
  | Screen | `take_screenshot` returns the desktop as an image on Linux, macOS, and Windows |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remcp/runtime",
3
- "version": "0.2.137",
3
+ "version": "0.2.139",
4
4
  "description": "First-party ReMCP local device runtime: filesystem, terminal, computer-use, browser, diagnostics and document tools over MCP.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/catalog.mjs CHANGED
@@ -830,8 +830,8 @@ export const toolDefinitions = [
830
830
  },
831
831
  ];
832
832
 
833
- export function coreToolSupported(definition) {
834
- return !['create_archive', 'extract_archive'].includes(definition.name) || process.platform === 'linux';
833
+ export function coreToolSupported(definition, { platform = process.platform } = {}) {
834
+ return !['create_archive', 'extract_archive'].includes(definition.name) || ['linux', 'darwin'].includes(platform);
835
835
  }
836
836
 
837
837
  export function supportedCoreTools() {
@@ -664,12 +664,12 @@ export const extendedToolDefinitions = [
664
664
  define('reveal_path', 'Reveal path', 'Reveal a permitted local file or directory in Finder, Explorer, or the Linux file manager after applying ReMCP filesystem confinement.', o({ path:s('File or directory to reveal.') }, ['path']), additive, desktopHandlers.reveal_path, ['desktop_open']),
665
665
  define('notification', 'Desktop notification', 'Show a native desktop notification or user-visible popup on the paired computer.', o({ title:s(), message:s('Notification message.'), timeout_seconds:n() }, ['message']), additive, desktopHandlers.notification, ['notifications']),
666
666
 
667
- define('browser_tabs', 'Browser tabs', 'List debuggable Chrome, Edge, or Chromium page targets from a loopback-only Chrome DevTools Protocol endpoint.', o({ ...browserTarget }), readOnlyLive, browserHandlers.browser_tabs, ['browser_cdp']),
667
+ define('browser_tabs', 'Browser tabs', 'List debuggable Chrome, Edge, or Chromium page targets from a loopback-only Chrome DevTools Protocol endpoint.', o({ ...browserTarget }), readOnlyOpen, browserHandlers.browser_tabs, ['browser_cdp']),
668
668
  define('browser_navigate', 'Browser navigate', 'Open a new debuggable tab or navigate a selected browser page by URL, history back/forward, or reload through Chrome DevTools Protocol.', o({ ...browserTarget, action:e(['url','new_tab','back','forward','reload'], 'Default url when url is provided, otherwise reload. new_tab creates the first page target when needed.'), url:s('Destination URL for action=url or action=new_tab.'), wait:b('Wait for the page load event; default true.'), ignore_cache:b('Reload without cache when action=reload.') }), openMutatingNonDestructive, browserHandlers.browser_navigate, ['browser_cdp']),
669
- define('browser_snapshot', 'Browser snapshot', 'Return the selected browser page accessibility tree through Chrome DevTools Protocol and, when requested, attach a real rendered viewport PNG for visual verification. A selector is temporarily recentered for capture, its exact viewport bounds are returned, and the prior scroll position is restored before return.', o({ ...browserTarget, max_nodes:n('Maximum AX nodes; default 1500.'), include_screenshot:b('Attach a real CDP-rendered viewport PNG screenshot; default false.'), selector:s('When include_screenshot=true, center this CSS-selected element before capture and report its viewport bounds.') }), readOnlyLive, browserHandlers.browser_snapshot, ['browser_cdp']),
670
- define('browser_find', 'Find browser element', 'Find visible DOM elements by CSS selector, text, or ARIA role and return reusable selectors plus text, value, and bounding boxes.', o({ ...browserTarget, selector:s('CSS selector.'), text:s('Visible text substring.'), role:s('ARIA role.'), limit:n() }), readOnlyLive, browserHandlers.browser_find, ['browser_cdp']),
669
+ define('browser_snapshot', 'Browser snapshot', 'Return the selected browser page accessibility tree through Chrome DevTools Protocol and, when requested, attach a real rendered viewport PNG for visual verification. A selector is temporarily recentered for capture, its exact viewport bounds are returned, and the prior scroll position is restored before return.', o({ ...browserTarget, max_nodes:n('Maximum AX nodes; default 1500.'), include_screenshot:b('Attach a real CDP-rendered viewport PNG screenshot; default false.'), selector:s('When include_screenshot=true, center this CSS-selected element before capture and report its viewport bounds.') }), readOnlyOpen, browserHandlers.browser_snapshot, ['browser_cdp']),
670
+ define('browser_find', 'Find browser element', 'Find visible DOM elements by CSS selector, text, or ARIA role and return reusable selectors plus text, value, and bounding boxes.', o({ ...browserTarget, selector:s('CSS selector.'), text:s('Visible text substring.'), role:s('ARIA role.'), limit:n() }), readOnlyOpen, browserHandlers.browser_find, ['browser_cdp']),
671
671
  define('browser_action', 'Browser element action', 'Click, focus, type/set a value, select, scroll a page or scrollable element, scroll an element into view, upload files, press a key, or set an exact responsive-test viewport in a debuggable browser page using DOM/CDP semantics.', o({ ...browserTarget, action:e(['click','focus','type','set_value','select','scroll','scroll_into_view','upload','press','set_viewport']), selector:s('CSS selector for the target element; prefer the reusable selector returned by browser_find.'), browser_text:s('Visible text used only to locate a DOM element; use this instead of overloading text for action=type.'), text:s('For action=type, Unicode text to insert. For non-type element actions without selector/browser_text, visible text may identify the target.'), clear:b('For action=type, clear the current value before inserting text.'), value:s('Value for action=set_value; also accepted as a legacy type payload when text is used as the locator.'), text_value:s('Compatibility alias for the type/set_value text value.'), option:s(), delta_x:n('Horizontal scroll delta; positive means right.'), delta_y:n('Vertical scroll delta; positive means down.'), delta:n('Alias for delta_y.'), direction:e(['up','down','left','right']), wheel_times:n('Number of 120-unit wheel steps for direction; 1..50.'), path:s(), paths:{type:'array',items:{type:'string'}}, key:s(), width:n('CSS viewport width for set_viewport.'), height:n('CSS viewport height for set_viewport.'), device_scale_factor:n('Device scale factor for set_viewport; default 1.'), mobile:b('Enable mobile emulation for set_viewport.') }, ['action']), openMutating, browserHandlers.browser_action, ['browser_cdp']),
672
- define('browser_wait', 'Wait for browser', 'Wait for DOM state, page text, URL, completed loading, a navigation away from the current URL, or a short network-idle period in a debuggable browser page. Use browser_evaluate separately for JavaScript predicates or page-specific inspection.', o({ ...browserTarget, condition:e(['selector','text','url_contains','load','navigation','network_idle']), selector:s(), text:s(), value:s(), poll_ms:n(), idle_ms:n('Required zero-in-flight network quiet window for network_idle; default 500 ms.') }), readOnlyLive, browserHandlers.browser_wait, ['browser_cdp']),
672
+ define('browser_wait', 'Wait for browser', 'Wait for DOM state, page text, URL, completed loading, a navigation away from the current URL, or a short network-idle period in a debuggable browser page. Use browser_evaluate separately for JavaScript predicates or page-specific inspection.', o({ ...browserTarget, condition:e(['selector','text','url_contains','load','navigation','network_idle']), selector:s(), text:s(), value:s(), poll_ms:n(), idle_ms:n('Required zero-in-flight network quiet window for network_idle; default 500 ms.') }), readOnlyOpen, browserHandlers.browser_wait, ['browser_cdp']),
673
673
  define('browser_evaluate', 'Evaluate browser JavaScript', 'Evaluate JavaScript in a selected debuggable browser page and return its serializable value. This is a powerful escape hatch for page-specific automation.', o({ ...browserTarget, expression:s('JavaScript expression.'), await_promise:b('Await a returned Promise; default true.') }, ['expression']), openMutating, browserHandlers.browser_evaluate, ['browser_evaluate']),
674
674
 
675
675
  define('service', 'Service control', 'List, inspect, start, stop, or restart operating-system services using Service Control Manager, launchctl, or systemd. Mutating actions pass through ReMCP command policy.', o({ action:e(['list','status','start','stop','restart']), name:s('Service/unit/launchd label.'), scope:e(['user','system']) }, ['action']), mutating, diagnosticHandlers.service, ['services']),
@@ -1449,17 +1449,16 @@ function archiveExpandedSize(lines, pattern, label, expectedEntries = null) {
1449
1449
  return total;
1450
1450
  }
1451
1451
 
1452
- function tarEntrySize(line) {
1452
+ export function tarEntrySize(line) {
1453
1453
  const tokens = String(line || '').trim().split(/\s+/);
1454
1454
  for (const index of [2, 3, 4]) {
1455
1455
  const size = Number(tokens[index]);
1456
1456
  if (!Number.isSafeInteger(size) || size < 0) continue;
1457
1457
  const tail = tokens.slice(index + 1);
1458
1458
  const gnuDate = /^\d{4}-\d{2}-\d{2}$/.test(tail[0] || '');
1459
- const bsdDate = /^[A-Z][a-z]{2}$/.test(tail[0] || '')
1460
- && /^\d{1,2}$/.test(tail[1] || '')
1461
- && ((/^\d{2}:\d{2}(?::\d{2})?$/.test(tail[2] || '') && /^\d{4}$/.test(tail[3] || ''))
1462
- || /^\d{4}$/.test(tail[2] || ''));
1459
+ const bsdMonthDay = /^[A-Z][a-z]{2}$/.test(tail[0] || '') && /^\d{1,2}$/.test(tail[1] || '');
1460
+ const bsdTime = /^\d{2}:\d{2}(?::\d{2})?$/.test(tail[2] || '');
1461
+ const bsdDate = bsdMonthDay && (bsdTime || /^\d{4}$/.test(tail[2] || ''));
1463
1462
  if (gnuDate || bsdDate) return size;
1464
1463
  }
1465
1464
  return null;