arena-bridge 0.6.8 → 0.6.9

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,14 @@ 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.9
8
+
9
+ ### Fixed
10
+ - Desktop control survives a Peekaboo update: when the Peekaboo Bridge host loses its macOS
11
+ permissions (Screen Recording / Accessibility), the bridge falls back to the local Peekaboo
12
+ runtime and keeps working. If nothing can capture, the tool now says so instead of quietly
13
+ returning an empty element list.
14
+
7
15
  ## 0.6.8
8
16
 
9
17
  ### 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.9",
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.9',
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.9',
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
  }
@@ -213,7 +214,8 @@ export function macTools(cfg = {}) {
213
214
  if (!best) best = cand;
214
215
  if (res.exit_code === 0 && cand.elements.length) return cand;
215
216
  if (res.exit_code === 0 && best.res.exit_code !== 0) best = cand;
216
- if (res.exit_code !== 0 && !UNKNOWN.test(res.stderr || '')) break;
217
+ const denied = isPermissionError(json, res);
218
+ if (res.exit_code !== 0 && !denied && !UNKNOWN.test(res.stderr || '')) break;
217
219
  }
218
220
  return best;
219
221
  };
@@ -259,6 +261,15 @@ export function macTools(cfg = {}) {
259
261
  if (!outPath.ok) return { ok: false, error: outPath.error, reason: outPath.reason };
260
262
  ensureDir(path.dirname(outPath.abs));
261
263
  const seen = await collectSee(args, outPath.abs);
264
+ const failure = peekError(seen.json);
265
+ if (failure && !seen.elements.length) {
266
+ return {
267
+ ok: false,
268
+ error: 'peekaboo_failed',
269
+ reason: failure.message || String(failure.code || 'peekaboo returned an error'),
270
+ hint: PERMISSION_HINT,
271
+ };
272
+ }
262
273
  const elements = seen.elements.slice(0, 300);
263
274
  const saved = fs.existsSync(outPath.abs);
264
275
  if (!saved) {
@@ -867,6 +878,25 @@ export function macTools(cfg = {}) {
867
878
  ];
868
879
  }
869
880
 
881
+ /** The Peekaboo envelope reports a host that lost its macOS permissions. */
882
+ function peekError(json) {
883
+ if (!json || typeof json !== 'object') return null;
884
+ const err = json.error;
885
+ if (err && typeof err === 'object' && (err.code || err.message)) return err;
886
+ return null;
887
+ }
888
+
889
+ function isPermissionError(json, res) {
890
+ const err = peekError(json);
891
+ const text = `${err?.code || ''} ${err?.message || ''} ${res?.stderr || ''}`;
892
+ return /permission|screen recording|accessibility|event synthesizing/i.test(text);
893
+ }
894
+
895
+ const PERMISSION_HINT =
896
+ 'The Peekaboo host that captures the screen lost its macOS permissions (this happens after a Peekaboo update). ' +
897
+ 'Re-grant Screen Recording and Accessibility to "Peekaboo Bridge" in System Settings → Privacy & Security, ' +
898
+ 'or let the bridge use the local runtime (--no-remote). Run mac_permissions for the current state.';
899
+
870
900
  function menuFlags(args) {
871
901
  const f = [];
872
902
  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.9' },
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.',