agentroam 0.2.0-preview.25 → 0.2.0-preview.26
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/bin/node-preflight.mjs +1 -1
- package/dist/cli.js +7 -0
- package/dist/error-log.js +113 -0
- package/dist/platform-packages.js +1 -1
- package/dist/runtime-manager.js +3 -0
- package/dist/tunnel/public-readiness.js +1 -1
- package/install/install-agentroam.ps1 +1 -1
- package/install/install-agentroam.sh +1 -1
- package/package.json +7 -7
package/bin/node-preflight.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import { MINIMUM_NODE_VERSION, compareNodeVersions, isSupportedNodeVersion, parseNodeVersion } from "./runtime-policy.mjs";
|
|
8
8
|
|
|
9
9
|
const execFileAsync = promisify(execFile);
|
|
10
|
-
const RELEASE_VERSION = "0.2.0-preview.
|
|
10
|
+
const RELEASE_VERSION = "0.2.0-preview.26";
|
|
11
11
|
const RELEASE_BASE_URL = `https://gitee.com/caoqu/team-agent/releases/download/v${RELEASE_VERSION}`;
|
|
12
12
|
const FORWARDED_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
13
13
|
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { printLocalDesktopUrl } from './local-desktop-url.js';
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join } from "node:path";
|
|
4
5
|
import { parseArgs } from "./args.js";
|
|
5
6
|
import { ensureCloudflared } from "./cloudflared/installer.js";
|
|
6
7
|
import { resolveCodexRuntime } from "./codex-runtime-manager.js";
|
|
@@ -19,6 +20,7 @@ import { currentCliPath, startUpdate } from "./update/update-command.js";
|
|
|
19
20
|
import { runUpdateWorker } from "./update/update-worker.js";
|
|
20
21
|
import { lockInstanceStartup, stopPreviousInstances } from "./instance-takeover.js";
|
|
21
22
|
import { runUnlockServiceCommand } from "./unlock-service.js";
|
|
23
|
+
import { createCliErrorLog } from "./error-log.js";
|
|
22
24
|
const VERSION = AGENTROAM_VERSION;
|
|
23
25
|
export async function main(argv) {
|
|
24
26
|
if (argv.includes("--help") || argv.includes("-h")) {
|
|
@@ -41,6 +43,11 @@ export async function main(argv) {
|
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
45
|
const options = parseArgs(argv);
|
|
46
|
+
// CLI 进程自身的按天错误日志:<dataDir>/logs/YYYY-MM-DD.log(NDJSON,与
|
|
47
|
+
// server/desktop 的 core logger 同格式)。uncaughtException 记录后按默认
|
|
48
|
+
// 语义退出(1),unhandledRejection 只记录。
|
|
49
|
+
const cliErrorLog = createCliErrorLog(join(options.dataDir, "logs"));
|
|
50
|
+
cliErrorLog.installGlobalErrorHandlers();
|
|
44
51
|
if (["pair", "devices", "revoke", "approvals", "approve", "deny", "lock", "unlock", "audit"].includes(options.command)) {
|
|
45
52
|
const dataDir = argv.includes("--data-dir") ? options.dataDir : await installedDataDir(options.dataDir);
|
|
46
53
|
if (options.command === "pair")
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
// Self-contained daily error log for the CLI process. The CLI cannot depend
|
|
4
|
+
// on @agent/core (it ships as a thin launcher), so this mirrors the exact
|
|
5
|
+
// NDJSON entry format of core's DailyFileLogger
|
|
6
|
+
// (`{ts, level, source, message, error?, data?}`) into `<dataDir>/logs/`.
|
|
7
|
+
// It records uncaughtException / unhandledRejection so launcher failures are
|
|
8
|
+
// strictly persisted, matching the server/desktop log series.
|
|
9
|
+
const LEVELS = new Set(["debug", "info", "warn", "error", "fatal"]);
|
|
10
|
+
function localDateString(date) {
|
|
11
|
+
const y = date.getFullYear();
|
|
12
|
+
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
13
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
14
|
+
return `${y}-${m}-${d}`;
|
|
15
|
+
}
|
|
16
|
+
function serializeError(err) {
|
|
17
|
+
if (err === undefined || err === null)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (err instanceof Error) {
|
|
20
|
+
const out = { name: err.name, message: err.message };
|
|
21
|
+
if (err.stack)
|
|
22
|
+
out.stack = err.stack;
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
if (typeof err === "object") {
|
|
26
|
+
const anyErr = err;
|
|
27
|
+
const out = {
|
|
28
|
+
name: typeof anyErr.name === "string" ? anyErr.name : "NonError",
|
|
29
|
+
message: typeof anyErr.message === "string" ? anyErr.message : String(err),
|
|
30
|
+
};
|
|
31
|
+
if (typeof anyErr.stack === "string")
|
|
32
|
+
out.stack = anyErr.stack;
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
return { name: "NonError", message: String(err) };
|
|
36
|
+
}
|
|
37
|
+
function safeStringify(value) {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.stringify(value) ?? "null";
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return '"[unserializable]"';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function createCliErrorLog(logsDir) {
|
|
46
|
+
let reportedWriteFailure = false;
|
|
47
|
+
const write = (line) => {
|
|
48
|
+
try {
|
|
49
|
+
if (!existsSync(logsDir))
|
|
50
|
+
mkdirSync(logsDir, { recursive: true });
|
|
51
|
+
appendFileSync(join(logsDir, `${localDateString(new Date())}.log`), line, "utf8");
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
if (!reportedWriteFailure) {
|
|
55
|
+
reportedWriteFailure = true;
|
|
56
|
+
try {
|
|
57
|
+
process.stderr.write(`[agentroam] failed to write error log to ${logsDir}; further failures are silent\n`);
|
|
58
|
+
}
|
|
59
|
+
catch { /* stderr gone */ }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const cleanupOldFiles = () => {
|
|
64
|
+
// 30-day retention, aligned with the core logger default. Best effort.
|
|
65
|
+
try {
|
|
66
|
+
if (!existsSync(logsDir))
|
|
67
|
+
return;
|
|
68
|
+
const cutoff = Date.now() - 30 * 24 * 60 * 60 * 1000;
|
|
69
|
+
for (const name of readdirSync(logsDir)) {
|
|
70
|
+
if (!/^\d{4}-\d{2}-\d{2}\.log$/.test(name))
|
|
71
|
+
continue;
|
|
72
|
+
const full = join(logsDir, name);
|
|
73
|
+
try {
|
|
74
|
+
if (statSync(full).mtimeMs < cutoff)
|
|
75
|
+
unlinkSync(full);
|
|
76
|
+
}
|
|
77
|
+
catch { /* concurrent removal */ }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch { /* best effort */ }
|
|
81
|
+
};
|
|
82
|
+
const log = (level, message, error, data) => {
|
|
83
|
+
if (!LEVELS.has(level))
|
|
84
|
+
level = "error";
|
|
85
|
+
const entry = {
|
|
86
|
+
ts: new Date().toISOString(),
|
|
87
|
+
level,
|
|
88
|
+
source: "cli",
|
|
89
|
+
message: typeof message === "string" ? message.slice(0, 4000) : String(message),
|
|
90
|
+
};
|
|
91
|
+
const serialized = serializeError(error);
|
|
92
|
+
if (serialized)
|
|
93
|
+
entry.error = serialized;
|
|
94
|
+
if (data !== undefined)
|
|
95
|
+
entry.data = data;
|
|
96
|
+
write(`${safeStringify(entry)}\n`);
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
log,
|
|
100
|
+
installGlobalErrorHandlers: (options = {}) => {
|
|
101
|
+
const exitOnUncaughtException = options.exitOnUncaughtException ?? true;
|
|
102
|
+
process.on("uncaughtException", (err) => {
|
|
103
|
+
log("fatal", "uncaughtException", err);
|
|
104
|
+
if (exitOnUncaughtException)
|
|
105
|
+
process.exit(1);
|
|
106
|
+
});
|
|
107
|
+
process.on("unhandledRejection", (reason) => {
|
|
108
|
+
log("error", "unhandledRejection", reason);
|
|
109
|
+
});
|
|
110
|
+
cleanupOldFiles();
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { MINIMUM_NODE_VERSION, assertSupportedNodeVersion } from "../bin/runtime-policy.mjs";
|
|
5
|
-
export const AGENTROAM_VERSION = "0.2.0-preview.
|
|
5
|
+
export const AGENTROAM_VERSION = "0.2.0-preview.26";
|
|
6
6
|
export const PLATFORM_DEPENDENCY_VERSIONS = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).optionalDependencies;
|
|
7
7
|
export const PLATFORM_PACKAGES = {
|
|
8
8
|
"darwin-arm64": {
|
package/dist/runtime-manager.js
CHANGED
|
@@ -36,6 +36,9 @@ export class RuntimeManager {
|
|
|
36
36
|
PORT: String(port),
|
|
37
37
|
HOST: options.localOnly ? "0.0.0.0" : "127.0.0.1",
|
|
38
38
|
AGENT_DATA_DIR: resolve(dataDir, "data"),
|
|
39
|
+
// 应用日志收口到 <dataDir>/logs,与 launchd 的 service.stdout/stderr.log
|
|
40
|
+
// 及 CLI 自身的错误日志同一个目录,用户排障时只需打包这一处。
|
|
41
|
+
AGENT_LOG_DIR: resolve(dataDir, "logs"),
|
|
39
42
|
AGENT_WEB_ROOTS: options.roots.join(delimiter),
|
|
40
43
|
AGENT_TRUST_TUNNEL_PROXY: "1",
|
|
41
44
|
AGENTROAM_VERSION: resolvePlatformRuntime(target).manifest.packageVersion,
|
|
@@ -22,7 +22,7 @@ export async function waitForPublicReadiness(publicUrl, options = {}) {
|
|
|
22
22
|
try {
|
|
23
23
|
const response = await fetchImpl(endpoint, {
|
|
24
24
|
cache: "no-store",
|
|
25
|
-
headers: { "user-agent": "agentroam-readiness/0.2.0-preview.
|
|
25
|
+
headers: { "user-agent": "agentroam-readiness/0.2.0-preview.26" },
|
|
26
26
|
signal: options.signal,
|
|
27
27
|
});
|
|
28
28
|
if (response.ok) {
|
|
@@ -4,7 +4,7 @@ $ProgressPreference = "SilentlyContinue"
|
|
|
4
4
|
$NodeVersion = "22.22.0"
|
|
5
5
|
$MinimumNodeVersion = "22.22.0"
|
|
6
6
|
# 默认跟随 npm preview 最新标签;可用 $env:AGENTROAM_VERSION 钉精确版本
|
|
7
|
-
# 例如:$env:AGENTROAM_VERSION = "0.2.0-preview.
|
|
7
|
+
# 例如:$env:AGENTROAM_VERSION = "0.2.0-preview.26"; ./install-agentroam.ps1
|
|
8
8
|
$AgentRoamVersionRequest = if ($env:AGENTROAM_VERSION) { $env:AGENTROAM_VERSION } else { "preview" }
|
|
9
9
|
$AgentRoamVersion = "pending-version"
|
|
10
10
|
$NodeArchive = "node-v22.22.0-win-x64.zip"
|
|
@@ -4,7 +4,7 @@ set -eu
|
|
|
4
4
|
NODE_VERSION="22.22.0"
|
|
5
5
|
MINIMUM_NODE_VERSION="22.22.0"
|
|
6
6
|
# Default to the newest published preview; pin an exact version via
|
|
7
|
-
# AGENTROAM_VERSION=0.2.0-preview.
|
|
7
|
+
# AGENTROAM_VERSION=0.2.0-preview.26 sh install-agentroam.sh
|
|
8
8
|
AGENTROAM_VERSION_REQUEST="${AGENTROAM_VERSION:-preview}"
|
|
9
9
|
AGENTROAM_VERSION=""
|
|
10
10
|
NODE_ARCHIVE="node-v22.22.0-darwin-arm64.tar.xz"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentroam",
|
|
3
|
-
"version": "0.2.0-preview.
|
|
3
|
+
"version": "0.2.0-preview.26",
|
|
4
4
|
"description": "Zero-install mobile remote terminal and file console",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"undici": "^6.25.0"
|
|
27
27
|
},
|
|
28
28
|
"optionalDependencies": {
|
|
29
|
-
"agentroam-runtime-darwin-arm64": "0.2.0-preview.
|
|
30
|
-
"agentroam-runtime-win32-x64": "0.2.0-preview.
|
|
31
|
-
"agentroam-cloudflared-darwin-arm64": "0.2.0-preview.
|
|
32
|
-
"agentroam-cloudflared-win32-x64": "0.2.0-preview.
|
|
33
|
-
"agentroam-tui-darwin-arm64": "0.2.0-preview.
|
|
34
|
-
"@caoqu/agentroam-tui-win32-x64": "0.2.0-preview.
|
|
29
|
+
"agentroam-runtime-darwin-arm64": "0.2.0-preview.26",
|
|
30
|
+
"agentroam-runtime-win32-x64": "0.2.0-preview.26",
|
|
31
|
+
"agentroam-cloudflared-darwin-arm64": "0.2.0-preview.26",
|
|
32
|
+
"agentroam-cloudflared-win32-x64": "0.2.0-preview.26",
|
|
33
|
+
"agentroam-tui-darwin-arm64": "0.2.0-preview.26",
|
|
34
|
+
"@caoqu/agentroam-tui-win32-x64": "0.2.0-preview.26"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^22.0.0",
|