mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix(cli): scope packaged compile cache
This commit is contained in:
@@ -28,6 +28,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- CLI/update: scope packaged Node compile caches by OpenClaw version and install metadata, so global installs no longer reuse stale compiled chunks after package updates. Thanks @pashpashpash.
|
||||
- Plugin SDK/testing: lazy-load TypeScript from the plugin test-contract runtime and add release checks for critical SDK contract entrypoint imports and bundle size, so published packages fail preflight before shipping ESM-incompatible or oversized contract helpers. Thanks @vincentkoc.
|
||||
- CLI/browser: preserve parent flags while lazy-loading browser subcommands, so `openclaw browser --json open` and `openclaw browser --json tabs` keep machine-readable output after reparsing. Fixes #74574. Thanks @devintegeritsm.
|
||||
- Plugins/runtime-deps: add `openclaw plugins deps` inspection and repair with script-free package-manager defaults shared across plugin installers, so operators can repair missing bundled runtime deps without corrupting JSON output or blocking unrelated conflict-free deps. Thanks @vincentkoc.
|
||||
|
||||
77
openclaw.mjs
77
openclaw.mjs
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { existsSync, readFileSync, statSync } from "node:fs";
|
||||
import { access } from "node:fs/promises";
|
||||
import module from "node:module";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const MIN_NODE_MAJOR = 22;
|
||||
@@ -46,6 +48,41 @@ const isSourceCheckoutLauncher = () =>
|
||||
const isNodeCompileCacheDisabled = () => process.env.NODE_DISABLE_COMPILE_CACHE !== undefined;
|
||||
const isNodeCompileCacheRequested = () =>
|
||||
process.env.NODE_COMPILE_CACHE !== undefined && !isNodeCompileCacheDisabled();
|
||||
const sanitizeCompileCachePathSegment = (value) => {
|
||||
const normalized = value.replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
|
||||
return normalized.length > 0 ? normalized : "unknown";
|
||||
};
|
||||
const readPackageVersion = () => {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
|
||||
if (typeof parsed?.version === "string" && parsed.version.trim().length > 0) {
|
||||
return parsed.version;
|
||||
}
|
||||
} catch {
|
||||
// Fall through to an install-metadata-only cache key.
|
||||
}
|
||||
return "unknown";
|
||||
};
|
||||
const resolvePackagedCompileCacheDirectory = () => {
|
||||
const packageJsonUrl = new URL("./package.json", import.meta.url);
|
||||
const version = sanitizeCompileCachePathSegment(readPackageVersion());
|
||||
let installMarker = "no-package-json";
|
||||
try {
|
||||
const stat = statSync(packageJsonUrl);
|
||||
installMarker = `${Math.trunc(stat.mtimeMs)}-${stat.size}`;
|
||||
} catch {
|
||||
// Package archives should always have package.json, but keep startup best-effort.
|
||||
}
|
||||
const baseDirectory = isNodeCompileCacheRequested()
|
||||
? process.env.NODE_COMPILE_CACHE
|
||||
: path.join(os.tmpdir(), "node-compile-cache");
|
||||
return path.join(
|
||||
baseDirectory,
|
||||
"openclaw",
|
||||
version,
|
||||
sanitizeCompileCachePathSegment(installMarker),
|
||||
);
|
||||
};
|
||||
|
||||
const respawnWithoutCompileCacheIfNeeded = () => {
|
||||
if (!isSourceCheckoutLauncher()) {
|
||||
@@ -79,10 +116,46 @@ const respawnWithoutCompileCacheIfNeeded = () => {
|
||||
|
||||
respawnWithoutCompileCacheIfNeeded();
|
||||
|
||||
const respawnWithPackagedCompileCacheIfNeeded = () => {
|
||||
if (isSourceCheckoutLauncher() || isNodeCompileCacheDisabled()) {
|
||||
return false;
|
||||
}
|
||||
if (process.env.OPENCLAW_PACKAGED_COMPILE_CACHE_RESPAWNED === "1") {
|
||||
return false;
|
||||
}
|
||||
const currentDirectory = module.getCompileCacheDir?.();
|
||||
if (!currentDirectory) {
|
||||
return false;
|
||||
}
|
||||
const desiredDirectory = resolvePackagedCompileCacheDirectory();
|
||||
if (path.resolve(currentDirectory) === path.resolve(desiredDirectory)) {
|
||||
return false;
|
||||
}
|
||||
const env = {
|
||||
...process.env,
|
||||
NODE_COMPILE_CACHE: desiredDirectory,
|
||||
OPENCLAW_PACKAGED_COMPILE_CACHE_RESPAWNED: "1",
|
||||
};
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
[...process.execArgv, fileURLToPath(import.meta.url), ...process.argv.slice(2)],
|
||||
{
|
||||
stdio: "inherit",
|
||||
env,
|
||||
},
|
||||
);
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
process.exit(result.status ?? 1);
|
||||
};
|
||||
|
||||
respawnWithPackagedCompileCacheIfNeeded();
|
||||
|
||||
// https://nodejs.org/api/module.html#module-compile-cache
|
||||
if (module.enableCompileCache && !isNodeCompileCacheDisabled() && !isSourceCheckoutLauncher()) {
|
||||
try {
|
||||
module.enableCompileCache();
|
||||
module.enableCompileCache(resolvePackagedCompileCacheDirectory());
|
||||
} catch {
|
||||
// Ignore errors
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { existsSync, mkdtempSync, mkdirSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { dirname, join } from "node:path";
|
||||
|
||||
export const WORKSPACE_TEMPLATE_PACK_PATHS = [
|
||||
"docs/reference/templates/AGENTS.md",
|
||||
@@ -23,6 +23,47 @@ const REQUIRED_BOOTSTRAP_WORKSPACE_FILES = [
|
||||
"BOOTSTRAP.md",
|
||||
];
|
||||
|
||||
export const WORKSPACE_BOOTSTRAP_SMOKE_TIMEOUT_MS = 15_000;
|
||||
const SAFE_UNIX_SMOKE_PATH = "/usr/bin:/bin";
|
||||
|
||||
export function createWorkspaceBootstrapSmokeEnv(env, homeDir, overrides = {}) {
|
||||
const allowlistedEnvEntries = [
|
||||
"TMPDIR",
|
||||
"TMP",
|
||||
"TEMP",
|
||||
"SystemRoot",
|
||||
"ComSpec",
|
||||
"PATHEXT",
|
||||
"WINDIR",
|
||||
];
|
||||
const windowsRoot = env.SystemRoot ?? env.WINDIR ?? "C:\\Windows";
|
||||
const nodeBinDir = dirname(process.execPath);
|
||||
const safePath =
|
||||
process.platform === "win32"
|
||||
? `${nodeBinDir};${windowsRoot}\\System32;${windowsRoot}`
|
||||
: `${nodeBinDir}:${SAFE_UNIX_SMOKE_PATH}`;
|
||||
|
||||
return {
|
||||
...Object.fromEntries(
|
||||
allowlistedEnvEntries.flatMap((key) => {
|
||||
const value = env[key];
|
||||
return typeof value === "string" && value.length > 0 ? [[key, value]] : [];
|
||||
}),
|
||||
),
|
||||
PATH: safePath,
|
||||
HOME: homeDir,
|
||||
USERPROFILE: homeDir,
|
||||
OPENCLAW_HOME: homeDir,
|
||||
OPENCLAW_NO_ONBOARD: "1",
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
AWS_EC2_METADATA_DISABLED: "true",
|
||||
AWS_SHARED_CREDENTIALS_FILE: join(homeDir, ".aws", "credentials"),
|
||||
AWS_CONFIG_FILE: join(homeDir, ".aws", "config"),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function collectMissingBootstrapWorkspaceFiles(workspaceDir) {
|
||||
return REQUIRED_BOOTSTRAP_WORKSPACE_FILES.filter(
|
||||
(filename) => !existsSync(join(workspaceDir, filename)),
|
||||
@@ -77,12 +118,8 @@ export function runInstalledWorkspaceBootstrapSmoke(params) {
|
||||
encoding: "utf8",
|
||||
maxBuffer: 1024 * 1024 * 16,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
env: {
|
||||
...process.env,
|
||||
HOME: homeDir,
|
||||
OPENCLAW_HOME: homeDir,
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
},
|
||||
timeout: WORKSPACE_BOOTSTRAP_SMOKE_TIMEOUT_MS,
|
||||
env: createWorkspaceBootstrapSmokeEnv(process.env, homeDir),
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join, resolve } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { COMPLETION_SKIP_PLUGIN_COMMANDS_ENV } from "../src/cli/completion-runtime.ts";
|
||||
import {
|
||||
isBundledRuntimeDepsInstallStagePath,
|
||||
LOCAL_BUILD_METADATA_DIST_PATHS,
|
||||
@@ -134,6 +135,12 @@ export const PACKED_CLI_SMOKE_COMMANDS = [
|
||||
["config", "schema"],
|
||||
["models", "list", "--provider", "amazon-bedrock"],
|
||||
] as const;
|
||||
export const PACKED_COMPLETION_SMOKE_ARGS = [
|
||||
"completion",
|
||||
"--write-state",
|
||||
"--shell",
|
||||
"zsh",
|
||||
] as const;
|
||||
|
||||
function collectBundledExtensions(): BundledExtension[] {
|
||||
const extensionsDir = resolve("extensions");
|
||||
@@ -318,6 +325,19 @@ export function createPackedCliSmokeEnv(
|
||||
};
|
||||
}
|
||||
|
||||
export function createPackedCompletionSmokeEnv(
|
||||
env: NodeJS.ProcessEnv,
|
||||
overrides: NodeJS.ProcessEnv = {},
|
||||
): NodeJS.ProcessEnv {
|
||||
return {
|
||||
...env,
|
||||
...overrides,
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
[COMPLETION_SKIP_PLUGIN_COMMANDS_ENV]: "1",
|
||||
};
|
||||
}
|
||||
|
||||
function runPackedBundledPluginPostinstall(packageRoot: string): void {
|
||||
execFileSync(process.execPath, [join(packageRoot, "scripts/postinstall-bundled-plugins.mjs")], {
|
||||
cwd: packageRoot,
|
||||
@@ -599,17 +619,14 @@ function runPackedBundledChannelEntrySmoke(): void {
|
||||
|
||||
execFileSync(
|
||||
process.execPath,
|
||||
[join(packageRoot, "openclaw.mjs"), "completion", "--write-state"],
|
||||
[join(packageRoot, "openclaw.mjs"), ...PACKED_COMPLETION_SMOKE_ARGS],
|
||||
{
|
||||
cwd: packageRoot,
|
||||
stdio: "inherit",
|
||||
env: {
|
||||
...process.env,
|
||||
env: createPackedCompletionSmokeEnv(process.env, {
|
||||
HOME: homeDir,
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
},
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { cleanupTempDirs, makeTempDir } from "../test/helpers/temp-dir.js";
|
||||
import {
|
||||
buildOpenClawCompileCacheRespawnPlan,
|
||||
isSourceCheckoutInstallRoot,
|
||||
resolveOpenClawCompileCacheDirectory,
|
||||
resolveEntryInstallRoot,
|
||||
shouldEnableOpenClawCompileCache,
|
||||
} from "./entry.compile-cache.js";
|
||||
@@ -54,6 +55,21 @@ describe("entry compile cache", () => {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("scopes packaged compile cache by package install metadata", async () => {
|
||||
const root = makeTempDir(tempDirs, "openclaw-compile-cache-package-key-");
|
||||
const packageJsonPath = path.join(root, "package.json");
|
||||
await fs.writeFile(packageJsonPath, '{"version":"2026.4.29"}\n', "utf8");
|
||||
|
||||
const directory = resolveOpenClawCompileCacheDirectory({
|
||||
env: { NODE_COMPILE_CACHE: path.join(root, ".node-cache") },
|
||||
installRoot: root,
|
||||
});
|
||||
|
||||
expect(directory).toContain(path.join(".node-cache", "openclaw"));
|
||||
expect(directory).toContain("2026.4.29");
|
||||
expect(path.basename(directory)).toMatch(/^\d+-\d+$/);
|
||||
});
|
||||
|
||||
it("builds a one-shot no-cache respawn plan when source checkout inherits NODE_COMPILE_CACHE", async () => {
|
||||
const root = makeTempDir(tempDirs, "openclaw-compile-cache-respawn-");
|
||||
await fs.mkdir(path.join(root, "src"), { recursive: true });
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { existsSync, readFileSync, statSync } from "node:fs";
|
||||
import { enableCompileCache, getCompileCacheDir } from "node:module";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
export function resolveEntryInstallRoot(entryFile: string): string {
|
||||
@@ -34,6 +35,55 @@ export function shouldEnableOpenClawCompileCache(params: {
|
||||
return !isSourceCheckoutInstallRoot(params.installRoot);
|
||||
}
|
||||
|
||||
function sanitizeCompileCachePathSegment(value: string): string {
|
||||
const normalized = value.replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
|
||||
return normalized.length > 0 ? normalized : "unknown";
|
||||
}
|
||||
|
||||
function readPackageVersion(packageJsonPath: string): string {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8")) as unknown;
|
||||
if (
|
||||
parsed &&
|
||||
typeof parsed === "object" &&
|
||||
"version" in parsed &&
|
||||
typeof parsed.version === "string" &&
|
||||
parsed.version.trim().length > 0
|
||||
) {
|
||||
return parsed.version;
|
||||
}
|
||||
} catch {
|
||||
// Fall through to an install-metadata-only cache key.
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
export function resolveOpenClawCompileCacheDirectory(params: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
installRoot: string;
|
||||
}): string {
|
||||
const env = params.env ?? process.env;
|
||||
const packageJsonPath = path.join(params.installRoot, "package.json");
|
||||
const version = sanitizeCompileCachePathSegment(readPackageVersion(packageJsonPath));
|
||||
let installMarker = "no-package-json";
|
||||
try {
|
||||
const stat = statSync(packageJsonPath);
|
||||
installMarker = `${Math.trunc(stat.mtimeMs)}-${stat.size}`;
|
||||
} catch {
|
||||
// Package archives should always have package.json, but keep startup best-effort.
|
||||
}
|
||||
const baseDirectory =
|
||||
env.NODE_COMPILE_CACHE && !isNodeCompileCacheDisabled(env)
|
||||
? env.NODE_COMPILE_CACHE
|
||||
: path.join(os.tmpdir(), "node-compile-cache");
|
||||
return path.join(
|
||||
baseDirectory,
|
||||
"openclaw",
|
||||
version,
|
||||
sanitizeCompileCachePathSegment(installMarker),
|
||||
);
|
||||
}
|
||||
|
||||
export type OpenClawCompileCacheRespawnPlan = {
|
||||
command: string;
|
||||
args: string[];
|
||||
@@ -107,7 +157,7 @@ export function enableOpenClawCompileCache(params: {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
enableCompileCache();
|
||||
enableCompileCache(resolveOpenClawCompileCacheDirectory(params));
|
||||
} catch {
|
||||
// Best-effort only; never block startup.
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ describe("openclaw launcher", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it("does not respawn packaged launchers when NODE_COMPILE_CACHE is configured", async () => {
|
||||
it("keeps compile cache enabled for packaged launchers when NODE_COMPILE_CACHE is configured", async () => {
|
||||
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
|
||||
await addCompileCacheProbe(fixtureRoot);
|
||||
|
||||
@@ -177,6 +177,30 @@ describe("openclaw launcher", () => {
|
||||
expect(result.stdout).toBe("cache:enabled;respawn:0");
|
||||
});
|
||||
|
||||
it("scopes packaged launcher compile cache inside configured cache roots", async () => {
|
||||
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
|
||||
await fs.writeFile(path.join(fixtureRoot, "package.json"), '{"version":"2026.4.29"}\n');
|
||||
await fs.writeFile(
|
||||
path.join(fixtureRoot, "dist", "entry.js"),
|
||||
[
|
||||
'import module from "node:module";',
|
||||
'process.stdout.write(module.getCompileCacheDir?.() ?? "cache:disabled");',
|
||||
].join("\n"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const result = spawnSync(process.execPath, [path.join(fixtureRoot, "openclaw.mjs")], {
|
||||
cwd: fixtureRoot,
|
||||
env: launcherEnv({
|
||||
NODE_COMPILE_CACHE: path.join(fixtureRoot, ".node-compile-cache"),
|
||||
}),
|
||||
encoding: "utf8",
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout).toContain(path.join(".node-compile-cache", "openclaw", "2026.4.29"));
|
||||
});
|
||||
|
||||
it("enables compile cache for packaged launchers", async () => {
|
||||
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
|
||||
await addCompileCacheProbe(fixtureRoot);
|
||||
|
||||
@@ -5,7 +5,10 @@ import { bundledDistPluginFile, bundledPluginFile } from "openclaw/plugin-sdk/te
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { listBundledPluginPackArtifacts } from "../scripts/lib/bundled-plugin-build-entries.mjs";
|
||||
import { listPluginSdkDistArtifacts } from "../scripts/lib/plugin-sdk-entries.mjs";
|
||||
import { WORKSPACE_TEMPLATE_PACK_PATHS } from "../scripts/lib/workspace-bootstrap-smoke.mjs";
|
||||
import {
|
||||
WORKSPACE_TEMPLATE_PACK_PATHS,
|
||||
createWorkspaceBootstrapSmokeEnv,
|
||||
} from "../scripts/lib/workspace-bootstrap-smoke.mjs";
|
||||
import { collectInstalledRootDependencyManifestErrors } from "../scripts/openclaw-npm-postpublish-verify.ts";
|
||||
import {
|
||||
collectAppcastSparkleVersionErrors,
|
||||
@@ -20,13 +23,16 @@ import {
|
||||
collectForbiddenPackPaths,
|
||||
collectMissingPackPaths,
|
||||
collectPackUnpackedSizeErrors,
|
||||
createPackedCompletionSmokeEnv,
|
||||
createPackedCliSmokeEnv,
|
||||
createPackedBundledPluginPostinstallEnv,
|
||||
MAX_CRITICAL_PLUGIN_SDK_ENTRYPOINT_BYTES,
|
||||
PACKED_CLI_SMOKE_COMMANDS,
|
||||
PACKED_COMPLETION_SMOKE_ARGS,
|
||||
packageNameFromSpecifier,
|
||||
resolveMissingPackBuildHint,
|
||||
} from "../scripts/release-check.ts";
|
||||
import { COMPLETION_SKIP_PLUGIN_COMMANDS_ENV } from "../src/cli/completion-runtime.ts";
|
||||
import {
|
||||
LOCAL_BUILD_METADATA_DIST_PATHS,
|
||||
PACKAGE_DIST_INVENTORY_RELATIVE_PATH,
|
||||
@@ -77,6 +83,10 @@ describe("packed CLI smoke", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps packed completion smoke scoped to one shell cache", () => {
|
||||
expect(PACKED_COMPLETION_SMOKE_ARGS).toEqual(["completion", "--write-state", "--shell", "zsh"]);
|
||||
});
|
||||
|
||||
it("builds a packed CLI smoke env with packaged-install guardrails", () => {
|
||||
expect(
|
||||
createPackedCliSmokeEnv(
|
||||
@@ -113,6 +123,61 @@ describe("packed CLI smoke", () => {
|
||||
OPENCLAW_STATE_DIR: "/tmp/smoke-state",
|
||||
});
|
||||
});
|
||||
|
||||
it("skips plugin command discovery during packed completion cache smoke", () => {
|
||||
expect(
|
||||
createPackedCompletionSmokeEnv(
|
||||
{
|
||||
PATH: "/usr/bin",
|
||||
OPENCLAW_COMPLETION_SKIP_PLUGIN_COMMANDS: "0",
|
||||
},
|
||||
{
|
||||
HOME: "/tmp/smoke-home",
|
||||
OPENCLAW_STATE_DIR: "/tmp/smoke-state",
|
||||
},
|
||||
),
|
||||
).toMatchObject({
|
||||
PATH: "/usr/bin",
|
||||
HOME: "/tmp/smoke-home",
|
||||
OPENCLAW_STATE_DIR: "/tmp/smoke-state",
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
[COMPLETION_SKIP_PLUGIN_COMMANDS_ENV]: "1",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("workspace bootstrap smoke", () => {
|
||||
it("runs with a sterile env instead of maintainer provider credentials", () => {
|
||||
expect(
|
||||
createWorkspaceBootstrapSmokeEnv(
|
||||
{
|
||||
PATH: "/usr/bin",
|
||||
HOME: "/tmp/original-home",
|
||||
TMPDIR: "/tmp/original-tmp",
|
||||
OPENAI_API_KEY: "real-secret",
|
||||
ANTHROPIC_API_KEY: "real-secret",
|
||||
OPENCLAW_CONFIG_PATH: "/tmp/leaky-config.json",
|
||||
},
|
||||
"/tmp/bootstrap-home",
|
||||
),
|
||||
).toEqual({
|
||||
PATH:
|
||||
process.platform === "win32"
|
||||
? `${dirname(process.execPath)};C:\\Windows\\System32;C:\\Windows`
|
||||
: `${dirname(process.execPath)}:/usr/bin:/bin`,
|
||||
HOME: "/tmp/bootstrap-home",
|
||||
USERPROFILE: "/tmp/bootstrap-home",
|
||||
OPENCLAW_HOME: "/tmp/bootstrap-home",
|
||||
TMPDIR: "/tmp/original-tmp",
|
||||
OPENCLAW_NO_ONBOARD: "1",
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
AWS_EC2_METADATA_DISABLED: "true",
|
||||
AWS_SHARED_CREDENTIALS_FILE: "/tmp/bootstrap-home/.aws/credentials",
|
||||
AWS_CONFIG_FILE: "/tmp/bootstrap-home/.aws/config",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("collectBundledExtensionManifestErrors", () => {
|
||||
|
||||
Reference in New Issue
Block a user