Files
openclaw/scripts/lib/package-dist-inventory-contract.mts
Peter Steinberger 3a37a12d89 fix(package): prevent installs from deleting validated runtime assets (#129724)
* fix(package): enforce postinstall inventory parity

Reject packages whose pruning inventory omits shipped dist assets, and verify every installed bundled plugin artifact survives postinstall. Preserve lifecycle-free historical package compatibility.

Fixes #129722

* fix(package): keep parity helper private

* refactor(package): deduplicate SDK artifact requirements
2026-08-25 21:14:39 -07:00

32 lines
1.0 KiB
TypeScript

export const PACKAGE_DIST_INVENTORY_RELATIVE_PATH = "dist/postinstall-inventory.json";
export const PACKAGE_INSTALL_GUARD_RELATIVE_PATH = "dist/openclaw-install-guard";
const UNINVENTORIED_PACKAGE_DIST_PATHS = new Set([
PACKAGE_DIST_INVENTORY_RELATIVE_PATH,
PACKAGE_INSTALL_GUARD_RELATIVE_PATH,
]);
export function comparePackageDistInventory(params: {
files: Iterable<string>;
inventory: Iterable<string>;
}): {
packagedFilesMissingFromInventory: string[];
inventoryEntriesMissingFromPackage: string[];
} {
const files = new Set(
[...params.files]
.map((entry) => entry.replace(/\\/gu, "/"))
.filter((entry) => entry.startsWith("dist/")),
);
const inventory = new Set([...params.inventory].map((entry) => entry.replace(/\\/gu, "/")));
return {
packagedFilesMissingFromInventory: [...files]
.filter((entry) => !UNINVENTORIED_PACKAGE_DIST_PATHS.has(entry) && !inventory.has(entry))
.toSorted(),
inventoryEntriesMissingFromPackage: [...inventory]
.filter((entry) => !files.has(entry))
.toSorted(),
};
}