



























@@ -1,9 +1,11 @@
11#!/usr/bin/env node
2233import { spawnSync } from "node:child_process";
4-import { existsSync, readFileSync } from "node:fs";
4+import { existsSync, readFileSync, statSync } from "node:fs";
55import { access } from "node:fs/promises";
66import module from "node:module";
7+import os from "node:os";
8+import path from "node:path";
79import { fileURLToPath } from "node:url";
810911const MIN_NODE_MAJOR = 22;
@@ -46,6 +48,41 @@ const isSourceCheckoutLauncher = () =>
4648const isNodeCompileCacheDisabled = () => process.env.NODE_DISABLE_COMPILE_CACHE !== undefined;
4749const isNodeCompileCacheRequested = () =>
4850process.env.NODE_COMPILE_CACHE !== undefined && !isNodeCompileCacheDisabled();
51+const sanitizeCompileCachePathSegment = (value) => {
52+const normalized = value.replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
53+return normalized.length > 0 ? normalized : "unknown";
54+};
55+const readPackageVersion = () => {
56+try {
57+const parsed = JSON.parse(readFileSync(new URL("./package.json", import.meta.url), "utf8"));
58+if (typeof parsed?.version === "string" && parsed.version.trim().length > 0) {
59+return parsed.version;
60+}
61+} catch {
62+// Fall through to an install-metadata-only cache key.
63+}
64+return "unknown";
65+};
66+const resolvePackagedCompileCacheDirectory = () => {
67+const packageJsonUrl = new URL("./package.json", import.meta.url);
68+const version = sanitizeCompileCachePathSegment(readPackageVersion());
69+let installMarker = "no-package-json";
70+try {
71+const stat = statSync(packageJsonUrl);
72+installMarker = `${Math.trunc(stat.mtimeMs)}-${stat.size}`;
73+} catch {
74+// Package archives should always have package.json, but keep startup best-effort.
75+}
76+const baseDirectory = isNodeCompileCacheRequested()
77+ ? process.env.NODE_COMPILE_CACHE
78+ : path.join(os.tmpdir(), "node-compile-cache");
79+return path.join(
80+baseDirectory,
81+"openclaw",
82+version,
83+sanitizeCompileCachePathSegment(installMarker),
84+);
85+};
49865087const respawnWithoutCompileCacheIfNeeded = () => {
5188if (!isSourceCheckoutLauncher()) {
@@ -79,10 +116,46 @@ const respawnWithoutCompileCacheIfNeeded = () => {
7911680117respawnWithoutCompileCacheIfNeeded();
81118119+const respawnWithPackagedCompileCacheIfNeeded = () => {
120+if (isSourceCheckoutLauncher() || isNodeCompileCacheDisabled()) {
121+return false;
122+}
123+if (process.env.OPENCLAW_PACKAGED_COMPILE_CACHE_RESPAWNED === "1") {
124+return false;
125+}
126+const currentDirectory = module.getCompileCacheDir?.();
127+if (!currentDirectory) {
128+return false;
129+}
130+const desiredDirectory = resolvePackagedCompileCacheDirectory();
131+if (path.resolve(currentDirectory) === path.resolve(desiredDirectory)) {
132+return false;
133+}
134+const env = {
135+ ...process.env,
136+NODE_COMPILE_CACHE: desiredDirectory,
137+OPENCLAW_PACKAGED_COMPILE_CACHE_RESPAWNED: "1",
138+};
139+const result = spawnSync(
140+process.execPath,
141+[...process.execArgv, fileURLToPath(import.meta.url), ...process.argv.slice(2)],
142+{
143+stdio: "inherit",
144+ env,
145+},
146+);
147+if (result.error) {
148+throw result.error;
149+}
150+process.exit(result.status ?? 1);
151+};
152+153+respawnWithPackagedCompileCacheIfNeeded();
154+82155// https://nodejs.org/api/module.html#module-compile-cache
83156if (module.enableCompileCache && !isNodeCompileCacheDisabled() && !isSourceCheckoutLauncher()) {
84157try {
85-module.enableCompileCache();
158+module.enableCompileCache(resolvePackagedCompileCacheDirectory());
86159} catch {
87160// Ignore errors
88161}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。