remotelink 0.4.7 → 0.4.8
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/README.md +16 -2
- package/dist/index.js +39 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -23,6 +23,20 @@ On first run, `remotelink`:
|
|
|
23
23
|
No public IP, VPN, router port forwarding, repository clone, or manual token
|
|
24
24
|
copy is required.
|
|
25
25
|
|
|
26
|
+
<!-- latest-release:start -->
|
|
27
|
+
## Latest release
|
|
28
|
+
|
|
29
|
+
**remotelink 0.4.8 — Device-local execution logs in Dashboard**
|
|
30
|
+
|
|
31
|
+
Published 2026-10-08
|
|
32
|
+
|
|
33
|
+
- Add a live Device execution log to Dashboard → Activity & details, read on demand from the paired computer's local Remote Arc operation log.
|
|
34
|
+
- Show recent tool calls, completion/failure state, reconnect and recovery events without turning the hosted audit store into a file-content or stdout archive.
|
|
35
|
+
- Keep logs local when a device is offline and surface a clear update requirement for older remotelink Agents that do not support on-demand log reads.
|
|
36
|
+
|
|
37
|
+
See the [full Remote Arc release history](https://remotearc.app/releases) or the [GitHub changelog](https://github.com/yaohuangguan/remote-arc/blob/master/CHANGELOG.md).
|
|
38
|
+
<!-- latest-release:end -->
|
|
39
|
+
|
|
26
40
|
## Connect your AI client
|
|
27
41
|
|
|
28
42
|
Remote MCP endpoint:
|
|
@@ -53,7 +67,7 @@ npx remotelink --help Show help
|
|
|
53
67
|
|
|
54
68
|
The package also exposes the aliases `remote-link` and `remote-arc`.
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
Background recovery and Relay reconnect are separate. A normal `npx remotelink@latest` launch can safely hand off a known older background Agent to the current release without creating two executors.
|
|
57
71
|
Recovery installs a user service (macOS/Linux) or a hidden login supervisor
|
|
58
72
|
(Windows), which takes over when the executing Agent ends. Only one updated
|
|
59
73
|
Agent owns execution; additional terminals follow its operation log and offer
|
|
@@ -62,7 +76,7 @@ execution lease. Turning recovery off preserves current execution. Explicit
|
|
|
62
76
|
Stop background Agent also ends that Agent's work. Windows recovery needs the
|
|
63
77
|
supervisor to remain running; killing it requires a local relaunch or login.
|
|
64
78
|
Sleep/power loss still makes the device unavailable. All concurrent instances
|
|
65
|
-
must be updated; pre-0.4.4 Agents do not participate in the execution lease. When the installed version is identified as an older release,
|
|
79
|
+
must be updated; pre-0.4.4 Agents do not participate in the execution lease. When the installed version is identified as an older release, the current CLI performs a controlled handoff even when that older Agent still owns the execution lease: it stops the known Remote Arc worker and supervisor, waits for the lease to release, preserves pairing and policy, installs the replacement bundle, and verifies that the replacement worker owns execution. If a saved device pairing has been revoked from Dashboard, interactive startup now validates it before viewer/background attach, stops the known local background owner, clears the revoked credential and begins fresh pairing. Unknown processes still fail closed instead of being killed automatically.
|
|
66
80
|
|
|
67
81
|
## Native execution core
|
|
68
82
|
|
package/dist/index.js
CHANGED
|
@@ -6890,6 +6890,38 @@ async function readAgentEvents(directory, cursor) {
|
|
|
6890
6890
|
await handle?.close();
|
|
6891
6891
|
}
|
|
6892
6892
|
}
|
|
6893
|
+
async function readAgentEventTail(directory, requestedLimit = 100) {
|
|
6894
|
+
const limit = Math.max(20, Math.min(200, Math.trunc(requestedLimit || 100)));
|
|
6895
|
+
const file = path5.join(directory, "events.log");
|
|
6896
|
+
let handle;
|
|
6897
|
+
try {
|
|
6898
|
+
handle = await fs5.open(file, "r");
|
|
6899
|
+
const stat = await handle.stat();
|
|
6900
|
+
const start = Math.max(0, stat.size - 128 * 1024);
|
|
6901
|
+
const buffer = Buffer.alloc(Math.min(stat.size - start, 128 * 1024));
|
|
6902
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, start);
|
|
6903
|
+
let lines = buffer.subarray(0, bytesRead).toString("utf8").split("\n");
|
|
6904
|
+
if (start > 0) lines = lines.slice(1);
|
|
6905
|
+
lines = lines.map((line) => line.trimEnd()).filter(Boolean);
|
|
6906
|
+
return {
|
|
6907
|
+
source: "local-device",
|
|
6908
|
+
lines: lines.slice(-limit),
|
|
6909
|
+
total_bytes: stat.size,
|
|
6910
|
+
truncated: start > 0 || lines.length > limit,
|
|
6911
|
+
updated_at: stat.mtime.toISOString()
|
|
6912
|
+
};
|
|
6913
|
+
} catch {
|
|
6914
|
+
return {
|
|
6915
|
+
source: "local-device",
|
|
6916
|
+
lines: [],
|
|
6917
|
+
total_bytes: 0,
|
|
6918
|
+
truncated: false,
|
|
6919
|
+
updated_at: null
|
|
6920
|
+
};
|
|
6921
|
+
} finally {
|
|
6922
|
+
await handle?.close();
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6893
6925
|
async function superviseAgent(options) {
|
|
6894
6926
|
let delay = options.delayMs ?? 1e3;
|
|
6895
6927
|
while (!options.signal.aborted && await options.enabled()) {
|
|
@@ -7433,7 +7465,7 @@ var {
|
|
|
7433
7465
|
} = createBackgroundController();
|
|
7434
7466
|
|
|
7435
7467
|
// src/index.ts
|
|
7436
|
-
var VERSION = "0.4.
|
|
7468
|
+
var VERSION = "0.4.8";
|
|
7437
7469
|
var DEFAULT_ORIGIN = "https://mcp.remotearc.app";
|
|
7438
7470
|
var CONFIG_DIR = path7.join(os4.homedir(), ".remotearc");
|
|
7439
7471
|
var CONFIG_PATH = path7.join(CONFIG_DIR, "config.json");
|
|
@@ -7698,7 +7730,7 @@ async function connectAgent(config) {
|
|
|
7698
7730
|
`Permission profile: ${isLocalSafeMode(config.mode) ? green("safe local cap") : cyan("dashboard-managed")}`
|
|
7699
7731
|
);
|
|
7700
7732
|
const tools = await core.tools();
|
|
7701
|
-
const internalTools = ["background_agent_status", "set_background_agent", "set_task_keep_awake", "goal_workspace"];
|
|
7733
|
+
const internalTools = ["background_agent_status", "set_background_agent", "set_task_keep_awake", "goal_workspace", "agent_execution_log"];
|
|
7702
7734
|
let keepAwake = createTaskKeepAwakeManager();
|
|
7703
7735
|
logLine("success", `Local tools ready: ${tools.length} exposed`);
|
|
7704
7736
|
process3.stdout.write(" " + dim(tools.map((tool) => tool.name).join(" \xB7 ")) + "\n");
|
|
@@ -7900,6 +7932,11 @@ async function connectAgent(config) {
|
|
|
7900
7932
|
enabled: status.enabled,
|
|
7901
7933
|
desired_enabled: config.backgroundEnabled ?? null
|
|
7902
7934
|
};
|
|
7935
|
+
} else if (message.tool === "agent_execution_log") {
|
|
7936
|
+
result = await readAgentEventTail(
|
|
7937
|
+
path7.join(CONFIG_DIR, "logs"),
|
|
7938
|
+
Number(message.arguments?.limit || 100)
|
|
7939
|
+
);
|
|
7903
7940
|
} else if (message.tool === "set_background_agent") {
|
|
7904
7941
|
const enabled = message.arguments?.enabled;
|
|
7905
7942
|
if (typeof enabled !== "boolean") {
|