@openclaw/lobster 2026.2.22 → 2026.2.24
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/package.json +1 -1
- package/src/lobster-tool.test.ts +10 -48
- package/src/test-helpers.ts +56 -0
- package/src/windows-spawn.test.ts +16 -49
package/package.json
CHANGED
package/src/lobster-tool.test.ts
CHANGED
|
@@ -5,6 +5,12 @@ import path from "node:path";
|
|
|
5
5
|
import { PassThrough } from "node:stream";
|
|
6
6
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
7
|
import type { OpenClawPluginApi, OpenClawPluginToolContext } from "../../../src/plugins/types.js";
|
|
8
|
+
import {
|
|
9
|
+
createWindowsCmdShimFixture,
|
|
10
|
+
restorePlatformPathEnv,
|
|
11
|
+
setProcessPlatform,
|
|
12
|
+
snapshotPlatformPathEnv,
|
|
13
|
+
} from "./test-helpers.js";
|
|
8
14
|
|
|
9
15
|
const spawnState = vi.hoisted(() => ({
|
|
10
16
|
queue: [] as Array<{ stdout: string; stderr?: string; exitCode?: number }>,
|
|
@@ -57,20 +63,9 @@ function fakeCtx(overrides: Partial<OpenClawPluginToolContext> = {}): OpenClawPl
|
|
|
57
63
|
};
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
function setProcessPlatform(platform: NodeJS.Platform) {
|
|
61
|
-
Object.defineProperty(process, "platform", {
|
|
62
|
-
value: platform,
|
|
63
|
-
configurable: true,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
66
|
describe("lobster plugin tool", () => {
|
|
68
67
|
let tempDir = "";
|
|
69
|
-
const
|
|
70
|
-
const originalPath = process.env.PATH;
|
|
71
|
-
const originalPathAlt = process.env.Path;
|
|
72
|
-
const originalPathExt = process.env.PATHEXT;
|
|
73
|
-
const originalPathExtAlt = process.env.Pathext;
|
|
68
|
+
const originalProcessState = snapshotPlatformPathEnv();
|
|
74
69
|
|
|
75
70
|
beforeAll(async () => {
|
|
76
71
|
({ createLobsterTool } = await import("./lobster-tool.js"));
|
|
@@ -79,29 +74,7 @@ describe("lobster plugin tool", () => {
|
|
|
79
74
|
});
|
|
80
75
|
|
|
81
76
|
afterEach(() => {
|
|
82
|
-
|
|
83
|
-
Object.defineProperty(process, "platform", originalPlatform);
|
|
84
|
-
}
|
|
85
|
-
if (originalPath === undefined) {
|
|
86
|
-
delete process.env.PATH;
|
|
87
|
-
} else {
|
|
88
|
-
process.env.PATH = originalPath;
|
|
89
|
-
}
|
|
90
|
-
if (originalPathAlt === undefined) {
|
|
91
|
-
delete process.env.Path;
|
|
92
|
-
} else {
|
|
93
|
-
process.env.Path = originalPathAlt;
|
|
94
|
-
}
|
|
95
|
-
if (originalPathExt === undefined) {
|
|
96
|
-
delete process.env.PATHEXT;
|
|
97
|
-
} else {
|
|
98
|
-
process.env.PATHEXT = originalPathExt;
|
|
99
|
-
}
|
|
100
|
-
if (originalPathExtAlt === undefined) {
|
|
101
|
-
delete process.env.Pathext;
|
|
102
|
-
} else {
|
|
103
|
-
process.env.Pathext = originalPathExtAlt;
|
|
104
|
-
}
|
|
77
|
+
restorePlatformPathEnv(originalProcessState);
|
|
105
78
|
});
|
|
106
79
|
|
|
107
80
|
afterAll(async () => {
|
|
@@ -156,17 +129,6 @@ describe("lobster plugin tool", () => {
|
|
|
156
129
|
});
|
|
157
130
|
};
|
|
158
131
|
|
|
159
|
-
const createWindowsShimFixture = async (params: {
|
|
160
|
-
shimPath: string;
|
|
161
|
-
scriptPath: string;
|
|
162
|
-
scriptToken: string;
|
|
163
|
-
}) => {
|
|
164
|
-
await fs.mkdir(path.dirname(params.scriptPath), { recursive: true });
|
|
165
|
-
await fs.mkdir(path.dirname(params.shimPath), { recursive: true });
|
|
166
|
-
await fs.writeFile(params.scriptPath, "module.exports = {};\n", "utf8");
|
|
167
|
-
await fs.writeFile(params.shimPath, `@echo off\r\n"${params.scriptToken}" %*\r\n`, "utf8");
|
|
168
|
-
};
|
|
169
|
-
|
|
170
132
|
it("runs lobster and returns parsed envelope in details", async () => {
|
|
171
133
|
spawnState.queue.push({
|
|
172
134
|
stdout: JSON.stringify({
|
|
@@ -281,10 +243,10 @@ describe("lobster plugin tool", () => {
|
|
|
281
243
|
setProcessPlatform("win32");
|
|
282
244
|
const shimScriptPath = path.join(tempDir, "shim-dist", "lobster-cli.cjs");
|
|
283
245
|
const shimPath = path.join(tempDir, "shim-bin", "lobster.cmd");
|
|
284
|
-
await
|
|
246
|
+
await createWindowsCmdShimFixture({
|
|
285
247
|
shimPath,
|
|
286
248
|
scriptPath: shimScriptPath,
|
|
287
|
-
|
|
249
|
+
shimLine: `"%dp0%\\..\\shim-dist\\lobster-cli.cjs" %*`,
|
|
288
250
|
});
|
|
289
251
|
process.env.PATHEXT = ".CMD;.EXE";
|
|
290
252
|
process.env.PATH = `${path.dirname(shimPath)};${process.env.PATH ?? ""}`;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
type PathEnvKey = "PATH" | "Path" | "PATHEXT" | "Pathext";
|
|
5
|
+
|
|
6
|
+
const PATH_ENV_KEYS = ["PATH", "Path", "PATHEXT", "Pathext"] as const;
|
|
7
|
+
|
|
8
|
+
export type PlatformPathEnvSnapshot = {
|
|
9
|
+
platformDescriptor: PropertyDescriptor | undefined;
|
|
10
|
+
env: Record<PathEnvKey, string | undefined>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export function setProcessPlatform(platform: NodeJS.Platform): void {
|
|
14
|
+
Object.defineProperty(process, "platform", {
|
|
15
|
+
value: platform,
|
|
16
|
+
configurable: true,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function snapshotPlatformPathEnv(): PlatformPathEnvSnapshot {
|
|
21
|
+
return {
|
|
22
|
+
platformDescriptor: Object.getOwnPropertyDescriptor(process, "platform"),
|
|
23
|
+
env: {
|
|
24
|
+
PATH: process.env.PATH,
|
|
25
|
+
Path: process.env.Path,
|
|
26
|
+
PATHEXT: process.env.PATHEXT,
|
|
27
|
+
Pathext: process.env.Pathext,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function restorePlatformPathEnv(snapshot: PlatformPathEnvSnapshot): void {
|
|
33
|
+
if (snapshot.platformDescriptor) {
|
|
34
|
+
Object.defineProperty(process, "platform", snapshot.platformDescriptor);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const key of PATH_ENV_KEYS) {
|
|
38
|
+
const value = snapshot.env[key];
|
|
39
|
+
if (value === undefined) {
|
|
40
|
+
delete process.env[key];
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
process.env[key] = value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function createWindowsCmdShimFixture(params: {
|
|
48
|
+
shimPath: string;
|
|
49
|
+
scriptPath: string;
|
|
50
|
+
shimLine: string;
|
|
51
|
+
}): Promise<void> {
|
|
52
|
+
await fs.mkdir(path.dirname(params.scriptPath), { recursive: true });
|
|
53
|
+
await fs.mkdir(path.dirname(params.shimPath), { recursive: true });
|
|
54
|
+
await fs.writeFile(params.scriptPath, "module.exports = {};\n", "utf8");
|
|
55
|
+
await fs.writeFile(params.shimPath, `@echo off\r\n${params.shimLine}\r\n`, "utf8");
|
|
56
|
+
}
|
|
@@ -2,22 +2,17 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
createWindowsCmdShimFixture,
|
|
7
|
+
restorePlatformPathEnv,
|
|
8
|
+
setProcessPlatform,
|
|
9
|
+
snapshotPlatformPathEnv,
|
|
10
|
+
} from "./test-helpers.js";
|
|
5
11
|
import { resolveWindowsLobsterSpawn } from "./windows-spawn.js";
|
|
6
12
|
|
|
7
|
-
function setProcessPlatform(platform: NodeJS.Platform) {
|
|
8
|
-
Object.defineProperty(process, "platform", {
|
|
9
|
-
value: platform,
|
|
10
|
-
configurable: true,
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
13
|
describe("resolveWindowsLobsterSpawn", () => {
|
|
15
14
|
let tempDir = "";
|
|
16
|
-
const
|
|
17
|
-
const originalPath = process.env.PATH;
|
|
18
|
-
const originalPathAlt = process.env.Path;
|
|
19
|
-
const originalPathExt = process.env.PATHEXT;
|
|
20
|
-
const originalPathExtAlt = process.env.Pathext;
|
|
15
|
+
const originalProcessState = snapshotPlatformPathEnv();
|
|
21
16
|
|
|
22
17
|
beforeEach(async () => {
|
|
23
18
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-lobster-win-spawn-"));
|
|
@@ -25,29 +20,7 @@ describe("resolveWindowsLobsterSpawn", () => {
|
|
|
25
20
|
});
|
|
26
21
|
|
|
27
22
|
afterEach(async () => {
|
|
28
|
-
|
|
29
|
-
Object.defineProperty(process, "platform", originalPlatform);
|
|
30
|
-
}
|
|
31
|
-
if (originalPath === undefined) {
|
|
32
|
-
delete process.env.PATH;
|
|
33
|
-
} else {
|
|
34
|
-
process.env.PATH = originalPath;
|
|
35
|
-
}
|
|
36
|
-
if (originalPathAlt === undefined) {
|
|
37
|
-
delete process.env.Path;
|
|
38
|
-
} else {
|
|
39
|
-
process.env.Path = originalPathAlt;
|
|
40
|
-
}
|
|
41
|
-
if (originalPathExt === undefined) {
|
|
42
|
-
delete process.env.PATHEXT;
|
|
43
|
-
} else {
|
|
44
|
-
process.env.PATHEXT = originalPathExt;
|
|
45
|
-
}
|
|
46
|
-
if (originalPathExtAlt === undefined) {
|
|
47
|
-
delete process.env.Pathext;
|
|
48
|
-
} else {
|
|
49
|
-
process.env.Pathext = originalPathExtAlt;
|
|
50
|
-
}
|
|
23
|
+
restorePlatformPathEnv(originalProcessState);
|
|
51
24
|
if (tempDir) {
|
|
52
25
|
await fs.rm(tempDir, { recursive: true, force: true });
|
|
53
26
|
tempDir = "";
|
|
@@ -57,14 +30,11 @@ describe("resolveWindowsLobsterSpawn", () => {
|
|
|
57
30
|
it("unwraps cmd shim with %dp0% token", async () => {
|
|
58
31
|
const scriptPath = path.join(tempDir, "shim-dist", "lobster-cli.cjs");
|
|
59
32
|
const shimPath = path.join(tempDir, "shim", "lobster.cmd");
|
|
60
|
-
await
|
|
61
|
-
await fs.mkdir(path.dirname(shimPath), { recursive: true });
|
|
62
|
-
await fs.writeFile(scriptPath, "module.exports = {};\n", "utf8");
|
|
63
|
-
await fs.writeFile(
|
|
33
|
+
await createWindowsCmdShimFixture({
|
|
64
34
|
shimPath,
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
);
|
|
35
|
+
scriptPath,
|
|
36
|
+
shimLine: `"%dp0%\\..\\shim-dist\\lobster-cli.cjs" %*`,
|
|
37
|
+
});
|
|
68
38
|
|
|
69
39
|
const target = resolveWindowsLobsterSpawn(shimPath, ["run", "noop"], process.env);
|
|
70
40
|
expect(target.command).toBe(process.execPath);
|
|
@@ -75,14 +45,11 @@ describe("resolveWindowsLobsterSpawn", () => {
|
|
|
75
45
|
it("unwraps cmd shim with %~dp0% token", async () => {
|
|
76
46
|
const scriptPath = path.join(tempDir, "shim-dist", "lobster-cli.cjs");
|
|
77
47
|
const shimPath = path.join(tempDir, "shim", "lobster.cmd");
|
|
78
|
-
await
|
|
79
|
-
await fs.mkdir(path.dirname(shimPath), { recursive: true });
|
|
80
|
-
await fs.writeFile(scriptPath, "module.exports = {};\n", "utf8");
|
|
81
|
-
await fs.writeFile(
|
|
48
|
+
await createWindowsCmdShimFixture({
|
|
82
49
|
shimPath,
|
|
83
|
-
|
|
84
|
-
"
|
|
85
|
-
);
|
|
50
|
+
scriptPath,
|
|
51
|
+
shimLine: `"%~dp0%\\..\\shim-dist\\lobster-cli.cjs" %*`,
|
|
52
|
+
});
|
|
86
53
|
|
|
87
54
|
const target = resolveWindowsLobsterSpawn(shimPath, ["run", "noop"], process.env);
|
|
88
55
|
expect(target.command).toBe(process.execPath);
|