Files
openclaw/scripts/run-node-watch-paths.mjs
2026-05-29 09:45:14 +01:00

82 lines
3.0 KiB
JavaScript

import path from "node:path";
import {
BUNDLED_PLUGIN_PATH_PREFIX,
BUNDLED_PLUGIN_ROOT_DIR,
} from "./lib/bundled-plugin-paths.mjs";
const RUN_NODE_PACKAGE_SOURCE_ROOTS = [
// Root runtime code imports these package sources through tsconfig aliases,
// while pnpm dev/watch still runs the root dist entrypoint. Treat them like
// src/ so edits restart the same process that consumes them.
"packages/gateway-client/src",
"packages/gateway-protocol/src",
"packages/net-policy/src",
];
export const runNodeSourceRoots = [
"src",
...RUN_NODE_PACKAGE_SOURCE_ROOTS,
BUNDLED_PLUGIN_ROOT_DIR,
];
export const runNodeConfigFiles = ["tsconfig.json", "package.json", "tsdown.config.ts"];
export const runNodeWatchedPaths = [...runNodeSourceRoots, ...runNodeConfigFiles];
export const extensionRestartMetadataFiles = new Set(["openclaw.plugin.json", "package.json"]);
const ignoredRunNodeRepoPathPatterns = [
/^extensions\/[^/]+\/src\/host\/.+\/\.bundle\.hash$/u,
/^extensions\/[^/]+\/src\/host\/.+\/[^/]+\.bundle\.js$/u,
];
const extensionSourceFilePattern = /\.(?:[cm]?[jt]sx?)$/;
export const normalizeRunNodePath = (filePath) => String(filePath ?? "").replaceAll("\\", "/");
const isIgnoredSourcePath = (relativePath) => {
const normalizedPath = normalizeRunNodePath(relativePath);
return (
normalizedPath.endsWith(".test.ts") ||
normalizedPath.endsWith(".test.tsx") ||
normalizedPath.endsWith("test-helpers.ts")
);
};
const isBuildRelevantSourcePath = (relativePath) => {
const normalizedPath = normalizeRunNodePath(relativePath);
return extensionSourceFilePattern.test(normalizedPath) && !isIgnoredSourcePath(normalizedPath);
};
const isRestartRelevantExtensionPath = (relativePath) => {
const normalizedPath = normalizeRunNodePath(relativePath);
if (extensionRestartMetadataFiles.has(path.posix.basename(normalizedPath))) {
return true;
}
return isBuildRelevantSourcePath(normalizedPath);
};
const isRelevantRunNodePath = (repoPath, isRelevantBundledPluginPath) => {
const normalizedPath = normalizeRunNodePath(repoPath).replace(/^\.\/+/, "");
if (ignoredRunNodeRepoPathPatterns.some((pattern) => pattern.test(normalizedPath))) {
return false;
}
if (runNodeConfigFiles.includes(normalizedPath)) {
return true;
}
if (normalizedPath.startsWith("src/")) {
return !isIgnoredSourcePath(normalizedPath.slice("src/".length));
}
for (const sourceRoot of RUN_NODE_PACKAGE_SOURCE_ROOTS) {
if (normalizedPath.startsWith(`${sourceRoot}/`)) {
return !isIgnoredSourcePath(normalizedPath.slice(sourceRoot.length + 1));
}
}
if (normalizedPath.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
return isRelevantBundledPluginPath(normalizedPath.slice(BUNDLED_PLUGIN_PATH_PREFIX.length));
}
return false;
};
export const isBuildRelevantRunNodePath = (repoPath) =>
isRelevantRunNodePath(repoPath, isBuildRelevantSourcePath);
export const isRestartRelevantRunNodePath = (repoPath) =>
isRelevantRunNodePath(repoPath, isRestartRelevantExtensionPath);