From 7a459045def4d874348c601804a1c71c86fa5554 Mon Sep 17 00:00:00 2001 From: Val Alexander <68980965+BunsDev@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:45:04 -0500 Subject: [PATCH] fix packaged control ui asset lookup (#53081) --- scripts/package-mac-app.sh | 11 +++++++++++ src/infra/control-ui-assets.test.ts | 10 ++++++++++ src/infra/control-ui-assets.ts | 3 ++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/scripts/package-mac-app.sh b/scripts/package-mac-app.sh index 35309048bfe..5c53d776217 100755 --- a/scripts/package-mac-app.sh +++ b/scripts/package-mac-app.sh @@ -246,6 +246,17 @@ else echo "WARN: model catalog missing at $MODEL_CATALOG_SRC (continuing)" >&2 fi +echo "📦 Copying Control UI assets" +CONTROL_UI_SRC="$ROOT_DIR/dist/control-ui" +CONTROL_UI_DEST="$APP_ROOT/Contents/Resources/control-ui" +if [ -d "$CONTROL_UI_SRC" ] && [ -f "$CONTROL_UI_SRC/index.html" ]; then + rm -rf "$CONTROL_UI_DEST" + cp -R "$CONTROL_UI_SRC" "$CONTROL_UI_DEST" +else + echo "ERROR: Control UI assets missing at $CONTROL_UI_SRC. Run pnpm ui:build first." >&2 + exit 1 +fi + echo "📦 Copying OpenClawKit resources" OPENCLAWKIT_BUNDLE="$(build_path_for_arch "$PRIMARY_ARCH")/$BUILD_CONFIG/OpenClawKit_OpenClawKit.bundle" if [ -d "$OPENCLAWKIT_BUNDLE" ]; then diff --git a/src/infra/control-ui-assets.test.ts b/src/infra/control-ui-assets.test.ts index ea834d093a8..e21ab5329ab 100644 --- a/src/infra/control-ui-assets.test.ts +++ b/src/infra/control-ui-assets.test.ts @@ -214,6 +214,16 @@ describe("control UI assets helpers (fs-mocked)", () => { expect(resolveControlUiRootSync({ moduleUrl })).toBe(uiDir); }); + it("prefers packaged app Control UI assets in Contents/Resources", () => { + const execPath = abs("fixtures/OpenClaw.app/Contents/MacOS/OpenClaw"); + const bundledUiDir = abs("fixtures/OpenClaw.app/Contents/Resources/control-ui"); + setFile(path.join(bundledUiDir, "index.html"), "\n"); + + state.realpaths.set(execPath, execPath); + + expect(resolveControlUiRootSync({ execPath })).toBe(bundledUiDir); + }); + it("resolves control-ui root for symlinked argv1 via realpath", () => { const pkgRoot = abs("fixtures/bun-global/openclaw"); const wrapperArgv1 = abs("fixtures/bin/openclaw"); diff --git a/src/infra/control-ui-assets.ts b/src/infra/control-ui-assets.ts index 90cdd7c31a2..c9f05ff1c34 100644 --- a/src/infra/control-ui-assets.ts +++ b/src/infra/control-ui-assets.ts @@ -215,7 +215,8 @@ export function resolveControlUiRootSync(opts: ControlUiRootResolveOptions = {}) cwd, }); - // Packaged app: control-ui lives alongside the executable. + // Packaged app: prefer bundled resources, then support legacy alongside-executable layout. + addCandidate(candidates, execDir ? path.join(execDir, "../Resources/control-ui") : null); addCandidate(candidates, execDir ? path.join(execDir, "control-ui") : null); if (moduleDir) { // dist/.js -> dist/control-ui