






















@@ -1277,13 +1277,44 @@ const shouldSkipWatchRuntimeSync = (deps, requirement) =>
12771277!hasMissingRequiredRuntimePostBuildOutput(deps);
1278127812791279const isGatewayClientCommand = (args) =>
1280-args[0] === "gateway" && (args[1] === "call" || args[1] === "status");
1280+(args[0] === "gateway" && (args[1] === "call" || args[1] === "status")) ||
1281+(args[0] === "agent" && !args.includes("--local"));
128112821282-const shouldUseExistingDistForGatewayClient = (deps, buildRequirement) =>
1283-buildRequirement.reason === "dirty_watched_tree" &&
1283+const shouldFastPathExistingDistForGatewayClient = (deps) =>
12841284isGatewayClientCommand(deps.args) &&
12851285deps.env.OPENCLAW_FORCE_BUILD !== "1" &&
1286-statMtime(deps.distEntry, deps.fs) != null;
1286+statMtime(deps.distEntry, deps.fs) != null &&
1287+canUseStampedGatewayClientDist(deps);
1288+1289+const canUseStampedGatewayClientDist = (deps) => {
1290+const currentHead = resolveGitHead(deps);
1291+if (!currentHead) {
1292+return false;
1293+}
1294+const buildStamp = readBuildStamp(deps);
1295+if (buildStamp.mtime == null || buildStamp.head !== currentHead) {
1296+return false;
1297+}
1298+for (const filePath of deps.configFiles) {
1299+const mtime = statMtime(filePath, deps.fs);
1300+if (mtime != null && mtime > buildStamp.mtime) {
1301+return false;
1302+}
1303+}
1304+if (hasMissingBuiltBundledPluginRuntimeEntryOutput(deps)) {
1305+return false;
1306+}
1307+const runtimeStamp = readRuntimePostBuildStamp(deps);
1308+if (
1309+runtimeStamp.mtime == null ||
1310+runtimeStamp.mtime < buildStamp.mtime ||
1311+runtimeStamp.head !== currentHead ||
1312+deps.env.OPENCLAW_FORCE_RUNTIME_POSTBUILD === "1"
1313+) {
1314+return false;
1315+}
1316+return !resolveRuntimePostBuildRequirement(deps).shouldSync;
1317+};
1287131812881319const isQaParityReportCommand = (args) => args[0] === "qa" && args[1] === "parity-report";
12891320const isQaCoverageReportCommand = (args) => args[0] === "qa" && args[1] === "coverage";
@@ -1374,16 +1405,13 @@ export async function runNodeMain(params = {}) {
1374140513751406try {
13761407let exitCode = 1;
1377-let buildRequirement = resolveBuildRequirement(deps);
1378-const useExistingGatewayClientDist = shouldUseExistingDistForGatewayClient(
1379-deps,
1380- buildRequirement,
1381-);
1408+if (shouldFastPathExistingDistForGatewayClient(deps)) {
1409+ exitCode = await runOpenClaw(deps);
1410+return await closeRunNodeOutputTee(deps, exitCode);
1411+}
1412+const buildRequirement = resolveBuildRequirement(deps);
13821413const useQaParityReportSource = shouldRunQaParityReportFromSource(deps, buildRequirement);
13831414const useQaCoverageReportSource = shouldRunQaCoverageReportFromSource(deps, buildRequirement);
1384-if (useExistingGatewayClientDist) {
1385-buildRequirement = { shouldBuild: false, reason: "gateway_client_existing_dist" };
1386-}
13871415if (useQaParityReportSource) {
13881416logRunner("Running QA parity report from source without rebuilding private QA dist.", deps);
13891417exitCode = await runQaParityReportFromSource(deps);
@@ -1395,26 +1423,24 @@ export async function runNodeMain(params = {}) {
13951423return await closeRunNodeOutputTee(deps, exitCode);
13961424}
13971425if (!buildRequirement.shouldBuild) {
1398-if (!useExistingGatewayClientDist) {
1399-const runtimePostBuildRequirement = resolveRuntimePostBuildRequirement(deps);
1400-if (
1401-runtimePostBuildRequirement.shouldSync &&
1402-!shouldSkipWatchRuntimeSync(deps, runtimePostBuildRequirement)
1403-) {
1404-const synced = await withRunNodeBuildLock(deps, async () => {
1405-const lockedRuntimePostBuildRequirement = resolveRuntimePostBuildRequirement(deps);
1406-if (!lockedRuntimePostBuildRequirement.shouldSync) {
1407-return true;
1408-}
1409-logRunner(
1410-`Syncing runtime artifacts (${lockedRuntimePostBuildRequirement.reason} - ${formatRuntimePostBuildReason(lockedRuntimePostBuildRequirement.reason)}).`,
1411-deps,
1412-);
1413-return await syncRuntimeArtifactsAndStamp(deps);
1414-});
1415-if (!synced) {
1416-return await closeRunNodeOutputTee(deps, 1);
1426+const runtimePostBuildRequirement = resolveRuntimePostBuildRequirement(deps);
1427+if (
1428+runtimePostBuildRequirement.shouldSync &&
1429+!shouldSkipWatchRuntimeSync(deps, runtimePostBuildRequirement)
1430+) {
1431+const synced = await withRunNodeBuildLock(deps, async () => {
1432+const lockedRuntimePostBuildRequirement = resolveRuntimePostBuildRequirement(deps);
1433+if (!lockedRuntimePostBuildRequirement.shouldSync) {
1434+return true;
14171435}
1436+logRunner(
1437+`Syncing runtime artifacts (${lockedRuntimePostBuildRequirement.reason} - ${formatRuntimePostBuildReason(lockedRuntimePostBuildRequirement.reason)}).`,
1438+deps,
1439+);
1440+return await syncRuntimeArtifactsAndStamp(deps);
1441+});
1442+if (!synced) {
1443+return await closeRunNodeOutputTee(deps, 1);
14181444}
14191445}
14201446exitCode = await runOpenClaw(deps);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。