From 5fe1d257a4fd8e9384c76f4b2e03bbd9b1fd5bbb Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 21 Feb 2026 02:25:00 -0500 Subject: [PATCH] Chore: harden A2UI bundle dependency resolution --- CHANGELOG.md | 1 + .../Tools/CanvasA2UI/rolldown.config.mjs | 34 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e5f62a606c..7c2942c74a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai - Security/Unused Dependencies: remove unused root devDependencies `@lit/context` and `@lit-labs/signals` flagged as unused by Knip dead-code reports. (#22471) Thanks @vincentkoc. - Security/Unused Dependencies: remove unused root dependency `lit` that is now scoped to `ui/` package dependencies. (#22471) Thanks @vincentkoc. - Security/Unused Dependencies: remove unused root dependencies `long` and `rolldown`; keep A2UI bundling functional by falling back to `pnpm dlx rolldown` when the binary is not locally installed. (#22481) Thanks @vincentkoc. +- Security/Unused Dependencies: harden A2UI bundling dependency resolution by resolving `lit`, `@lit/context`, `@lit-labs/signals`, and `signal-utils` from UI workspace or repo-root dependency locations to tolerate Docker layout differences without root-only assumptions. (#22504) Thanks @vincentkoc. - Security/Unused Dependencies: fix A2UI bundle resolution for removed root `lit` deps by resolving `lit`, `@lit/context`, `@lit-labs/signals`, and `signal-utils` from UI workspace dependencies in `rolldown.config.mjs` during bundling. (#22481) Thanks @vincentkoc. - Security/Unused Dependencies: simplify `canvas-a2ui` bundling script by removing temporary vendored `node_modules` symlink logic now that `ui` workspace dependencies are explicit. (#22481) Thanks @vincentkoc. - Security/Unused Dependencies: remove unused `@microsoft/agents-hosting-express` and `@microsoft/agents-hosting-extensions-teams` from `extensions/msteams` because current code only uses `@microsoft/agents-hosting`. Thanks @vincentkoc. diff --git a/apps/shared/OpenClawKit/Tools/CanvasA2UI/rolldown.config.mjs b/apps/shared/OpenClawKit/Tools/CanvasA2UI/rolldown.config.mjs index 98256ced706..7466e719e83 100644 --- a/apps/shared/OpenClawKit/Tools/CanvasA2UI/rolldown.config.mjs +++ b/apps/shared/OpenClawKit/Tools/CanvasA2UI/rolldown.config.mjs @@ -1,4 +1,5 @@ import path from "node:path"; +import { existsSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { defineConfig } from "rolldown"; @@ -17,6 +18,26 @@ const outputFile = path.resolve( const a2uiLitDist = path.resolve(repoRoot, "vendor/a2ui/renderers/lit/dist/src"); const a2uiThemeContext = path.resolve(a2uiLitDist, "0.8/ui/context/theme.js"); +const uiNodeModules = path.resolve(uiRoot, "node_modules"); +const repoNodeModules = path.resolve(repoRoot, "node_modules"); + +function resolveUiDependency(moduleId) { + const candidates = [ + path.resolve(uiNodeModules, moduleId), + path.resolve(repoNodeModules, moduleId), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) { + return candidate; + } + } + + const fallbackCandidates = candidates.join(", "); + throw new Error( + `A2UI bundle config cannot resolve ${moduleId}. Checked: ${fallbackCandidates}. ` + + "Keep dependency installed in ui workspace or repo root before bundling.", + ); +} export default defineConfig({ input: fromHere("bootstrap.js"), @@ -29,12 +50,13 @@ export default defineConfig({ "@a2ui/lit": path.resolve(a2uiLitDist, "index.js"), "@a2ui/lit/ui": path.resolve(a2uiLitDist, "0.8/ui/ui.js"), "@openclaw/a2ui-theme-context": a2uiThemeContext, - "@lit/context": path.resolve(uiRoot, "node_modules/@lit/context/index.js"), - "@lit/context/": path.resolve(uiRoot, "node_modules/@lit/context/"), - "@lit-labs/signals": path.resolve(uiRoot, "node_modules/@lit-labs/signals/index.js"), - "@lit-labs/signals/": path.resolve(uiRoot, "node_modules/@lit-labs/signals/"), - lit: path.resolve(uiRoot, "node_modules/lit/index.js"), - "lit/": path.resolve(uiRoot, "node_modules/lit/"), + "@lit/context": resolveUiDependency("@lit/context"), + "@lit/context/": resolveUiDependency("@lit/context/"), + "@lit-labs/signals": resolveUiDependency("@lit-labs/signals"), + "@lit-labs/signals/": resolveUiDependency("@lit-labs/signals/"), + lit: resolveUiDependency("lit"), + "lit/": resolveUiDependency("lit/"), + "signal-utils": resolveUiDependency("signal-utils"), }, }, output: {