agentroam 0.2.0-preview.22 → 0.2.0-preview.23
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/codex-runtime-manager.js +20 -4
- package/dist/codex-runtime-manager.test.js +70 -9
- package/dist/platform-packages.js +1 -1
- package/dist/tunnel/public-readiness.js +1 -1
- package/install/install-agentroam.ps1 +1 -0
- package/install/install-agentroam.sh +1 -1
- package/package.json +3 -3
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.23";
|
|
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
|
|
|
@@ -5,6 +5,8 @@ import { delimiter, dirname, isAbsolute, relative, resolve, win32 } from "node:p
|
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
const execFileAsync = promisify(execFile);
|
|
7
7
|
export const CODEX_RUNTIME_VERSION = "0.153.0";
|
|
8
|
+
// Managed install pin tracks releases; the compatibility floor for user installs is independent.
|
|
9
|
+
export const CODEX_MINIMUM_VERSION = "0.153.0";
|
|
8
10
|
const CODEX_PACKAGE = `@openai/codex@${CODEX_RUNTIME_VERSION}`;
|
|
9
11
|
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
10
12
|
export const CODEX_INSTALL_TIMEOUT_MS = 60 * 60_000;
|
|
@@ -130,6 +132,19 @@ export function parseCodexVersion(output) {
|
|
|
130
132
|
const match = output.match(/(?:^|\s)(\d+\.\d+\.\d+)(?:\s|$)/);
|
|
131
133
|
return match?.[1] ?? null;
|
|
132
134
|
}
|
|
135
|
+
// Compare numeric components, so 0.153.10 and 0.154.0 both exceed 0.153.2.
|
|
136
|
+
export function isCodexVersionAtLeast(version, minimum) {
|
|
137
|
+
const actual = version.split(".").map(BigInt);
|
|
138
|
+
const required = minimum.split(".").map(BigInt);
|
|
139
|
+
for (let index = 0; index < required.length; index += 1) {
|
|
140
|
+
if (actual[index] !== required[index])
|
|
141
|
+
return actual[index] > required[index];
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
function meetsCodexMinimum(version) {
|
|
146
|
+
return isCodexVersionAtLeast(version, CODEX_MINIMUM_VERSION);
|
|
147
|
+
}
|
|
133
148
|
async function findCompatibleGlobalCodex(pathValue, platform, dependencies) {
|
|
134
149
|
const names = platform === "win32" ? ["codex.exe", "codex"] : ["codex"];
|
|
135
150
|
const pathDelimiter = platform === "win32" ? ";" : delimiter;
|
|
@@ -257,10 +272,11 @@ async function validateCodex(executable, source, _platform, dependencies) {
|
|
|
257
272
|
}
|
|
258
273
|
const versionResult = await dependencies.run(executable, ["--version"], 5_000);
|
|
259
274
|
const version = parseCodexVersion(`${versionResult.stdout}\n${versionResult.stderr}`);
|
|
260
|
-
if (!version)
|
|
261
|
-
throw new Error(`Unable to parse Codex version from ${executable}`);
|
|
262
|
-
|
|
263
|
-
|
|
275
|
+
if (!version) {
|
|
276
|
+
throw new Error(`Unable to parse a supported stable Codex version from ${executable}`);
|
|
277
|
+
}
|
|
278
|
+
if (!meetsCodexMinimum(version)) {
|
|
279
|
+
throw new Error(`Codex ${version} at ${executable} is incompatible; AgentRoam requires >=${CODEX_MINIMUM_VERSION}`);
|
|
264
280
|
}
|
|
265
281
|
try {
|
|
266
282
|
await dependencies.run(executable, ["app-server", "--help"], 5_000);
|
|
@@ -2,21 +2,31 @@ import { chmod, mkdtemp, mkdir, readdir, rm, writeFile } from "node:fs/promises"
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { dirname, resolve, win32 } from "node:path";
|
|
4
4
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
5
|
-
import { CODEX_INSTALL_STALE_LOCK_MS, CODEX_INSTALL_TIMEOUT_MS, CODEX_RUNTIME_VERSION, managedCodexBinaryCandidates, parseCodexVersion, resolveCodexRuntime, resolveNpmExecutor, } from "./codex-runtime-manager.js";
|
|
5
|
+
import { CODEX_INSTALL_STALE_LOCK_MS, CODEX_INSTALL_TIMEOUT_MS, CODEX_MINIMUM_VERSION, CODEX_RUNTIME_VERSION, isCodexVersionAtLeast, managedCodexBinaryCandidates, parseCodexVersion, resolveCodexRuntime, resolveNpmExecutor, } from "./codex-runtime-manager.js";
|
|
6
6
|
const temporaryDirectories = [];
|
|
7
7
|
afterEach(async () => {
|
|
8
8
|
await Promise.all(temporaryDirectories.splice(0).map((path) => rm(path, { recursive: true, force: true })));
|
|
9
9
|
});
|
|
10
10
|
describe("managed Codex runtime", () => {
|
|
11
11
|
it("parses the official version output", () => {
|
|
12
|
-
expect(parseCodexVersion("codex-cli 0.153.
|
|
12
|
+
expect(parseCodexVersion("codex-cli 0.153.5")).toBe("0.153.5");
|
|
13
13
|
expect(parseCodexVersion("codex-cli next")).toBeNull();
|
|
14
14
|
});
|
|
15
|
+
it("compares versions numerically instead of lexicographically", () => {
|
|
16
|
+
// Samples stay below the current pin: pins only move forward, so these
|
|
17
|
+
// literals can never collide with the upgrade script's version replacement.
|
|
18
|
+
expect(isCodexVersionAtLeast("0.140.12", "0.140.3")).toBe(true);
|
|
19
|
+
expect(isCodexVersionAtLeast("0.140.3", "0.140.12")).toBe(false);
|
|
20
|
+
expect(isCodexVersionAtLeast(CODEX_MINIMUM_VERSION, CODEX_MINIMUM_VERSION)).toBe(true);
|
|
21
|
+
expect(isCodexVersionAtLeast("0.139.9", CODEX_MINIMUM_VERSION)).toBe(false);
|
|
22
|
+
expect(isCodexVersionAtLeast("0.152.0", "0.140.0")).toBe(true);
|
|
23
|
+
expect(isCodexVersionAtLeast("1.0.0", "0.140.0")).toBe(true);
|
|
24
|
+
});
|
|
15
25
|
it("uses a compatible explicit absolute executable first", async () => {
|
|
16
26
|
const root = await temporaryRoot();
|
|
17
27
|
const executable = await fakeExecutable(resolve(root, "codex"));
|
|
18
28
|
const run = vi.fn(async (_command, args) => ({
|
|
19
|
-
stdout: args[0] === "--version" ?
|
|
29
|
+
stdout: args[0] === "--version" ? `codex-cli ${CODEX_RUNTIME_VERSION}\n` : "app-server help\n",
|
|
20
30
|
stderr: "",
|
|
21
31
|
}));
|
|
22
32
|
await expect(resolveCodexRuntime({
|
|
@@ -32,7 +42,29 @@ describe("managed Codex runtime", () => {
|
|
|
32
42
|
});
|
|
33
43
|
expect(run.mock.calls.map((call) => call[1])).toEqual([["--version"], ["app-server", "--help"]]);
|
|
34
44
|
});
|
|
35
|
-
it("
|
|
45
|
+
it("accepts explicit executables at or above the minimum stable version", async () => {
|
|
46
|
+
const outputs = [
|
|
47
|
+
`codex-cli ${CODEX_MINIMUM_VERSION}\n`,
|
|
48
|
+
`codex-cli ${CODEX_RUNTIME_VERSION}\n`,
|
|
49
|
+
];
|
|
50
|
+
for (const output of outputs) {
|
|
51
|
+
const root = await temporaryRoot();
|
|
52
|
+
const executable = await fakeExecutable(resolve(root, "codex"));
|
|
53
|
+
await expect(resolveCodexRuntime({
|
|
54
|
+
dataDir: resolve(root, "data"),
|
|
55
|
+
target: "darwin-arm64",
|
|
56
|
+
environment: { AGENT_CODEX_BIN: executable, PATH: "" },
|
|
57
|
+
platform: "darwin",
|
|
58
|
+
dependencies: {
|
|
59
|
+
run: async (_command, args) => ({
|
|
60
|
+
stdout: args[0] === "--version" ? output : "app-server help\n",
|
|
61
|
+
stderr: "",
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
64
|
+
})).resolves.toMatchObject({ executable, source: "explicit" });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
it("rejects an explicit executable below the minimum instead of silently replacing it", async () => {
|
|
36
68
|
const root = await temporaryRoot();
|
|
37
69
|
const executable = await fakeExecutable(resolve(root, "codex"));
|
|
38
70
|
await expect(resolveCodexRuntime({
|
|
@@ -41,9 +73,22 @@ describe("managed Codex runtime", () => {
|
|
|
41
73
|
environment: { AGENT_CODEX_BIN: executable, PATH: "" },
|
|
42
74
|
platform: "darwin",
|
|
43
75
|
dependencies: {
|
|
44
|
-
run: async () => ({ stdout: "codex-cli 0.
|
|
76
|
+
run: async () => ({ stdout: "codex-cli 0.152.9\n", stderr: "" }),
|
|
45
77
|
},
|
|
46
|
-
})).rejects.toThrow(
|
|
78
|
+
})).rejects.toThrow(`requires >=${CODEX_MINIMUM_VERSION}`);
|
|
79
|
+
});
|
|
80
|
+
it("rejects prerelease or otherwise unparseable version output", async () => {
|
|
81
|
+
const root = await temporaryRoot();
|
|
82
|
+
const executable = await fakeExecutable(resolve(root, "codex"));
|
|
83
|
+
await expect(resolveCodexRuntime({
|
|
84
|
+
dataDir: resolve(root, "data"),
|
|
85
|
+
target: "darwin-arm64",
|
|
86
|
+
environment: { AGENT_CODEX_BIN: executable, PATH: "" },
|
|
87
|
+
platform: "darwin",
|
|
88
|
+
dependencies: {
|
|
89
|
+
run: async () => ({ stdout: "codex-cli 0.150.0-alpha.1\n", stderr: "" }),
|
|
90
|
+
},
|
|
91
|
+
})).rejects.toThrow("Unable to parse a supported stable Codex version");
|
|
47
92
|
});
|
|
48
93
|
it("skips an incompatible PATH executable and reuses the managed runtime", async () => {
|
|
49
94
|
const root = await temporaryRoot();
|
|
@@ -52,7 +97,7 @@ describe("managed Codex runtime", () => {
|
|
|
52
97
|
const managed = await fakeExecutable(managedCodexBinaryCandidates(managedRoot, "darwin-arm64")[0]);
|
|
53
98
|
const run = vi.fn(async (command, args) => ({
|
|
54
99
|
stdout: args[0] === "--version"
|
|
55
|
-
? command === global ? "codex-cli 0.152.0\n" :
|
|
100
|
+
? command === global ? "codex-cli 0.152.0\n" : `codex-cli ${CODEX_RUNTIME_VERSION}\n`
|
|
56
101
|
: "help\n",
|
|
57
102
|
stderr: "",
|
|
58
103
|
}));
|
|
@@ -65,6 +110,22 @@ describe("managed Codex runtime", () => {
|
|
|
65
110
|
})).resolves.toEqual({ executable: managed, version: CODEX_RUNTIME_VERSION, source: "managed" });
|
|
66
111
|
expect(run.mock.calls.some((call) => call[1].includes("install"))).toBe(false);
|
|
67
112
|
});
|
|
113
|
+
it("reuses a qualified PATH executable without installing", async () => {
|
|
114
|
+
const root = await temporaryRoot();
|
|
115
|
+
const global = await fakeExecutable(resolve(root, "bin", "codex"));
|
|
116
|
+
const run = vi.fn(async (_command, args) => ({
|
|
117
|
+
stdout: args[0] === "--version" ? `codex-cli ${CODEX_RUNTIME_VERSION}\n` : "help\n",
|
|
118
|
+
stderr: "",
|
|
119
|
+
}));
|
|
120
|
+
await expect(resolveCodexRuntime({
|
|
121
|
+
dataDir: resolve(root, "data"),
|
|
122
|
+
target: "darwin-arm64",
|
|
123
|
+
environment: { PATH: resolve(root, "bin") },
|
|
124
|
+
platform: "darwin",
|
|
125
|
+
dependencies: { run },
|
|
126
|
+
})).resolves.toEqual({ executable: global, version: CODEX_RUNTIME_VERSION, source: "global" });
|
|
127
|
+
expect(run.mock.calls.some((call) => call[1].includes("install"))).toBe(false);
|
|
128
|
+
});
|
|
68
129
|
it("installs the locked official package into a versioned runtime directory", async () => {
|
|
69
130
|
const root = await temporaryRoot();
|
|
70
131
|
const npmExecPath = await fakeExecutable(resolve(root, "npm-cli.js"));
|
|
@@ -80,7 +141,7 @@ describe("managed Codex runtime", () => {
|
|
|
80
141
|
return { stdout: "installed", stderr: "" };
|
|
81
142
|
}
|
|
82
143
|
return {
|
|
83
|
-
stdout: args[0] === "--version" ?
|
|
144
|
+
stdout: args[0] === "--version" ? `codex-cli ${CODEX_RUNTIME_VERSION}\n` : "help\n",
|
|
84
145
|
stderr: "",
|
|
85
146
|
};
|
|
86
147
|
});
|
|
@@ -110,7 +171,7 @@ describe("managed Codex runtime", () => {
|
|
|
110
171
|
return { stdout: "installed", stderr: "" };
|
|
111
172
|
}
|
|
112
173
|
return {
|
|
113
|
-
stdout: args[0] === "--version" ?
|
|
174
|
+
stdout: args[0] === "--version" ? `codex-cli ${CODEX_RUNTIME_VERSION}\n` : "help\n",
|
|
114
175
|
stderr: "",
|
|
115
176
|
};
|
|
116
177
|
};
|
|
@@ -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.23";
|
|
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": {
|
|
@@ -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.23" },
|
|
26
26
|
signal: options.signal,
|
|
27
27
|
});
|
|
28
28
|
if (response.ok) {
|
|
@@ -4,6 +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.23"; ./install-agentroam.ps1
|
|
7
8
|
$AgentRoamVersionRequest = if ($env:AGENTROAM_VERSION) { $env:AGENTROAM_VERSION } else { "preview" }
|
|
8
9
|
$AgentRoamVersion = "pending-version"
|
|
9
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.23 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.23",
|
|
4
4
|
"description": "Zero-install mobile remote terminal and file console",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,8 +26,8 @@
|
|
|
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.
|
|
29
|
+
"agentroam-runtime-darwin-arm64": "0.2.0-preview.23",
|
|
30
|
+
"agentroam-runtime-win32-x64": "0.2.0-preview.23",
|
|
31
31
|
"agentroam-cloudflared-darwin-arm64": "0.2.0-preview.20",
|
|
32
32
|
"agentroam-cloudflared-win32-x64": "0.2.0-preview.20",
|
|
33
33
|
"agentroam-tui-darwin-arm64": "0.2.0-preview.20",
|