remotelink 0.2.0 → 0.3.0
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/dist/index.js +29 -14
- package/dist/index.js.map +1 -1
- package/package.json +32 -31
package/dist/index.js
CHANGED
|
@@ -9,10 +9,11 @@ import process from "process";
|
|
|
9
9
|
import { Client } from "@modelcontextprotocol/client";
|
|
10
10
|
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
|
11
11
|
import WebSocket from "ws";
|
|
12
|
-
var VERSION = "0.
|
|
12
|
+
var VERSION = "0.3.0";
|
|
13
13
|
var DEFAULT_ORIGIN = "https://remote.samyao.me";
|
|
14
|
-
var CONFIG_DIR = path.join(os.homedir(), ".
|
|
14
|
+
var CONFIG_DIR = path.join(os.homedir(), ".remotearc");
|
|
15
15
|
var CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
|
|
16
|
+
var LEGACY_CONFIG_PATH = path.join(os.homedir(), ".remote-link", "config.json");
|
|
16
17
|
var SAFE_TOOLS = /* @__PURE__ */ new Set([
|
|
17
18
|
"list_directory",
|
|
18
19
|
"read_file",
|
|
@@ -37,7 +38,18 @@ async function readConfig() {
|
|
|
37
38
|
try {
|
|
38
39
|
return JSON.parse(await fs.readFile(CONFIG_PATH, "utf8"));
|
|
39
40
|
} catch {
|
|
40
|
-
|
|
41
|
+
try {
|
|
42
|
+
const legacy = JSON.parse(
|
|
43
|
+
await fs.readFile(LEGACY_CONFIG_PATH, "utf8")
|
|
44
|
+
);
|
|
45
|
+
await writeConfig(legacy);
|
|
46
|
+
process.stdout.write(
|
|
47
|
+
"Migrated existing Remote Link pairing to Remote Arc.\n"
|
|
48
|
+
);
|
|
49
|
+
return legacy;
|
|
50
|
+
} catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
41
53
|
}
|
|
42
54
|
}
|
|
43
55
|
async function writeConfig(config) {
|
|
@@ -47,8 +59,11 @@ async function writeConfig(config) {
|
|
|
47
59
|
});
|
|
48
60
|
}
|
|
49
61
|
async function resetConfig() {
|
|
50
|
-
await
|
|
51
|
-
|
|
62
|
+
await Promise.all([
|
|
63
|
+
fs.rm(CONFIG_PATH, { force: true }),
|
|
64
|
+
fs.rm(LEGACY_CONFIG_PATH, { force: true })
|
|
65
|
+
]);
|
|
66
|
+
process.stdout.write("Remote Arc device credentials removed.\n");
|
|
52
67
|
}
|
|
53
68
|
function openBrowser(url) {
|
|
54
69
|
const command = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
@@ -75,7 +90,7 @@ async function pair(origin, mode) {
|
|
|
75
90
|
throw new Error("Could not start device pairing: " + response.status);
|
|
76
91
|
}
|
|
77
92
|
const pairing = await response.json();
|
|
78
|
-
process.stdout.write("\nRemote
|
|
93
|
+
process.stdout.write("\nRemote Arc\n\n");
|
|
79
94
|
process.stdout.write("Pair this computer in your browser.\n\n");
|
|
80
95
|
process.stdout.write(" " + pairing.user_code + "\n\n");
|
|
81
96
|
process.stdout.write(pairing.verification_uri_complete + "\n\n");
|
|
@@ -112,7 +127,7 @@ async function pair(origin, mode) {
|
|
|
112
127
|
await writeConfig(config);
|
|
113
128
|
return config;
|
|
114
129
|
}
|
|
115
|
-
throw new Error("Pairing expired. Run Remote
|
|
130
|
+
throw new Error("Pairing expired. Run Remote Arc again to retry.");
|
|
116
131
|
}
|
|
117
132
|
var ExecutionCore = class {
|
|
118
133
|
constructor(mode) {
|
|
@@ -123,7 +138,7 @@ var ExecutionCore = class {
|
|
|
123
138
|
async connect() {
|
|
124
139
|
if (this.client) return this.client;
|
|
125
140
|
const client = new Client({
|
|
126
|
-
name: "
|
|
141
|
+
name: "remotearc-cli-core",
|
|
127
142
|
version: VERSION
|
|
128
143
|
});
|
|
129
144
|
const command = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
@@ -239,7 +254,7 @@ async function connectAgent(config) {
|
|
|
239
254
|
});
|
|
240
255
|
} catch (error) {
|
|
241
256
|
process.stderr.write(
|
|
242
|
-
"Remote
|
|
257
|
+
"Remote Arc connection failed: " + (error instanceof Error ? error.message : String(error)) + "\n"
|
|
243
258
|
);
|
|
244
259
|
} finally {
|
|
245
260
|
ws.removeAllListeners();
|
|
@@ -258,13 +273,13 @@ async function main() {
|
|
|
258
273
|
if (argFlag("--help") || argFlag("-h")) {
|
|
259
274
|
process.stdout.write(
|
|
260
275
|
[
|
|
261
|
-
"Remote
|
|
276
|
+
"Remote Arc",
|
|
262
277
|
"",
|
|
263
278
|
"Usage:",
|
|
264
|
-
" npx
|
|
279
|
+
" npx remotelink",
|
|
265
280
|
"",
|
|
266
281
|
"After the npm release:",
|
|
267
|
-
" npx remotelink
|
|
282
|
+
" npx remotelink",
|
|
268
283
|
"",
|
|
269
284
|
"Options:",
|
|
270
285
|
" --safe Read-only local capability mode",
|
|
@@ -285,7 +300,7 @@ async function main() {
|
|
|
285
300
|
await resetConfig();
|
|
286
301
|
return;
|
|
287
302
|
}
|
|
288
|
-
const origin = process.env.REMOTE_LINK_ORIGIN || process.argv.find((value) => value.startsWith("--origin="))?.slice(9) || DEFAULT_ORIGIN;
|
|
303
|
+
const origin = process.env.REMOTEARC_ORIGIN || process.env.REMOTE_LINK_ORIGIN || process.argv.find((value) => value.startsWith("--origin="))?.slice(9) || DEFAULT_ORIGIN;
|
|
289
304
|
let config = await readConfig();
|
|
290
305
|
if (!config) {
|
|
291
306
|
config = await pair(origin, selectedMode());
|
|
@@ -297,7 +312,7 @@ async function main() {
|
|
|
297
312
|
}
|
|
298
313
|
main().catch((error) => {
|
|
299
314
|
process.stderr.write(
|
|
300
|
-
"\nRemote
|
|
315
|
+
"\nRemote Arc error: " + (error instanceof Error ? error.message : String(error)) + "\n"
|
|
301
316
|
);
|
|
302
317
|
process.exit(1);
|
|
303
318
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\nimport os from \"node:os\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs/promises\";\r\nimport { spawn } from \"node:child_process\";\r\nimport process from \"node:process\";\r\nimport { Client } from \"@modelcontextprotocol/client\";\r\nimport { StdioClientTransport } from \"@modelcontextprotocol/client/stdio\";\r\nimport WebSocket from \"ws\";\r\n\r\nconst VERSION = \"0.2.0\";\r\nconst DEFAULT_ORIGIN = \"https://remote.samyao.me\";\r\nconst CONFIG_DIR = path.join(os.homedir(), \".remote-link\");\r\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\r\n\r\ntype Mode = \"safe\" | \"developer\";\r\n\r\ntype SavedConfig = {\r\n deviceId: string;\r\n deviceToken: string;\r\n deviceName: string;\r\n origin: string;\r\n mode: Mode;\r\n};\r\n\r\ntype PairingStart = {\r\n device_code: string;\r\n device_secret: string;\r\n user_code: string;\r\n verification_uri: string;\r\n verification_uri_complete: string;\r\n expires_in: number;\r\n interval: number;\r\n};\r\n\r\ntype PairingToken = {\r\n device_id: string;\r\n device_token: string;\r\n relay_url: string;\r\n};\r\n\r\nconst SAFE_TOOLS = new Set([\r\n \"list_directory\",\r\n \"read_file\",\r\n \"get_file_info\",\r\n \"list_processes\",\r\n]);\r\n\r\nconst DEVELOPER_TOOLS = new Set([\r\n ...SAFE_TOOLS,\r\n \"start_process\",\r\n \"write_file\",\r\n \"edit_block\",\r\n]);\r\n\r\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\r\n\r\nfunction argFlag(name: string) {\r\n return process.argv.includes(name);\r\n}\r\n\r\nfunction selectedMode(): Mode {\r\n if (argFlag(\"--safe\")) return \"safe\";\r\n return \"developer\";\r\n}\r\n\r\nasync function readConfig(): Promise<SavedConfig | null> {\r\n try {\r\n return JSON.parse(await fs.readFile(CONFIG_PATH, \"utf8\")) as SavedConfig;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nasync function writeConfig(config: SavedConfig) {\r\n await fs.mkdir(CONFIG_DIR, { recursive: true });\r\n await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2) + \"\\n\", {\r\n mode: 0o600,\r\n });\r\n}\r\n\r\nasync function resetConfig() {\r\n await fs.rm(CONFIG_PATH, { force: true });\r\n process.stdout.write(\"Remote Link device credentials removed.\\n\");\r\n}\r\n\r\nfunction openBrowser(url: string) {\r\n const command =\r\n process.platform === \"win32\"\r\n ? \"cmd\"\r\n : process.platform === \"darwin\"\r\n ? \"open\"\r\n : \"xdg-open\";\r\n const args =\r\n process.platform === \"win32\"\r\n ? [\"/c\", \"start\", \"\", url]\r\n : [url];\r\n\r\n const child = spawn(command, args, {\r\n detached: true,\r\n stdio: \"ignore\",\r\n });\r\n child.unref();\r\n}\r\n\r\nasync function pair(origin: string, mode: Mode): Promise<SavedConfig> {\r\n const deviceName = os.hostname();\r\n const response = await fetch(origin + \"/api/device/start\", {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({\r\n device_name: deviceName,\r\n platform: process.platform,\r\n arch: process.arch,\r\n hostname: os.hostname(),\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(\"Could not start device pairing: \" + response.status);\r\n }\r\n\r\n const pairing = (await response.json()) as PairingStart;\r\n\r\n process.stdout.write(\"\\nRemote Link\\n\\n\");\r\n process.stdout.write(\"Pair this computer in your browser.\\n\\n\");\r\n process.stdout.write(\" \" + pairing.user_code + \"\\n\\n\");\r\n process.stdout.write(pairing.verification_uri_complete + \"\\n\\n\");\r\n process.stdout.write(\"Opening browser...\\n\");\r\n openBrowser(pairing.verification_uri_complete);\r\n\r\n const startedAt = Date.now();\r\n while (Date.now() - startedAt < pairing.expires_in * 1000) {\r\n await sleep(Math.max(pairing.interval, 2) * 1000);\r\n\r\n const tokenResponse = await fetch(origin + \"/api/device/token\", {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({\r\n device_code: pairing.device_code,\r\n device_secret: pairing.device_secret,\r\n }),\r\n });\r\n\r\n if (tokenResponse.status === 428) {\r\n process.stdout.write(\".\");\r\n continue;\r\n }\r\n\r\n if (!tokenResponse.ok) {\r\n const body = await tokenResponse.text();\r\n throw new Error(\"Pairing failed: \" + body);\r\n }\r\n\r\n const result = (await tokenResponse.json()) as PairingToken;\r\n process.stdout.write(\"\\n\\n✓ Device authorized\\n\");\r\n\r\n const config: SavedConfig = {\r\n deviceId: result.device_id,\r\n deviceToken: result.device_token,\r\n deviceName,\r\n origin,\r\n mode,\r\n };\r\n await writeConfig(config);\r\n return config;\r\n }\r\n\r\n throw new Error(\"Pairing expired. Run Remote Link again to retry.\");\r\n}\r\n\r\nclass ExecutionCore {\r\n private client: Client | null = null;\r\n\r\n constructor(private readonly mode: Mode) {}\r\n\r\n async connect() {\r\n if (this.client) return this.client;\r\n\r\n const client = new Client({\r\n name: \"remote-link-cli-core\",\r\n version: VERSION,\r\n });\r\n\r\n const command = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\r\n const transport = new StdioClientTransport({\r\n command,\r\n args: [\"-y\", \"@wonderwhy-er/desktop-commander@latest\"],\r\n stderr: \"inherit\",\r\n });\r\n\r\n await client.connect(transport);\r\n this.client = client;\r\n return client;\r\n }\r\n\r\n async tools() {\r\n const list = await (await this.connect()).listTools();\r\n const allowed = this.mode === \"developer\" ? DEVELOPER_TOOLS : SAFE_TOOLS;\r\n return list.tools.filter((tool) => allowed.has(tool.name));\r\n }\r\n\r\n async call(name: string, args: Record<string, unknown>) {\r\n const allowed = this.mode === \"developer\" ? DEVELOPER_TOOLS : SAFE_TOOLS;\r\n if (!allowed.has(name)) {\r\n throw new Error(\"Tool blocked by local permission mode: \" + name);\r\n }\r\n\r\n return (await this.connect()).callTool({\r\n name,\r\n arguments: args,\r\n });\r\n }\r\n\r\n async close() {\r\n if (!this.client) return;\r\n await this.client.close();\r\n this.client = null;\r\n }\r\n}\r\n\r\nasync function connectAgent(config: SavedConfig) {\r\n const core = new ExecutionCore(config.mode);\r\n const tools = await core.tools();\r\n const wsUrl = new URL(\"/agent\", config.origin.replace(/^http/, \"ws\"));\r\n\r\n let stopped = false;\r\n let backoff = 1000;\r\n\r\n const shutdown = async () => {\r\n stopped = true;\r\n await core.close().catch(() => undefined);\r\n process.exit(0);\r\n };\r\n process.on(\"SIGINT\", shutdown);\r\n process.on(\"SIGTERM\", shutdown);\r\n\r\n while (!stopped) {\r\n const ws = new WebSocket(wsUrl, {\r\n headers: {\r\n Authorization: \"Bearer \" + config.deviceToken,\r\n },\r\n });\r\n\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n ws.once(\"open\", resolve);\r\n ws.once(\"error\", reject);\r\n });\r\n\r\n backoff = 1000;\r\n ws.send(\r\n JSON.stringify({\r\n type: \"hello\",\r\n device: {\r\n id: config.deviceId,\r\n name: config.deviceName,\r\n platform: process.platform,\r\n arch: process.arch,\r\n hostname: os.hostname(),\r\n agentVersion: VERSION,\r\n },\r\n tools: tools.map((tool) => tool.name),\r\n }),\r\n );\r\n\r\n process.stdout.write(\r\n \"✓ Connected as \" +\r\n config.deviceName +\r\n \" (\" +\r\n config.mode +\r\n \" mode)\\n\",\r\n );\r\n process.stdout.write(\" \" + config.origin + \"\\n\");\r\n process.stdout.write(\"Press Ctrl+C to disconnect.\\n\");\r\n\r\n await new Promise<void>((resolve) => {\r\n ws.on(\"message\", async (raw) => {\r\n let message: {\r\n type?: string;\r\n id?: string;\r\n tool?: string;\r\n arguments?: Record<string, unknown>;\r\n };\r\n\r\n try {\r\n message = JSON.parse(raw.toString());\r\n } catch {\r\n return;\r\n }\r\n\r\n if (\r\n message.type !== \"call\" ||\r\n !message.id ||\r\n !message.tool\r\n ) {\r\n return;\r\n }\r\n\r\n try {\r\n const result = await core.call(\r\n message.tool,\r\n message.arguments || {},\r\n );\r\n ws.send(\r\n JSON.stringify({\r\n type: \"result\",\r\n id: message.id,\r\n result,\r\n }),\r\n );\r\n } catch (error) {\r\n ws.send(\r\n JSON.stringify({\r\n type: \"result\",\r\n id: message.id,\r\n error: error instanceof Error ? error.message : String(error),\r\n }),\r\n );\r\n }\r\n });\r\n\r\n ws.once(\"close\", resolve);\r\n ws.once(\"error\", resolve);\r\n });\r\n } catch (error) {\r\n process.stderr.write(\r\n \"Remote Link connection failed: \" +\r\n (error instanceof Error ? error.message : String(error)) +\r\n \"\\n\",\r\n );\r\n } finally {\r\n ws.removeAllListeners();\r\n ws.close();\r\n }\r\n\r\n if (!stopped) {\r\n process.stdout.write(\r\n \"Disconnected. Reconnecting in \" + Math.round(backoff / 1000) + \"s...\\n\",\r\n );\r\n await sleep(backoff);\r\n backoff = Math.min(backoff * 2, 30_000);\r\n }\r\n }\r\n}\r\n\r\nasync function main() {\r\n if (argFlag(\"--help\") || argFlag(\"-h\")) {\r\n process.stdout.write(\r\n [\r\n \"Remote Link\",\r\n \"\",\r\n \"Usage:\",\r\n \" npx --yes --package=github:yaohuangguan/remote-link remote-link\",\r\n \"\",\r\n \"After the npm release:\",\r\n \" npx remotelink@latest\",\r\n \"\",\r\n \"Options:\",\r\n \" --safe Read-only local capability mode\",\r\n \" --developer Read/write/shell mode (default)\",\r\n \" --reset Remove this computer's saved pairing\",\r\n \" --version Print CLI version\",\r\n \" --help Show this help\",\r\n \"\",\r\n ].join(\"\\n\"),\r\n );\r\n return;\r\n }\r\n\r\n if (argFlag(\"--version\") || argFlag(\"-v\")) {\r\n process.stdout.write(VERSION + \"\\n\");\r\n return;\r\n }\r\n\r\n if (argFlag(\"--reset\")) {\r\n await resetConfig();\r\n return;\r\n }\r\n\r\n const origin =\r\n process.env.REMOTE_LINK_ORIGIN ||\r\n process.argv.find((value) => value.startsWith(\"--origin=\"))?.slice(9) ||\r\n DEFAULT_ORIGIN;\r\n\r\n let config = await readConfig();\r\n if (!config) {\r\n config = await pair(origin, selectedMode());\r\n } else if (argFlag(\"--safe\") || argFlag(\"--developer\")) {\r\n config.mode = selectedMode();\r\n await writeConfig(config);\r\n }\r\n\r\n await connectAgent(config);\r\n}\r\n\r\nmain().catch((error) => {\r\n process.stderr.write(\r\n \"\\nRemote Link error: \" +\r\n (error instanceof Error ? error.message : String(error)) +\r\n \"\\n\",\r\n );\r\n process.exit(1);\r\n});\r\n"],"mappings":";;;AACA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,aAAa;AACtB,OAAO,aAAa;AACpB,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC,OAAO,eAAe;AAEtB,IAAM,UAAU;AAChB,IAAM,iBAAiB;AACvB,IAAM,aAAa,KAAK,KAAK,GAAG,QAAQ,GAAG,cAAc;AACzD,IAAM,cAAc,KAAK,KAAK,YAAY,aAAa;AA4BvD,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B,GAAG;AAAA,EACH;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,QAAQ,CAAC,OAAe,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAE9E,SAAS,QAAQ,MAAc;AAC7B,SAAO,QAAQ,KAAK,SAAS,IAAI;AACnC;AAEA,SAAS,eAAqB;AAC5B,MAAI,QAAQ,QAAQ,EAAG,QAAO;AAC9B,SAAO;AACT;AAEA,eAAe,aAA0C;AACvD,MAAI;AACF,WAAO,KAAK,MAAM,MAAM,GAAG,SAAS,aAAa,MAAM,CAAC;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,YAAY,QAAqB;AAC9C,QAAM,GAAG,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAC9C,QAAM,GAAG,UAAU,aAAa,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM;AAAA,IACtE,MAAM;AAAA,EACR,CAAC;AACH;AAEA,eAAe,cAAc;AAC3B,QAAM,GAAG,GAAG,aAAa,EAAE,OAAO,KAAK,CAAC;AACxC,UAAQ,OAAO,MAAM,2CAA2C;AAClE;AAEA,SAAS,YAAY,KAAa;AAChC,QAAM,UACJ,QAAQ,aAAa,UACjB,QACA,QAAQ,aAAa,WACnB,SACA;AACR,QAAM,OACJ,QAAQ,aAAa,UACjB,CAAC,MAAM,SAAS,IAAI,GAAG,IACvB,CAAC,GAAG;AAEV,QAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,IACjC,UAAU;AAAA,IACV,OAAO;AAAA,EACT,CAAC;AACD,QAAM,MAAM;AACd;AAEA,eAAe,KAAK,QAAgB,MAAkC;AACpE,QAAM,aAAa,GAAG,SAAS;AAC/B,QAAM,WAAW,MAAM,MAAM,SAAS,qBAAqB;AAAA,IACzD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU;AAAA,MACnB,aAAa;AAAA,MACb,UAAU,QAAQ;AAAA,MAClB,MAAM,QAAQ;AAAA,MACd,UAAU,GAAG,SAAS;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,qCAAqC,SAAS,MAAM;AAAA,EACtE;AAEA,QAAM,UAAW,MAAM,SAAS,KAAK;AAErC,UAAQ,OAAO,MAAM,mBAAmB;AACxC,UAAQ,OAAO,MAAM,yCAAyC;AAC9D,UAAQ,OAAO,MAAM,OAAO,QAAQ,YAAY,MAAM;AACtD,UAAQ,OAAO,MAAM,QAAQ,4BAA4B,MAAM;AAC/D,UAAQ,OAAO,MAAM,sBAAsB;AAC3C,cAAY,QAAQ,yBAAyB;AAE7C,QAAM,YAAY,KAAK,IAAI;AAC3B,SAAO,KAAK,IAAI,IAAI,YAAY,QAAQ,aAAa,KAAM;AACzD,UAAM,MAAM,KAAK,IAAI,QAAQ,UAAU,CAAC,IAAI,GAAI;AAEhD,UAAM,gBAAgB,MAAM,MAAM,SAAS,qBAAqB;AAAA,MAC9D,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,aAAa,QAAQ;AAAA,QACrB,eAAe,QAAQ;AAAA,MACzB,CAAC;AAAA,IACH,CAAC;AAED,QAAI,cAAc,WAAW,KAAK;AAChC,cAAQ,OAAO,MAAM,GAAG;AACxB;AAAA,IACF;AAEA,QAAI,CAAC,cAAc,IAAI;AACrB,YAAM,OAAO,MAAM,cAAc,KAAK;AACtC,YAAM,IAAI,MAAM,qBAAqB,IAAI;AAAA,IAC3C;AAEA,UAAM,SAAU,MAAM,cAAc,KAAK;AACzC,YAAQ,OAAO,MAAM,gCAA2B;AAEhD,UAAM,SAAsB;AAAA,MAC1B,UAAU,OAAO;AAAA,MACjB,aAAa,OAAO;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,YAAY,MAAM;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,kDAAkD;AACpE;AAEA,IAAM,gBAAN,MAAoB;AAAA,EAGlB,YAA6B,MAAY;AAAZ;AAAA,EAAa;AAAA,EAAb;AAAA,EAFrB,SAAwB;AAAA,EAIhC,MAAM,UAAU;AACd,QAAI,KAAK,OAAQ,QAAO,KAAK;AAE7B,UAAM,SAAS,IAAI,OAAO;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAED,UAAM,UAAU,QAAQ,aAAa,UAAU,YAAY;AAC3D,UAAM,YAAY,IAAI,qBAAqB;AAAA,MACzC;AAAA,MACA,MAAM,CAAC,MAAM,wCAAwC;AAAA,MACrD,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,OAAO,QAAQ,SAAS;AAC9B,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ;AACZ,UAAM,OAAO,OAAO,MAAM,KAAK,QAAQ,GAAG,UAAU;AACpD,UAAM,UAAU,KAAK,SAAS,cAAc,kBAAkB;AAC9D,WAAO,KAAK,MAAM,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,IAAI,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,KAAK,MAAc,MAA+B;AACtD,UAAM,UAAU,KAAK,SAAS,cAAc,kBAAkB;AAC9D,QAAI,CAAC,QAAQ,IAAI,IAAI,GAAG;AACtB,YAAM,IAAI,MAAM,4CAA4C,IAAI;AAAA,IAClE;AAEA,YAAQ,MAAM,KAAK,QAAQ,GAAG,SAAS;AAAA,MACrC;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,KAAK,OAAO,MAAM;AACxB,SAAK,SAAS;AAAA,EAChB;AACF;AAEA,eAAe,aAAa,QAAqB;AAC/C,QAAM,OAAO,IAAI,cAAc,OAAO,IAAI;AAC1C,QAAM,QAAQ,MAAM,KAAK,MAAM;AAC/B,QAAM,QAAQ,IAAI,IAAI,UAAU,OAAO,OAAO,QAAQ,SAAS,IAAI,CAAC;AAEpE,MAAI,UAAU;AACd,MAAI,UAAU;AAEd,QAAM,WAAW,YAAY;AAC3B,cAAU;AACV,UAAM,KAAK,MAAM,EAAE,MAAM,MAAM,MAAS;AACxC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,QAAQ;AAC7B,UAAQ,GAAG,WAAW,QAAQ;AAE9B,SAAO,CAAC,SAAS;AACf,UAAM,KAAK,IAAI,UAAU,OAAO;AAAA,MAC9B,SAAS;AAAA,QACP,eAAe,YAAY,OAAO;AAAA,MACpC;AAAA,IACF,CAAC;AAED,QAAI;AACF,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAG,KAAK,QAAQ,OAAO;AACvB,WAAG,KAAK,SAAS,MAAM;AAAA,MACzB,CAAC;AAED,gBAAU;AACV,SAAG;AAAA,QACD,KAAK,UAAU;AAAA,UACb,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,IAAI,OAAO;AAAA,YACX,MAAM,OAAO;AAAA,YACb,UAAU,QAAQ;AAAA,YAClB,MAAM,QAAQ;AAAA,YACd,UAAU,GAAG,SAAS;AAAA,YACtB,cAAc;AAAA,UAChB;AAAA,UACA,OAAO,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAEA,cAAQ,OAAO;AAAA,QACb,yBACE,OAAO,aACP,OACA,OAAO,OACP;AAAA,MACJ;AACA,cAAQ,OAAO,MAAM,OAAO,OAAO,SAAS,IAAI;AAChD,cAAQ,OAAO,MAAM,+BAA+B;AAEpD,YAAM,IAAI,QAAc,CAAC,YAAY;AACnC,WAAG,GAAG,WAAW,OAAO,QAAQ;AAC9B,cAAI;AAOJ,cAAI;AACF,sBAAU,KAAK,MAAM,IAAI,SAAS,CAAC;AAAA,UACrC,QAAQ;AACN;AAAA,UACF;AAEA,cACE,QAAQ,SAAS,UACjB,CAAC,QAAQ,MACT,CAAC,QAAQ,MACT;AACA;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,SAAS,MAAM,KAAK;AAAA,cACxB,QAAQ;AAAA,cACR,QAAQ,aAAa,CAAC;AAAA,YACxB;AACA,eAAG;AAAA,cACD,KAAK,UAAU;AAAA,gBACb,MAAM;AAAA,gBACN,IAAI,QAAQ;AAAA,gBACZ;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF,SAAS,OAAO;AACd,eAAG;AAAA,cACD,KAAK,UAAU;AAAA,gBACb,MAAM;AAAA,gBACN,IAAI,QAAQ;AAAA,gBACZ,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,cAC9D,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF,CAAC;AAED,WAAG,KAAK,SAAS,OAAO;AACxB,WAAG,KAAK,SAAS,OAAO;AAAA,MAC1B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,OAAO;AAAA,QACb,qCACG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACtD;AAAA,MACJ;AAAA,IACF,UAAE;AACA,SAAG,mBAAmB;AACtB,SAAG,MAAM;AAAA,IACX;AAEA,QAAI,CAAC,SAAS;AACZ,cAAQ,OAAO;AAAA,QACb,mCAAmC,KAAK,MAAM,UAAU,GAAI,IAAI;AAAA,MAClE;AACA,YAAM,MAAM,OAAO;AACnB,gBAAU,KAAK,IAAI,UAAU,GAAG,GAAM;AAAA,IACxC;AAAA,EACF;AACF;AAEA,eAAe,OAAO;AACpB,MAAI,QAAQ,QAAQ,KAAK,QAAQ,IAAI,GAAG;AACtC,YAAQ,OAAO;AAAA,MACb;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AACA;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,KAAK,QAAQ,IAAI,GAAG;AACzC,YAAQ,OAAO,MAAM,UAAU,IAAI;AACnC;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,YAAY;AAClB;AAAA,EACF;AAEA,QAAM,SACJ,QAAQ,IAAI,sBACZ,QAAQ,KAAK,KAAK,CAAC,UAAU,MAAM,WAAW,WAAW,CAAC,GAAG,MAAM,CAAC,KACpE;AAEF,MAAI,SAAS,MAAM,WAAW;AAC9B,MAAI,CAAC,QAAQ;AACX,aAAS,MAAM,KAAK,QAAQ,aAAa,CAAC;AAAA,EAC5C,WAAW,QAAQ,QAAQ,KAAK,QAAQ,aAAa,GAAG;AACtD,WAAO,OAAO,aAAa;AAC3B,UAAM,YAAY,MAAM;AAAA,EAC1B;AAEA,QAAM,aAAa,MAAM;AAC3B;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,OAAO;AAAA,IACb,2BACG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACtD;AAAA,EACJ;AACA,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\nimport os from \"node:os\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs/promises\";\r\nimport { spawn } from \"node:child_process\";\r\nimport process from \"node:process\";\r\nimport { Client } from \"@modelcontextprotocol/client\";\r\nimport { StdioClientTransport } from \"@modelcontextprotocol/client/stdio\";\r\nimport WebSocket from \"ws\";\r\n\r\nconst VERSION = \"0.3.0\";\r\nconst DEFAULT_ORIGIN = \"https://remote.samyao.me\";\r\nconst CONFIG_DIR = path.join(os.homedir(), \".remotearc\");\r\nconst CONFIG_PATH = path.join(CONFIG_DIR, \"config.json\");\r\nconst LEGACY_CONFIG_PATH = path.join(os.homedir(), \".remote-link\", \"config.json\");\r\n\r\ntype Mode = \"safe\" | \"developer\";\r\n\r\ntype SavedConfig = {\r\n deviceId: string;\r\n deviceToken: string;\r\n deviceName: string;\r\n origin: string;\r\n mode: Mode;\r\n};\r\n\r\ntype PairingStart = {\r\n device_code: string;\r\n device_secret: string;\r\n user_code: string;\r\n verification_uri: string;\r\n verification_uri_complete: string;\r\n expires_in: number;\r\n interval: number;\r\n};\r\n\r\ntype PairingToken = {\r\n device_id: string;\r\n device_token: string;\r\n relay_url: string;\r\n};\r\n\r\nconst SAFE_TOOLS = new Set([\r\n \"list_directory\",\r\n \"read_file\",\r\n \"get_file_info\",\r\n \"list_processes\",\r\n]);\r\n\r\nconst DEVELOPER_TOOLS = new Set([\r\n ...SAFE_TOOLS,\r\n \"start_process\",\r\n \"write_file\",\r\n \"edit_block\",\r\n]);\r\n\r\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\r\n\r\nfunction argFlag(name: string) {\r\n return process.argv.includes(name);\r\n}\r\n\r\nfunction selectedMode(): Mode {\r\n if (argFlag(\"--safe\")) return \"safe\";\r\n return \"developer\";\r\n}\r\n\r\nasync function readConfig(): Promise<SavedConfig | null> {\r\n try {\r\n return JSON.parse(await fs.readFile(CONFIG_PATH, \"utf8\")) as SavedConfig;\r\n } catch {\r\n try {\r\n const legacy = JSON.parse(\r\n await fs.readFile(LEGACY_CONFIG_PATH, \"utf8\"),\r\n ) as SavedConfig;\r\n await writeConfig(legacy);\r\n process.stdout.write(\r\n \"Migrated existing Remote Link pairing to Remote Arc.\\n\",\r\n );\r\n return legacy;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n}\r\n\r\nasync function writeConfig(config: SavedConfig) {\r\n await fs.mkdir(CONFIG_DIR, { recursive: true });\r\n await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2) + \"\\n\", {\r\n mode: 0o600,\r\n });\r\n}\r\n\r\nasync function resetConfig() {\r\n await Promise.all([\r\n fs.rm(CONFIG_PATH, { force: true }),\r\n fs.rm(LEGACY_CONFIG_PATH, { force: true }),\r\n ]);\r\n process.stdout.write(\"Remote Arc device credentials removed.\\n\");\r\n}\r\n\r\nfunction openBrowser(url: string) {\r\n const command =\r\n process.platform === \"win32\"\r\n ? \"cmd\"\r\n : process.platform === \"darwin\"\r\n ? \"open\"\r\n : \"xdg-open\";\r\n const args =\r\n process.platform === \"win32\"\r\n ? [\"/c\", \"start\", \"\", url]\r\n : [url];\r\n\r\n const child = spawn(command, args, {\r\n detached: true,\r\n stdio: \"ignore\",\r\n });\r\n child.unref();\r\n}\r\n\r\nasync function pair(origin: string, mode: Mode): Promise<SavedConfig> {\r\n const deviceName = os.hostname();\r\n const response = await fetch(origin + \"/api/device/start\", {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({\r\n device_name: deviceName,\r\n platform: process.platform,\r\n arch: process.arch,\r\n hostname: os.hostname(),\r\n }),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(\"Could not start device pairing: \" + response.status);\r\n }\r\n\r\n const pairing = (await response.json()) as PairingStart;\r\n\r\n process.stdout.write(\"\\nRemote Arc\\n\\n\");\r\n process.stdout.write(\"Pair this computer in your browser.\\n\\n\");\r\n process.stdout.write(\" \" + pairing.user_code + \"\\n\\n\");\r\n process.stdout.write(pairing.verification_uri_complete + \"\\n\\n\");\r\n process.stdout.write(\"Opening browser...\\n\");\r\n openBrowser(pairing.verification_uri_complete);\r\n\r\n const startedAt = Date.now();\r\n while (Date.now() - startedAt < pairing.expires_in * 1000) {\r\n await sleep(Math.max(pairing.interval, 2) * 1000);\r\n\r\n const tokenResponse = await fetch(origin + \"/api/device/token\", {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({\r\n device_code: pairing.device_code,\r\n device_secret: pairing.device_secret,\r\n }),\r\n });\r\n\r\n if (tokenResponse.status === 428) {\r\n process.stdout.write(\".\");\r\n continue;\r\n }\r\n\r\n if (!tokenResponse.ok) {\r\n const body = await tokenResponse.text();\r\n throw new Error(\"Pairing failed: \" + body);\r\n }\r\n\r\n const result = (await tokenResponse.json()) as PairingToken;\r\n process.stdout.write(\"\\n\\n✓ Device authorized\\n\");\r\n\r\n const config: SavedConfig = {\r\n deviceId: result.device_id,\r\n deviceToken: result.device_token,\r\n deviceName,\r\n origin,\r\n mode,\r\n };\r\n await writeConfig(config);\r\n return config;\r\n }\r\n\r\n throw new Error(\"Pairing expired. Run Remote Arc again to retry.\");\r\n}\r\n\r\nclass ExecutionCore {\r\n private client: Client | null = null;\r\n\r\n constructor(private readonly mode: Mode) {}\r\n\r\n async connect() {\r\n if (this.client) return this.client;\r\n\r\n const client = new Client({\r\n name: \"remotearc-cli-core\",\r\n version: VERSION,\r\n });\r\n\r\n const command = process.platform === \"win32\" ? \"npx.cmd\" : \"npx\";\r\n const transport = new StdioClientTransport({\r\n command,\r\n args: [\"-y\", \"@wonderwhy-er/desktop-commander@latest\"],\r\n stderr: \"inherit\",\r\n });\r\n\r\n await client.connect(transport);\r\n this.client = client;\r\n return client;\r\n }\r\n\r\n async tools() {\r\n const list = await (await this.connect()).listTools();\r\n const allowed = this.mode === \"developer\" ? DEVELOPER_TOOLS : SAFE_TOOLS;\r\n return list.tools.filter((tool) => allowed.has(tool.name));\r\n }\r\n\r\n async call(name: string, args: Record<string, unknown>) {\r\n const allowed = this.mode === \"developer\" ? DEVELOPER_TOOLS : SAFE_TOOLS;\r\n if (!allowed.has(name)) {\r\n throw new Error(\"Tool blocked by local permission mode: \" + name);\r\n }\r\n\r\n return (await this.connect()).callTool({\r\n name,\r\n arguments: args,\r\n });\r\n }\r\n\r\n async close() {\r\n if (!this.client) return;\r\n await this.client.close();\r\n this.client = null;\r\n }\r\n}\r\n\r\nasync function connectAgent(config: SavedConfig) {\r\n const core = new ExecutionCore(config.mode);\r\n const tools = await core.tools();\r\n const wsUrl = new URL(\"/agent\", config.origin.replace(/^http/, \"ws\"));\r\n\r\n let stopped = false;\r\n let backoff = 1000;\r\n\r\n const shutdown = async () => {\r\n stopped = true;\r\n await core.close().catch(() => undefined);\r\n process.exit(0);\r\n };\r\n process.on(\"SIGINT\", shutdown);\r\n process.on(\"SIGTERM\", shutdown);\r\n\r\n while (!stopped) {\r\n const ws = new WebSocket(wsUrl, {\r\n headers: {\r\n Authorization: \"Bearer \" + config.deviceToken,\r\n },\r\n });\r\n\r\n try {\r\n await new Promise<void>((resolve, reject) => {\r\n ws.once(\"open\", resolve);\r\n ws.once(\"error\", reject);\r\n });\r\n\r\n backoff = 1000;\r\n ws.send(\r\n JSON.stringify({\r\n type: \"hello\",\r\n device: {\r\n id: config.deviceId,\r\n name: config.deviceName,\r\n platform: process.platform,\r\n arch: process.arch,\r\n hostname: os.hostname(),\r\n agentVersion: VERSION,\r\n },\r\n tools: tools.map((tool) => tool.name),\r\n }),\r\n );\r\n\r\n process.stdout.write(\r\n \"✓ Connected as \" +\r\n config.deviceName +\r\n \" (\" +\r\n config.mode +\r\n \" mode)\\n\",\r\n );\r\n process.stdout.write(\" \" + config.origin + \"\\n\");\r\n process.stdout.write(\"Press Ctrl+C to disconnect.\\n\");\r\n\r\n await new Promise<void>((resolve) => {\r\n ws.on(\"message\", async (raw) => {\r\n let message: {\r\n type?: string;\r\n id?: string;\r\n tool?: string;\r\n arguments?: Record<string, unknown>;\r\n };\r\n\r\n try {\r\n message = JSON.parse(raw.toString());\r\n } catch {\r\n return;\r\n }\r\n\r\n if (\r\n message.type !== \"call\" ||\r\n !message.id ||\r\n !message.tool\r\n ) {\r\n return;\r\n }\r\n\r\n try {\r\n const result = await core.call(\r\n message.tool,\r\n message.arguments || {},\r\n );\r\n ws.send(\r\n JSON.stringify({\r\n type: \"result\",\r\n id: message.id,\r\n result,\r\n }),\r\n );\r\n } catch (error) {\r\n ws.send(\r\n JSON.stringify({\r\n type: \"result\",\r\n id: message.id,\r\n error: error instanceof Error ? error.message : String(error),\r\n }),\r\n );\r\n }\r\n });\r\n\r\n ws.once(\"close\", resolve);\r\n ws.once(\"error\", resolve);\r\n });\r\n } catch (error) {\r\n process.stderr.write(\r\n \"Remote Arc connection failed: \" +\r\n (error instanceof Error ? error.message : String(error)) +\r\n \"\\n\",\r\n );\r\n } finally {\r\n ws.removeAllListeners();\r\n ws.close();\r\n }\r\n\r\n if (!stopped) {\r\n process.stdout.write(\r\n \"Disconnected. Reconnecting in \" + Math.round(backoff / 1000) + \"s...\\n\",\r\n );\r\n await sleep(backoff);\r\n backoff = Math.min(backoff * 2, 30_000);\r\n }\r\n }\r\n}\r\n\r\nasync function main() {\r\n if (argFlag(\"--help\") || argFlag(\"-h\")) {\r\n process.stdout.write(\r\n [\r\n \"Remote Arc\",\r\n \"\",\r\n \"Usage:\",\r\n \" npx remotelink\",\r\n \"\",\r\n \"After the npm release:\",\r\n \" npx remotelink\",\r\n \"\",\r\n \"Options:\",\r\n \" --safe Read-only local capability mode\",\r\n \" --developer Read/write/shell mode (default)\",\r\n \" --reset Remove this computer's saved pairing\",\r\n \" --version Print CLI version\",\r\n \" --help Show this help\",\r\n \"\",\r\n ].join(\"\\n\"),\r\n );\r\n return;\r\n }\r\n\r\n if (argFlag(\"--version\") || argFlag(\"-v\")) {\r\n process.stdout.write(VERSION + \"\\n\");\r\n return;\r\n }\r\n\r\n if (argFlag(\"--reset\")) {\r\n await resetConfig();\r\n return;\r\n }\r\n\r\n const origin =\r\n process.env.REMOTEARC_ORIGIN || process.env.REMOTE_LINK_ORIGIN ||\r\n process.argv.find((value) => value.startsWith(\"--origin=\"))?.slice(9) ||\r\n DEFAULT_ORIGIN;\r\n\r\n let config = await readConfig();\r\n if (!config) {\r\n config = await pair(origin, selectedMode());\r\n } else if (argFlag(\"--safe\") || argFlag(\"--developer\")) {\r\n config.mode = selectedMode();\r\n await writeConfig(config);\r\n }\r\n\r\n await connectAgent(config);\r\n}\r\n\r\nmain().catch((error) => {\r\n process.stderr.write(\r\n \"\\nRemote Arc error: \" +\r\n (error instanceof Error ? error.message : String(error)) +\r\n \"\\n\",\r\n );\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "remotelink",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Connect a computer to Remote
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"remotelink": "dist/index.js",
|
|
8
|
-
"remote-link": "dist/index.js"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"@types/
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "remotelink",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Connect a computer to Remote Arc with one command.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"remotelink": "dist/index.js",
|
|
8
|
+
"remote-link": "dist/index.js",
|
|
9
|
+
"remote-arc": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup src/index.ts --format esm --platform node --target node20 --sourcemap",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"prepublishOnly": "pnpm build"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@modelcontextprotocol/client": "^2.1.0",
|
|
24
|
+
"ws": "^8.18.3"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^24.13.6",
|
|
28
|
+
"@types/ws": "^8.18.1",
|
|
29
|
+
"tsup": "^8.5.0",
|
|
30
|
+
"typescript": "^6.0.3"
|
|
31
|
+
}
|
|
32
|
+
}
|