arena-bridge 0.6.0 → 0.6.2
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 +12 -0
- package/README.md +3 -1
- package/package.json +5 -5
- package/src/cli.mjs +10 -2
- package/src/direct.mjs +1 -1
- package/src/hub.mjs +1 -1
- package/src/mcp.mjs +1 -1
- package/src/tunnel.mjs +18 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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.2
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- `arena-bridge tunnel --bin ngrok` runs an ngrok tunnel instead of cloudflared; with an
|
|
11
|
+
authtoken and a reserved domain (`--authtoken`, `--domain`) the public URL stays the same
|
|
12
|
+
across restarts, so the agent prompt does not have to be copied again.
|
|
13
|
+
|
|
14
|
+
## 0.6.1
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Repository links point to the new home: github.com/vernikr/arena-bridge.
|
|
18
|
+
|
|
7
19
|
## 0.6.0
|
|
8
20
|
|
|
9
21
|
### Added
|
package/README.md
CHANGED
|
@@ -54,7 +54,9 @@ arena-bridge setup --root ~/projects --root ~/Documents
|
|
|
54
54
|
`setup` печатает готовый промпт и публичный URL. Дальше — просто говорите агенту задачу.
|
|
55
55
|
|
|
56
56
|
Нужен туннель? Поставьте `cloudflared` (`brew install cloudflared` или бинарник в `/usr/local/bin`).
|
|
57
|
-
|
|
57
|
+
Можно и через ngrok — `arena-bridge tunnel --bin ngrok`; с сохранённым токеном и зарезервированным
|
|
58
|
+
доменом публичный адрес остаётся постоянным, и промпт агенту не нужно копировать заново:
|
|
59
|
+
`arena-bridge tunnel --bin ngrok --authtoken <token> --domain <name>.ngrok-free.dev`.
|
|
58
60
|
|
|
59
61
|
### В фоне, чтобы не открывать терминал
|
|
60
62
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arena-bridge",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
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": {
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
|
-
"url": "git+https://github.com/vernikr
|
|
29
|
+
"url": "git+https://github.com/vernikr/arena-bridge.git"
|
|
30
30
|
},
|
|
31
|
-
"homepage": "https://github.com/vernikr
|
|
31
|
+
"homepage": "https://github.com/vernikr/arena-bridge#readme",
|
|
32
32
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/vernikr
|
|
33
|
+
"url": "https://github.com/vernikr/arena-bridge/issues"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"mcp",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"mcp-server",
|
|
48
48
|
"self-hosted"
|
|
49
49
|
],
|
|
50
|
-
"author": "vernikr
|
|
50
|
+
"author": "vernikr",
|
|
51
51
|
"license": "MIT",
|
|
52
52
|
"publishConfig": {
|
|
53
53
|
"access": "public"
|
package/src/cli.mjs
CHANGED
|
@@ -92,7 +92,9 @@ Common options:
|
|
|
92
92
|
--hub URL hub base URL (for "connect" / init --mode hub)
|
|
93
93
|
--public-url URL public base URL the agent should use
|
|
94
94
|
--protocol P tunnel transport: http2 (default, works on locked-down networks) or quic
|
|
95
|
-
--bin PATH tunnel binary to run (default: cloudflared)
|
|
95
|
+
--bin PATH tunnel binary to run (default: cloudflared; "ngrok" is supported too)
|
|
96
|
+
--authtoken TOKEN ngrok authtoken (keeps the same URL on every restart)
|
|
97
|
+
--domain NAME ngrok reserved domain, e.g. my-machine.ngrok-free.app
|
|
96
98
|
--no-approval disable the human approval gate (dangerous)
|
|
97
99
|
--no-shell disable shell execution entirely
|
|
98
100
|
|
|
@@ -197,7 +199,13 @@ async function cmdTunnel(args) {
|
|
|
197
199
|
}
|
|
198
200
|
|
|
199
201
|
console.log(`starting ${bin} (protocol=${protocol})…`);
|
|
200
|
-
const { child, urlPromise } = startTunnel(cfg, {
|
|
202
|
+
const { child, urlPromise } = startTunnel(cfg, {
|
|
203
|
+
port,
|
|
204
|
+
protocol,
|
|
205
|
+
bin,
|
|
206
|
+
authtoken: args.flags.authtoken,
|
|
207
|
+
domain: args.flags.domain,
|
|
208
|
+
});
|
|
201
209
|
|
|
202
210
|
let publicUrl;
|
|
203
211
|
try {
|
package/src/direct.mjs
CHANGED
package/src/hub.mjs
CHANGED
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.
|
|
51
|
+
serverInfo: { name: 'arena-bridge', version: '0.6.2' },
|
|
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.',
|
package/src/tunnel.mjs
CHANGED
|
@@ -2,15 +2,27 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import net from 'node:net';
|
|
3
3
|
|
|
4
4
|
const URL_RE = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/i;
|
|
5
|
+
const NGROK_URL_RE = /https:\/\/[a-z0-9-]+\.ngrok(?:-free)?\.(?:app|io|dev)/i;
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* Starts a
|
|
8
|
-
* QUIC (UDP/7844) is blocked on many
|
|
9
|
-
*
|
|
8
|
+
* Starts a tunnel and resolves with the public URL it prints.
|
|
9
|
+
* cloudflared: QUIC (UDP/7844) is blocked on many networks, so we default to http2 over TCP/443.
|
|
10
|
+
* ngrok: an authtoken and an optional reserved domain give the same URL on every restart.
|
|
10
11
|
*/
|
|
11
|
-
export function startTunnel(cfg, { port, protocol = 'http2', bin = 'cloudflared' } = {}) {
|
|
12
|
+
export function startTunnel(cfg, { port, protocol = 'http2', bin = 'cloudflared', authtoken, domain } = {}) {
|
|
12
13
|
const target = `http://127.0.0.1:${port}`;
|
|
13
|
-
const
|
|
14
|
+
const isNgrok = /ngrok/i.test(bin);
|
|
15
|
+
const args = isNgrok
|
|
16
|
+
? [
|
|
17
|
+
'http',
|
|
18
|
+
target,
|
|
19
|
+
...(authtoken ? ['--authtoken', String(authtoken)] : []),
|
|
20
|
+
...(domain ? ['--domain', String(domain)] : []),
|
|
21
|
+
'--log',
|
|
22
|
+
'stdout',
|
|
23
|
+
]
|
|
24
|
+
: ['tunnel', '--url', target, '--protocol', protocol];
|
|
25
|
+
const urlPattern = isNgrok ? NGROK_URL_RE : URL_RE;
|
|
14
26
|
|
|
15
27
|
const child = spawn(bin, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
16
28
|
|
|
@@ -27,7 +39,7 @@ export function startTunnel(cfg, { port, protocol = 'http2', bin = 'cloudflared'
|
|
|
27
39
|
const onChunk = (chunk) => {
|
|
28
40
|
const text = chunk.toString();
|
|
29
41
|
buffer += text;
|
|
30
|
-
const match =
|
|
42
|
+
const match = urlPattern.exec(buffer);
|
|
31
43
|
if (match && !settled) {
|
|
32
44
|
settled = true;
|
|
33
45
|
resolveUrl(match[0]);
|