diff --git a/nix/checks/openclaw-package-contents.nix b/nix/checks/openclaw-package-contents.nix index 2b13b12..de37b1b 100644 --- a/nix/checks/openclaw-package-contents.nix +++ b/nix/checks/openclaw-package-contents.nix @@ -1,6 +1,7 @@ { lib, stdenv, + nodejs_22, openclawGateway, }: @@ -17,6 +18,7 @@ stdenv.mkDerivation { }; doCheck = true; + nativeCheckInputs = [ nodejs_22 ]; checkPhase = "${../scripts/check-package-contents.sh}"; installPhase = "${../scripts/empty-install.sh}"; } diff --git a/nix/lib/openclaw-gateway-common.nix b/nix/lib/openclaw-gateway-common.nix index 0a9fe46..7384f1e 100644 --- a/nix/lib/openclaw-gateway-common.nix +++ b/nix/lib/openclaw-gateway-common.nix @@ -40,6 +40,7 @@ let "releaseVersion" "applyPublicSurfaceHardlinksPatch" "applySkipPluginAutoEnableNixModePatch" + "publicSurfaceHardlinksPatch" "fsSafeSource" ]; @@ -59,6 +60,8 @@ let fetchFromGitHub sourceFetch; fsSafeSource = if sourceInfo ? fsSafeSource then fetchFromGitHub sourceInfo.fsSafeSource else null; + publicSurfaceHardlinksPatch = + sourceInfo.publicSurfaceHardlinksPatch or ../patches/allow-package-public-surface-hardlinks.patch; nodeAddonApi = import ../packages/node-addon-api.nix { inherit stdenv fetchurl; }; @@ -88,7 +91,7 @@ let PATCH_BUNDLED_RUNTIME_DEPS_SCRIPT = "${../patches/stage-bundled-plugin-runtime-deps.mjs}"; PATCH_PUBLIC_SURFACE_HARDLINKS = if sourceInfo.applyPublicSurfaceHardlinksPatch or true then - "${../patches/allow-package-public-surface-hardlinks.patch}" + "${publicSurfaceHardlinksPatch}" else ""; PATCH_SKIP_PLUGIN_AUTO_ENABLE_NIX_MODE = diff --git a/nix/patches/allow-package-public-surface-hardlinks-open-root.patch b/nix/patches/allow-package-public-surface-hardlinks-open-root.patch new file mode 100644 index 0000000..3eb6d3f --- /dev/null +++ b/nix/patches/allow-package-public-surface-hardlinks-open-root.patch @@ -0,0 +1,20 @@ +diff --git a/src/plugins/public-surface-loader.ts b/src/plugins/public-surface-loader.ts +index 5f6f939..b8d27c8 100644 +--- a/src/plugins/public-surface-loader.ts ++++ b/src/plugins/public-surface-loader.ts +@@ -133,8 +133,12 @@ export function loadBundledPluginPublicArtifactModuleSync(para +- const opened = openRootFileSync({ ++ const packageRoot = path.resolve(OPENCLAW_PACKAGE_ROOT); ++ const resolvedModulePath = path.resolve(location.modulePath); ++ const isPackagePublicSurface = resolvedModulePath.startsWith(`${packageRoot}${path.sep}`); ++ ++ const opened = openRootFileSync({ + absolutePath: location.modulePath, + rootPath: location.boundaryRoot, + boundaryLabel: + location.boundaryRoot === OPENCLAW_PACKAGE_ROOT ? "OpenClaw package root" : "plugin root", +- rejectHardlinks: true, ++ rejectHardlinks: !isPackagePublicSurface, + }); + if (!opened.ok) { + throw new Error( diff --git a/nix/patches/allow-package-public-surface-hardlinks.patch b/nix/patches/allow-package-public-surface-hardlinks.patch index 56c7802..e4826ed 100644 --- a/nix/patches/allow-package-public-surface-hardlinks.patch +++ b/nix/patches/allow-package-public-surface-hardlinks.patch @@ -1,13 +1,20 @@ diff --git a/src/plugins/public-surface-loader.ts b/src/plugins/public-surface-loader.ts -index 5f6f939..8cb550f 100644 +index 1f5b5ab..a08ef8a 100644 --- a/src/plugins/public-surface-loader.ts +++ b/src/plugins/public-surface-loader.ts -@@ -128,7 +128,7 @@ export function loadBundledPluginPublicArtifactModuleSync(para +@@ -124,8 +124,12 @@ export function loadBundledPluginPublicArtifactModuleSync(para +- const opened = openBoundaryFileSync({ ++ const packageRoot = path.resolve(OPENCLAW_PACKAGE_ROOT); ++ const resolvedModulePath = path.resolve(location.modulePath); ++ const isPackagePublicSurface = resolvedModulePath.startsWith(`${packageRoot}${path.sep}`); ++ ++ const opened = openBoundaryFileSync({ + absolutePath: location.modulePath, rootPath: location.boundaryRoot, boundaryLabel: location.boundaryRoot === OPENCLAW_PACKAGE_ROOT ? "OpenClaw package root" : "plugin root", - rejectHardlinks: true, -+ rejectHardlinks: location.boundaryRoot !== OPENCLAW_PACKAGE_ROOT, ++ rejectHardlinks: !isPackagePublicSurface, }); if (!opened.ok) { throw new Error( diff --git a/nix/scripts/check-package-contents.sh b/nix/scripts/check-package-contents.sh index 8bc77bc..e2309bf 100755 --- a/nix/scripts/check-package-contents.sh +++ b/nix/scripts/check-package-contents.sh @@ -36,7 +36,7 @@ require_path "${root}/node_modules/hasown" require_path "${root}/node_modules/combined-stream" public_surface_loader="$( - grep -Rsl "function loadBundledPluginPublicArtifactModuleSync" "${root}/dist" | head -1 + find "${root}/dist" -name "*.js" -type f -exec grep -sl "function loadBundledPluginPublicArtifactModuleSync" {} + | head -1 )" if [ -z "$public_surface_loader" ]; then echo "Missing bundled plugin public surface loader" >&2 @@ -46,6 +46,28 @@ if grep -q "rejectHardlinks: true" "$public_surface_loader"; then echo "Bundled plugin public surface loader still rejects hardlinked package files" >&2 exit 1 fi +export PUBLIC_SURFACE_LOADER="$public_surface_loader" +node --input-type=module <<'NODE' +import { pathToFileURL } from "node:url"; + +const loaderPath = process.env.PUBLIC_SURFACE_LOADER; +if (!loaderPath) { + throw new Error("PUBLIC_SURFACE_LOADER is not set"); +} + +const loader = await import(pathToFileURL(loaderPath).href); +const loadBundledPluginPublicArtifactModuleSync = + loader.loadBundledPluginPublicArtifactModuleSync ?? loader.t; + +if (typeof loadBundledPluginPublicArtifactModuleSync !== "function") { + throw new Error("Bundled plugin public surface loader export not found"); +} + +loadBundledPluginPublicArtifactModuleSync({ + dirName: "openai", + artifactBasename: "provider-policy-api.js", +}); +NODE require_js_alias_target() { alias="$1" diff --git a/nix/sources/openclaw-dogfood-source.nix b/nix/sources/openclaw-dogfood-source.nix index 4bf5b86..ab5837f 100644 --- a/nix/sources/openclaw-dogfood-source.nix +++ b/nix/sources/openclaw-dogfood-source.nix @@ -12,5 +12,6 @@ hash = "sha256-jndOOSSFROyrK4RiwAsJfUuCJTj7qbmmm4Qz8BqtJ/c="; }; + publicSurfaceHardlinksPatch = ../patches/allow-package-public-surface-hardlinks-open-root.patch; applySkipPluginAutoEnableNixModePatch = false; }