arena-bridge 0.6.8 → 0.6.10

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
@@ -4,6 +4,23 @@ All notable changes to this project are documented here.
4
4
  The format follows [Keep a Changelog](https://keepachangelog.com/) and the project uses
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## 0.6.10
8
+
9
+ ### Fixed
10
+ - The screenshot fallback no longer relies on a Peekaboo command that was removed in v4, so the
11
+ bridge can still grab a picture when the accessibility tree is empty.
12
+ - The permission message now names the exact place to fix it (System Settings → Privacy &
13
+ Security → Screen Recording / Accessibility → "Peekaboo Bridge") and explains that the local
14
+ Peekaboo runtime inherits the grant from whatever starts the bridge.
15
+
16
+ ## 0.6.9
17
+
18
+ ### Fixed
19
+ - Desktop control survives a Peekaboo update: when the Peekaboo Bridge host loses its macOS
20
+ permissions (Screen Recording / Accessibility), the bridge falls back to the local Peekaboo
21
+ runtime and keeps working. If nothing can capture, the tool now says so instead of quietly
22
+ returning an empty element list.
23
+
7
24
  ## 0.6.8
8
25
 
9
26
  ### Added
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  <img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="license">
13
13
  <img src="https://img.shields.io/badge/node-%3E%3D18-green.svg?style=flat-square" alt="node">
14
14
  <img src="https://img.shields.io/badge/dependencies-0-brightgreen.svg?style=flat-square" alt="dependencies">
15
- <img src="https://img.shields.io/badge/tests-120%20passed-brightgreen.svg?style=flat-square" alt="tests">
15
+ <img src="https://img.shields.io/badge/tests-124%20passed-brightgreen.svg?style=flat-square" alt="tests">
16
16
  </p>
17
17
 
18
18
  <p align="center">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arena-bridge",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "description": "Give a cloud AI agent (Arena.ai Agent Mode, Claude, Cursor, ...) controlled access to your own machine over HTTP/MCP: files, shell, Chrome and the macOS desktop, with an approval gate, trust windows and an audit log.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/direct.mjs CHANGED
@@ -30,7 +30,7 @@ export function createDirectServer(cfg, engine) {
30
30
  ok: true,
31
31
  mode: 'direct',
32
32
  device: cfg.device,
33
- version: '0.6.8',
33
+ version: '0.6.10',
34
34
  uptime_sec: Math.round(process.uptime()),
35
35
  });
36
36
  }
package/src/hub.mjs CHANGED
@@ -90,7 +90,7 @@ export function createHubServer(cfg) {
90
90
  return sendJson(res, 200, {
91
91
  ok: true,
92
92
  mode: 'hub',
93
- version: '0.6.8',
93
+ version: '0.6.10',
94
94
  devices: [...devices.keys()],
95
95
  });
96
96
  }
package/src/mac.mjs CHANGED
@@ -193,6 +193,7 @@ export function macTools(cfg = {}) {
193
193
  ['see', '--tree', '--no-screenshot', '--json', ...targetFlags(args)],
194
194
  ['see', '--tree', '--no-screenshot', '--no-remote', '--json', ...targetFlags(args)],
195
195
  ['see', '--tree', '--json', ...targetFlags(args)],
196
+ ['see', '--no-remote', '--tree', '--json', ...targetFlags(args)],
196
197
  ['see', '--json', ...targetFlags(args)],
197
198
  ];
198
199
  }
@@ -200,7 +201,8 @@ export function macTools(cfg = {}) {
200
201
  [...base, '--json', '--path', outPath],
201
202
  [...base, '--path', outPath, '--json'],
202
203
  [...base, '--no-remote', '--json', '--path', outPath],
203
- ['image', '--mode', mode, ...targetFlags(args), '--json', '--path', outPath],
204
+ ['see', '--mode', mode, ...targetFlags(args), '--no-elements', '--json', '--path', outPath],
205
+ ['see', '--mode', mode, ...targetFlags(args), '--no-elements', '--no-remote', '--json', '--path', outPath],
204
206
  ];
205
207
  };
206
208
 
@@ -213,7 +215,8 @@ export function macTools(cfg = {}) {
213
215
  if (!best) best = cand;
214
216
  if (res.exit_code === 0 && cand.elements.length) return cand;
215
217
  if (res.exit_code === 0 && best.res.exit_code !== 0) best = cand;
216
- if (res.exit_code !== 0 && !UNKNOWN.test(res.stderr || '')) break;
218
+ const denied = isPermissionError(json, res);
219
+ if (res.exit_code !== 0 && !denied && !UNKNOWN.test(res.stderr || '')) break;
217
220
  }
218
221
  return best;
219
222
  };
@@ -259,6 +262,15 @@ export function macTools(cfg = {}) {
259
262
  if (!outPath.ok) return { ok: false, error: outPath.error, reason: outPath.reason };
260
263
  ensureDir(path.dirname(outPath.abs));
261
264
  const seen = await collectSee(args, outPath.abs);
265
+ const failure = peekError(seen.json);
266
+ if (failure && !seen.elements.length) {
267
+ return {
268
+ ok: false,
269
+ error: 'peekaboo_failed',
270
+ reason: failure.message || String(failure.code || 'peekaboo returned an error'),
271
+ hint: PERMISSION_HINT,
272
+ };
273
+ }
262
274
  const elements = seen.elements.slice(0, 300);
263
275
  const saved = fs.existsSync(outPath.abs);
264
276
  if (!saved) {
@@ -867,6 +879,26 @@ export function macTools(cfg = {}) {
867
879
  ];
868
880
  }
869
881
 
882
+ /** The Peekaboo envelope reports a host that lost its macOS permissions. */
883
+ function peekError(json) {
884
+ if (!json || typeof json !== 'object') return null;
885
+ const err = json.error;
886
+ if (err && typeof err === 'object' && (err.code || err.message)) return err;
887
+ return null;
888
+ }
889
+
890
+ function isPermissionError(json, res) {
891
+ const err = peekError(json);
892
+ const text = `${err?.code || ''} ${err?.message || ''} ${res?.stderr || ''}`;
893
+ return /permission|screen recording|accessibility|event synthesizing/i.test(text);
894
+ }
895
+
896
+ const PERMISSION_HINT =
897
+ 'macOS did not let the bridge capture the screen. This usually happens right after a Peekaboo update: ' +
898
+ 'open System Settings → Privacy & Security → Screen Recording (and Accessibility), turn on ' +
899
+ '"Peekaboo Bridge" and quit and reopen Peekaboo. The bridge also falls back to the local Peekaboo ' +
900
+ 'runtime, which needs the same grant for the app that starts the bridge (for example Terminal).';
901
+
870
902
  function menuFlags(args) {
871
903
  const f = [];
872
904
  if (args.app) f.push('--app', String(args.app));
package/src/mcp.mjs CHANGED
@@ -48,7 +48,7 @@ export async function handleMcp(req, res, ctx) {
48
48
  mcpResponse(id, {
49
49
  protocolVersion: PROTOCOL_VERSION,
50
50
  capabilities: { tools: { listChanged: false } },
51
- serverInfo: { name: 'arena-bridge', version: '0.6.8' },
51
+ serverInfo: { name: 'arena-bridge', version: '0.6.10' },
52
52
  instructions:
53
53
  'Tools operate the user\'s own machine. Dangerous operations may return ' +
54
54
  'PROTECTED and require a local human approval.',