diff --git a/apps/.i18n/native-source.json b/apps/.i18n/native-source.json
index 4b924fe24e61..1375fb9ad9ba 100644
--- a/apps/.i18n/native-source.json
+++ b/apps/.i18n/native-source.json
@@ -15073,14 +15073,6 @@
"surface": "android",
"id": "native.android.709aff840be1f167"
},
- {
- "kind": "plist-string",
- "line": 8,
- "path": "apps/ios/ActivityWidget/Info.plist",
- "source": "OpenClaw Activity",
- "surface": "apple",
- "id": "native.apple.8f741d09cc1d5495"
- },
{
"kind": "ui-call",
"line": 18,
@@ -15201,14 +15193,6 @@
"surface": "apple",
"id": "native.apple.18d4f8a4eea7f930"
},
- {
- "kind": "plist-string",
- "line": 8,
- "path": "apps/ios/ShareExtension/Info.plist",
- "source": "OpenClaw Share",
- "surface": "apple",
- "id": "native.apple.9168fcd110c3019a"
- },
{
"kind": "conditional-branch",
"line": 236,
diff --git a/apps/ios/ActivityWidget/ar.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/ar.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/ar.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/ar.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/de.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/de.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/de.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/de.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/es.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/es.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/es.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/es.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/fa.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/fa.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/fa.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/fa.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/fr.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/fr.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/fr.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/fr.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/hi.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/hi.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/hi.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/hi.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/id.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/id.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/id.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/id.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/it.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/it.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/it.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/it.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/ja.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/ja.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/ja.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/ja.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/ko.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/ko.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/ko.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/ko.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/nl.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/nl.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/nl.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/nl.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/pl.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/pl.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/pl.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/pl.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/pt-BR.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/pt-BR.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/pt-BR.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/pt-BR.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/ru.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/ru.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/ru.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/ru.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/sv.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/sv.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/sv.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/sv.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/th.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/th.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/th.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/th.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/tr.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/tr.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/tr.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/tr.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/uk.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/uk.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/uk.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/uk.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/vi.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/vi.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/vi.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/vi.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/zh-Hans.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/zh-Hans.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/zh-Hans.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/zh-Hans.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ActivityWidget/zh-Hant.lproj/InfoPlist.strings b/apps/ios/ActivityWidget/zh-Hant.lproj/InfoPlist.strings
index 85fde909ccc8..8b137891791f 100644
--- a/apps/ios/ActivityWidget/zh-Hant.lproj/InfoPlist.strings
+++ b/apps/ios/ActivityWidget/zh-Hant.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Activity";
+
diff --git a/apps/ios/ShareExtension/ar.lproj/InfoPlist.strings b/apps/ios/ShareExtension/ar.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/ar.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/ar.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/de.lproj/InfoPlist.strings b/apps/ios/ShareExtension/de.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/de.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/de.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/es.lproj/InfoPlist.strings b/apps/ios/ShareExtension/es.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/es.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/es.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/fa.lproj/InfoPlist.strings b/apps/ios/ShareExtension/fa.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/fa.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/fa.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/fr.lproj/InfoPlist.strings b/apps/ios/ShareExtension/fr.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/fr.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/fr.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/hi.lproj/InfoPlist.strings b/apps/ios/ShareExtension/hi.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/hi.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/hi.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/id.lproj/InfoPlist.strings b/apps/ios/ShareExtension/id.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/id.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/id.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/it.lproj/InfoPlist.strings b/apps/ios/ShareExtension/it.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/it.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/it.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/ja.lproj/InfoPlist.strings b/apps/ios/ShareExtension/ja.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/ja.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/ja.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/ko.lproj/InfoPlist.strings b/apps/ios/ShareExtension/ko.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/ko.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/ko.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/nl.lproj/InfoPlist.strings b/apps/ios/ShareExtension/nl.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/nl.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/nl.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/pl.lproj/InfoPlist.strings b/apps/ios/ShareExtension/pl.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/pl.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/pl.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/pt-BR.lproj/InfoPlist.strings b/apps/ios/ShareExtension/pt-BR.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/pt-BR.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/pt-BR.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/ru.lproj/InfoPlist.strings b/apps/ios/ShareExtension/ru.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/ru.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/ru.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/sv.lproj/InfoPlist.strings b/apps/ios/ShareExtension/sv.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/sv.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/sv.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/th.lproj/InfoPlist.strings b/apps/ios/ShareExtension/th.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/th.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/th.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/tr.lproj/InfoPlist.strings b/apps/ios/ShareExtension/tr.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/tr.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/tr.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/uk.lproj/InfoPlist.strings b/apps/ios/ShareExtension/uk.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/uk.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/uk.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/vi.lproj/InfoPlist.strings b/apps/ios/ShareExtension/vi.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/vi.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/vi.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/zh-Hans.lproj/InfoPlist.strings b/apps/ios/ShareExtension/zh-Hans.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/zh-Hans.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/zh-Hans.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/ShareExtension/zh-Hant.lproj/InfoPlist.strings b/apps/ios/ShareExtension/zh-Hant.lproj/InfoPlist.strings
index 20e0bdb147c3..8b137891791f 100644
--- a/apps/ios/ShareExtension/zh-Hant.lproj/InfoPlist.strings
+++ b/apps/ios/ShareExtension/zh-Hant.lproj/InfoPlist.strings
@@ -1 +1 @@
-"CFBundleDisplayName" = "OpenClaw Share";
+
diff --git a/apps/ios/Sources/Info.plist b/apps/ios/Sources/Info.plist
index b4f03acc8321..d38f8231741a 100644
--- a/apps/ios/Sources/Info.plist
+++ b/apps/ios/Sources/Info.plist
@@ -9,7 +9,7 @@
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
- $(OPENCLAW_APP_DISPLAY_NAME)
+ OpenClaw
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIconName
diff --git a/apps/ios/Sources/ar.lproj/InfoPlist.strings b/apps/ios/Sources/ar.lproj/InfoPlist.strings
index 838ce2c5a8df..0e3c530b11aa 100644
--- a/apps/ios/Sources/ar.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/ar.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "يستخدم OpenClaw تقويماتك لعرض الأحداث وسياق الجدولة عند تفعيل الوصول إلى التقويم.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/de.lproj/InfoPlist.strings b/apps/ios/Sources/de.lproj/InfoPlist.strings
index b86d40499756..d2169c480e39 100644
--- a/apps/ios/Sources/de.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/de.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw verwendet Ihre Kalender, um Ereignisse und Planungskontext anzuzeigen, wenn Sie den Kalenderzugriff aktivieren.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/es.lproj/InfoPlist.strings b/apps/ios/Sources/es.lproj/InfoPlist.strings
index 57f71f74efe8..dfd06e740a8f 100644
--- a/apps/ios/Sources/es.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/es.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw usa tus calendarios para mostrar eventos y contexto de programación cuando activas el acceso al calendario.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/fa.lproj/InfoPlist.strings b/apps/ios/Sources/fa.lproj/InfoPlist.strings
index b1283cdc64eb..fb18b9213afe 100644
--- a/apps/ios/Sources/fa.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/fa.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw از تقویمهای شما استفاده میکند تا وقتی دسترسی به تقویم را فعال میکنید، رویدادها و زمینهٔ زمانبندی را نشان دهد.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/fr.lproj/InfoPlist.strings b/apps/ios/Sources/fr.lproj/InfoPlist.strings
index 9dccf0d4c1bd..a18dbd76cd98 100644
--- a/apps/ios/Sources/fr.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/fr.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw utilise vos calendriers pour afficher les événements et le contexte de planification lorsque vous activez l’accès au calendrier.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/hi.lproj/InfoPlist.strings b/apps/ios/Sources/hi.lproj/InfoPlist.strings
index 0abc633c6821..158f6cbabb88 100644
--- a/apps/ios/Sources/hi.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/hi.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "जब आप कैलेंडर एक्सेस सक्षम करते हैं, तो OpenClaw इवेंट और शेड्यूलिंग संदर्भ दिखाने के लिए आपके कैलेंडर का उपयोग करता है.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/id.lproj/InfoPlist.strings b/apps/ios/Sources/id.lproj/InfoPlist.strings
index 96f54d25da48..84c65fb7023a 100644
--- a/apps/ios/Sources/id.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/id.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw menggunakan kalender Anda untuk menampilkan acara dan konteks penjadwalan saat Anda mengaktifkan akses kalender.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/it.lproj/InfoPlist.strings b/apps/ios/Sources/it.lproj/InfoPlist.strings
index d338d7732762..88636261d628 100644
--- a/apps/ios/Sources/it.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/it.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw usa i tuoi calendari per mostrare eventi e contesto di pianificazione quando abiliti l'accesso al calendario.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/ja.lproj/InfoPlist.strings b/apps/ios/Sources/ja.lproj/InfoPlist.strings
index de497d0898b1..7d43aa5ebed3 100644
--- a/apps/ios/Sources/ja.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/ja.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClawは、カレンダーへのアクセスを有効にしたときに、イベントとスケジュールのコンテキストを表示するためにカレンダーを使用します。";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/ko.lproj/InfoPlist.strings b/apps/ios/Sources/ko.lproj/InfoPlist.strings
index 0b5afe50d6fc..223792605e45 100644
--- a/apps/ios/Sources/ko.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/ko.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "캘린더 접근을 활성화하면 OpenClaw가 캘린더를 사용하여 이벤트와 일정 컨텍스트를 표시합니다.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/nl.lproj/InfoPlist.strings b/apps/ios/Sources/nl.lproj/InfoPlist.strings
index 43a121270031..324362f43ab5 100644
--- a/apps/ios/Sources/nl.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/nl.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw gebruikt je agenda’s om gebeurtenissen en planningscontext te tonen wanneer je agendatoegang inschakelt.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/pl.lproj/InfoPlist.strings b/apps/ios/Sources/pl.lproj/InfoPlist.strings
index 4c2572fe3dab..85402261c2eb 100644
--- a/apps/ios/Sources/pl.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/pl.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw używa Twoich kalendarzy do wyświetlania wydarzeń i kontekstu planowania, gdy włączysz dostęp do kalendarza.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/pt-BR.lproj/InfoPlist.strings b/apps/ios/Sources/pt-BR.lproj/InfoPlist.strings
index ea48ce050697..54964a9854d4 100644
--- a/apps/ios/Sources/pt-BR.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/pt-BR.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "O OpenClaw usa seus calendários para mostrar eventos e contexto de agendamento quando você ativa o acesso ao calendário.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/ru.lproj/InfoPlist.strings b/apps/ios/Sources/ru.lproj/InfoPlist.strings
index bf989875ab05..9c64ccca2199 100644
--- a/apps/ios/Sources/ru.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/ru.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw использует ваши календари, чтобы показывать события и контекст расписания, когда вы включаете доступ к календарю.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/sv.lproj/InfoPlist.strings b/apps/ios/Sources/sv.lproj/InfoPlist.strings
index d7eec5ec0795..11bdd82a5d2a 100644
--- a/apps/ios/Sources/sv.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/sv.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw använder dina kalendrar för att visa händelser och schemaläggningssammanhang när du aktiverar kalenderåtkomst.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/th.lproj/InfoPlist.strings b/apps/ios/Sources/th.lproj/InfoPlist.strings
index 206a1760c0ad..6b86eeb65f75 100644
--- a/apps/ios/Sources/th.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/th.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw ใช้ปฏิทินของคุณเพื่อแสดงกิจกรรมและบริบทการจัดกำหนดการเมื่อคุณเปิดใช้งานการเข้าถึงปฏิทิน";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/tr.lproj/InfoPlist.strings b/apps/ios/Sources/tr.lproj/InfoPlist.strings
index dede337c925c..13172c117ced 100644
--- a/apps/ios/Sources/tr.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/tr.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw, takvim erişimini etkinleştirdiğinizde etkinlikleri ve planlama bağlamını göstermek için takvimlerinizi kullanır.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/uk.lproj/InfoPlist.strings b/apps/ios/Sources/uk.lproj/InfoPlist.strings
index e6f94a08115d..7e1b54474acf 100644
--- a/apps/ios/Sources/uk.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/uk.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw використовує ваші календарі, щоб показувати події та контекст планування, коли ви надаєте доступ до календаря.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/vi.lproj/InfoPlist.strings b/apps/ios/Sources/vi.lproj/InfoPlist.strings
index 55be62688c70..20c031cf9013 100644
--- a/apps/ios/Sources/vi.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/vi.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw sử dụng lịch của bạn để hiển thị sự kiện và ngữ cảnh lên lịch khi bạn bật quyền truy cập lịch.";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/zh-Hans.lproj/InfoPlist.strings b/apps/ios/Sources/zh-Hans.lproj/InfoPlist.strings
index 8f389ac2ab0e..cfae48f272f3 100644
--- a/apps/ios/Sources/zh-Hans.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/zh-Hans.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "当你启用日历访问权限时,OpenClaw 会使用你的日历来显示事件和日程安排上下文。";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/Sources/zh-Hant.lproj/InfoPlist.strings b/apps/ios/Sources/zh-Hant.lproj/InfoPlist.strings
index f7da9dff1bee..51359394701e 100644
--- a/apps/ios/Sources/zh-Hant.lproj/InfoPlist.strings
+++ b/apps/ios/Sources/zh-Hant.lproj/InfoPlist.strings
@@ -1,4 +1,3 @@
-"CFBundleDisplayName" = "$(OPENCLAW_APP_DISPLAY_NAME)";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
"NSCalendarsFullAccessUsageDescription" = "OpenClaw 會在你啟用行事曆存取權限時,使用你的行事曆來顯示事件與排程情境。";
/* OpenClaw source: "OpenClaw uses your calendars to show events and scheduling context when you enable calendar access." */
diff --git a/apps/ios/WatchApp/ar.lproj/InfoPlist.strings b/apps/ios/WatchApp/ar.lproj/InfoPlist.strings
index 1609e0803a7b..0aaf64d59f32 100644
--- a/apps/ios/WatchApp/ar.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/ar.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "يربط OpenClaw ساعة Apple Watch هذه مباشرةً بـ Gateway الخاص بك على الشبكات المحلية الموثوقة.";
diff --git a/apps/ios/WatchApp/de.lproj/InfoPlist.strings b/apps/ios/WatchApp/de.lproj/InfoPlist.strings
index 0cb24a7b1029..6480c34f420e 100644
--- a/apps/ios/WatchApp/de.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/de.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw verbindet diese Apple Watch in vertrauenswürdigen lokalen Netzwerken direkt mit Ihrem Gateway.";
diff --git a/apps/ios/WatchApp/es.lproj/InfoPlist.strings b/apps/ios/WatchApp/es.lproj/InfoPlist.strings
index c784984b9ed1..099adc2615bc 100644
--- a/apps/ios/WatchApp/es.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/es.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw conecta este Apple Watch directamente a tu Gateway en redes locales de confianza.";
diff --git a/apps/ios/WatchApp/fa.lproj/InfoPlist.strings b/apps/ios/WatchApp/fa.lproj/InfoPlist.strings
index f3a211554e3e..aed5b047bf9b 100644
--- a/apps/ios/WatchApp/fa.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/fa.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw این Apple Watch را در شبکههای محلی مورد اعتماد مستقیماً به Gateway شما متصل میکند.";
diff --git a/apps/ios/WatchApp/fr.lproj/InfoPlist.strings b/apps/ios/WatchApp/fr.lproj/InfoPlist.strings
index d9210d8c7383..50bc85467499 100644
--- a/apps/ios/WatchApp/fr.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/fr.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw connecte cette Apple Watch directement à votre Gateway sur les réseaux locaux de confiance.";
diff --git a/apps/ios/WatchApp/hi.lproj/InfoPlist.strings b/apps/ios/WatchApp/hi.lproj/InfoPlist.strings
index 98e852773315..83ca100488b4 100644
--- a/apps/ios/WatchApp/hi.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/hi.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw इस Apple Watch को विश्वसनीय लोकल नेटवर्क पर सीधे आपके Gateway से कनेक्ट करता है।";
diff --git a/apps/ios/WatchApp/id.lproj/InfoPlist.strings b/apps/ios/WatchApp/id.lproj/InfoPlist.strings
index 7db156181b7a..254f18b764b9 100644
--- a/apps/ios/WatchApp/id.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/id.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw menyambungkan Apple Watch ini langsung ke Gateway Anda di jaringan lokal tepercaya.";
diff --git a/apps/ios/WatchApp/it.lproj/InfoPlist.strings b/apps/ios/WatchApp/it.lproj/InfoPlist.strings
index e0011a9c6fb2..2cee5a88c3de 100644
--- a/apps/ios/WatchApp/it.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/it.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw connette questo Apple Watch direttamente al tuo Gateway su reti locali attendibili.";
diff --git a/apps/ios/WatchApp/ja.lproj/InfoPlist.strings b/apps/ios/WatchApp/ja.lproj/InfoPlist.strings
index 22aecad88cc6..605819077fa2 100644
--- a/apps/ios/WatchApp/ja.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/ja.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw は信頼できるローカルネットワーク上で、この Apple Watch を Gateway に直接接続します。";
diff --git a/apps/ios/WatchApp/ko.lproj/InfoPlist.strings b/apps/ios/WatchApp/ko.lproj/InfoPlist.strings
index 21ef63bf0ec4..17c01d5b7872 100644
--- a/apps/ios/WatchApp/ko.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/ko.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw는 신뢰할 수 있는 로컬 네트워크에서 이 Apple Watch를 Gateway에 직접 연결합니다.";
diff --git a/apps/ios/WatchApp/nl.lproj/InfoPlist.strings b/apps/ios/WatchApp/nl.lproj/InfoPlist.strings
index 1ef6fb2cbbe2..715ed267089b 100644
--- a/apps/ios/WatchApp/nl.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/nl.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw verbindt deze Apple Watch rechtstreeks met je Gateway op vertrouwde lokale netwerken.";
diff --git a/apps/ios/WatchApp/pl.lproj/InfoPlist.strings b/apps/ios/WatchApp/pl.lproj/InfoPlist.strings
index 584ed04b2807..e65362062ec6 100644
--- a/apps/ios/WatchApp/pl.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/pl.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw łączy ten Apple Watch bezpośrednio z Twoim Gateway w zaufanych sieciach lokalnych.";
diff --git a/apps/ios/WatchApp/pt-BR.lproj/InfoPlist.strings b/apps/ios/WatchApp/pt-BR.lproj/InfoPlist.strings
index 1d04320951ca..bff19ee619b9 100644
--- a/apps/ios/WatchApp/pt-BR.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/pt-BR.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "O OpenClaw conecta este Apple Watch diretamente ao seu Gateway em redes locais confiáveis.";
diff --git a/apps/ios/WatchApp/ru.lproj/InfoPlist.strings b/apps/ios/WatchApp/ru.lproj/InfoPlist.strings
index 710b171527a5..c31eaa9a03af 100644
--- a/apps/ios/WatchApp/ru.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/ru.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw подключает эти Apple Watch напрямую к вашему Gateway в доверенных локальных сетях.";
diff --git a/apps/ios/WatchApp/sv.lproj/InfoPlist.strings b/apps/ios/WatchApp/sv.lproj/InfoPlist.strings
index 2c7ea8afc2c1..022f767620b5 100644
--- a/apps/ios/WatchApp/sv.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/sv.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw ansluter denna Apple Watch direkt till din Gateway på betrodda lokala nätverk.";
diff --git a/apps/ios/WatchApp/th.lproj/InfoPlist.strings b/apps/ios/WatchApp/th.lproj/InfoPlist.strings
index 88875c47fa8b..4343e8a84715 100644
--- a/apps/ios/WatchApp/th.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/th.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw เชื่อมต่อ Apple Watch นี้เข้ากับ Gateway ของคุณโดยตรงบนเครือข่ายในพื้นที่ที่เชื่อถือได้";
diff --git a/apps/ios/WatchApp/tr.lproj/InfoPlist.strings b/apps/ios/WatchApp/tr.lproj/InfoPlist.strings
index af4444a6fcc3..425c3e2da8f4 100644
--- a/apps/ios/WatchApp/tr.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/tr.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw, bu Apple Watch'u güvenilir yerel ağlarda doğrudan Gateway'inize bağlar.";
diff --git a/apps/ios/WatchApp/uk.lproj/InfoPlist.strings b/apps/ios/WatchApp/uk.lproj/InfoPlist.strings
index 997b437303fe..cd71b583bd36 100644
--- a/apps/ios/WatchApp/uk.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/uk.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw підключає цей Apple Watch безпосередньо до вашого Gateway в довірених локальних мережах.";
diff --git a/apps/ios/WatchApp/vi.lproj/InfoPlist.strings b/apps/ios/WatchApp/vi.lproj/InfoPlist.strings
index 79d78d369e29..8f33e3e3260a 100644
--- a/apps/ios/WatchApp/vi.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/vi.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw kết nối Apple Watch này trực tiếp với Gateway của bạn trên các mạng cục bộ đáng tin cậy.";
diff --git a/apps/ios/WatchApp/zh-Hans.lproj/InfoPlist.strings b/apps/ios/WatchApp/zh-Hans.lproj/InfoPlist.strings
index 56aced421b2b..3a0cf65ba81a 100644
--- a/apps/ios/WatchApp/zh-Hans.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/zh-Hans.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "在受信任的本地网络上,OpenClaw 将此 Apple Watch 直接连接到您的 Gateway。";
diff --git a/apps/ios/WatchApp/zh-Hant.lproj/InfoPlist.strings b/apps/ios/WatchApp/zh-Hant.lproj/InfoPlist.strings
index 6190d7781596..41b76408fb72 100644
--- a/apps/ios/WatchApp/zh-Hant.lproj/InfoPlist.strings
+++ b/apps/ios/WatchApp/zh-Hant.lproj/InfoPlist.strings
@@ -1,3 +1,2 @@
-"CFBundleDisplayName" = "OpenClaw";
/* OpenClaw source: "OpenClaw connects this Apple Watch directly to your Gateway on trusted local networks." */
"NSLocalNetworkUsageDescription" = "OpenClaw 會在受信任的本機網路上將此 Apple Watch 直接連線到您的 Gateway。";
diff --git a/apps/ios/project.yml b/apps/ios/project.yml
index 20f0e473cf5e..66f6dead6d68 100644
--- a/apps/ios/project.yml
+++ b/apps/ios/project.yml
@@ -114,7 +114,6 @@ targets:
CODE_SIGN_STYLE: "$(OPENCLAW_CODE_SIGN_STYLE)"
DEVELOPMENT_TEAM: "$(OPENCLAW_DEVELOPMENT_TEAM)"
OPENCLAW_ACTIVE_APP_GROUP_ID: "$(OPENCLAW_APP_GROUP_ID)"
- OPENCLAW_APP_DISPLAY_NAME: OpenClaw
OPENCLAW_URL_SCHEME: openclaw
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_APP_BUNDLE_ID)"
PROVISIONING_PROFILE_SPECIFIER: "$(OPENCLAW_APP_PROFILE)"
@@ -129,7 +128,6 @@ targets:
ASSETCATALOG_COMPILER_APPICON_NAME: AppIconDebug
CODE_SIGN_STYLE: Automatic
OPENCLAW_ACTIVE_APP_GROUP_ID: "$(OPENCLAW_DEBUG_APP_GROUP_ID)"
- OPENCLAW_APP_DISPLAY_NAME: OpenClaw
OPENCLAW_CODE_SIGN_ENTITLEMENTS: Sources/OpenClaw.entitlements
OPENCLAW_APNS_ENTITLEMENT_ENVIRONMENT: development
OPENCLAW_URL_SCHEME: openclaw-debug
@@ -145,7 +143,7 @@ targets:
info:
path: Sources/Info.plist
properties:
- CFBundleDisplayName: "$(OPENCLAW_APP_DISPLAY_NAME)"
+ CFBundleDisplayName: OpenClaw
CFBundleIconName: "$(ASSETCATALOG_COMPILER_APPICON_NAME)"
CFBundleURLTypes:
- CFBundleURLName: ai.openclawfoundation.app
diff --git a/scripts/apple-app-i18n.ts b/scripts/apple-app-i18n.ts
index 207893c68697..614588efee1f 100644
--- a/scripts/apple-app-i18n.ts
+++ b/scripts/apple-app-i18n.ts
@@ -481,9 +481,7 @@ function parseInfoPlistStrings(source: string): Array<{ key: string; source: str
key: decodeXml(match[1] ?? ""),
source: decodeXml(match[2] ?? ""),
}))
- .filter(
- (entry) => entry.key === "CFBundleDisplayName" || entry.key.endsWith("UsageDescription"),
- );
+ .filter((entry) => entry.key.endsWith("UsageDescription"));
}
type InfoPlistTranslation = {
@@ -855,9 +853,6 @@ async function syncIosInfoPlist(write: boolean): Promise {
const existing = parseStringsFile(existingSource ?? "");
const artifact = translations.find((candidate) => candidate.locale === locale);
const lines = sourceEntries.map(({ key, source }) => {
- if (key === "CFBundleDisplayName") {
- return `${stringsLiteral(key)} = ${stringsLiteral(source)};`;
- }
const sourceId = sourceIds.get([target.sourcePath, source].join("\u0000"));
if (!sourceId) {
throw new Error(`missing native InfoPlist source id for ${target.sourcePath}:${key}`);
diff --git a/scripts/ios-validate-app-store-ipa.sh b/scripts/ios-validate-app-store-ipa.sh
index 91eab6896a43..e248c1cbd338 100755
--- a/scripts/ios-validate-app-store-ipa.sh
+++ b/scripts/ios-validate-app-store-ipa.sh
@@ -219,11 +219,28 @@ assert_build_provenance() {
fi
}
+assert_localized_plists_resolve_build_settings() {
+ local localized_plist
+ local rendered
+ while IFS= read -r -d '' localized_plist; do
+ if ! rendered="$("${PLUTIL_BIN}" -convert xml1 -o - "${localized_plist}" 2>/dev/null)"; then
+ echo "Invalid IPA: could not read localized plist ${localized_plist#"${app_path}/"}." >&2
+ exit 1
+ fi
+ if grep -Eq '\$\([A-Za-z0-9_.-]+\)|\$\{[A-Za-z0-9_.-]+\}' <<<"${rendered}"; then
+ echo "Invalid IPA: unresolved build setting in localized plist ${localized_plist#"${app_path}/"}." >&2
+ exit 1
+ fi
+ done < <(find "${app_path}" -type f -path "*.lproj/InfoPlist.strings" -print0)
+}
+
assert_plist_string "${info_plist}" "CFBundleIdentifier" "${EXPECTED_BUNDLE_ID}" "bundle identifier mismatch"
+assert_plist_string "${info_plist}" "CFBundleDisplayName" "OpenClaw" "display name mismatch"
assert_plist_string "${info_plist}" "OpenClawPushMode" "${EXPECTED_PUSH_MODE}" "push mode mismatch"
assert_plist_nonempty_string "${info_plist}" "NSHealthShareUsageDescription" "Health share usage description"
assert_plist_nonempty_string "${info_plist}" "NSHealthUpdateUsageDescription" "Health update usage description"
assert_build_provenance
+assert_localized_plists_resolve_build_settings
assert_plist_empty_or_absent "${info_plist}" "OpenClawPushRelayBaseURL" "push relay URL override"
assert_plist_key_absent "${info_plist}" "OpenClawPushTransport" "legacy push transport"
assert_plist_key_absent "${info_plist}" "OpenClawPushDistribution" "legacy push distribution"
diff --git a/scripts/native-app-i18n.ts b/scripts/native-app-i18n.ts
index b1f7f75bb726..df9889193d92 100644
--- a/scripts/native-app-i18n.ts
+++ b/scripts/native-app-i18n.ts
@@ -166,7 +166,9 @@ const APPLE_BUILTIN_UI_CALLS = new Set([
"Toggle",
"searchable",
]);
-const APPLE_PLIST_STRINGS = /([\s\S]*?)<\/string>/gu;
+const APPLE_PLIST_KEYED_STRINGS = /([^<]+)<\/key>\s*([\s\S]*?)<\/string>/gu;
+// macOS uses this legacy privacy key instead of the *UsageDescription suffix.
+const APPLE_LOCALIZABLE_DESCRIPTION_KEYS = new Set(["NSScreenCaptureDescription"]);
const GENERATED_PATH_RE = /(?:^|[\\/])(?:build|\.gradle|\.build|DerivedData)(?:$|[\\/])/u;
const EXCLUDED_PATH_RE = /(?:^|[\\/])(?:Tests?|UITests?|test|Preview(?:s)?)(?:$|[\\/])/u;
const EXCLUDED_FILE_RE = /(?:Tests?|UITests?|Previews?|Testing)\.(?:swift|kt|kts)$/u;
@@ -196,6 +198,19 @@ function isAsciiAlphaNumeric(character: string): boolean {
);
}
+function decodeXml(value: string): string {
+ return value
+ .replaceAll(""", '"')
+ .replaceAll("'", "'")
+ .replaceAll("<", "<")
+ .replaceAll(">", ">")
+ .replaceAll("&", "&");
+}
+
+function isLocalizableApplePlistKey(key: string): boolean {
+ return key.endsWith("UsageDescription") || APPLE_LOCALIZABLE_DESCRIPTION_KEYS.has(key);
+}
+
export function isConditionalBranchIdentifier(source: string): boolean {
let index = 0;
while (index < source.length && isAsciiLowercaseLetter(source.charAt(index))) {
@@ -1058,15 +1073,18 @@ export function extractNativeI18nCandidates(
}
}
if (surface === "apple" && repoPath.endsWith(".plist")) {
- for (const match of source.matchAll(APPLE_PLIST_STRINGS)) {
- if (match[1]) {
+ for (const match of source.matchAll(APPLE_PLIST_KEYED_STRINGS)) {
+ const key = match[1];
+ const value = match[2];
+ if (key && isLocalizableApplePlistKey(key) && value) {
+ const valueOffset = (match.index ?? 0) + match[0].indexOf(value);
addCandidate(
entries,
surface,
repoPath,
- match[1],
+ decodeXml(value),
"plist-string",
- lineNumber(source, match.index ?? 0),
+ lineNumber(source, valueOffset),
);
}
}
diff --git a/test/scripts/apple-app-i18n.test.ts b/test/scripts/apple-app-i18n.test.ts
index a134221b6b62..c542d41a2a94 100644
--- a/test/scripts/apple-app-i18n.test.ts
+++ b/test/scripts/apple-app-i18n.test.ts
@@ -1,4 +1,4 @@
-import { mkdtemp, readFile, rm } from "node:fs/promises";
+import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
@@ -464,7 +464,7 @@ describe("Apple app i18n catalogs", () => {
]);
});
- it("generates InfoPlist localizations for every shipped iOS target", async () => {
+ it("generates only localized usage descriptions for every shipped iOS target", async () => {
const french = await readFile("apps/ios/Sources/fr.lproj/InfoPlist.strings", "utf8");
const watchChinese = await readFile(
"apps/ios/WatchApp/zh-Hans.lproj/InfoPlist.strings",
@@ -483,8 +483,28 @@ describe("Apple app i18n catalogs", () => {
expect(french).toContain('"NSMicrophoneUsageDescription" = ');
expect(french).toContain('"NSHealthUpdateUsageDescription" = ');
expect(watchChinese).toContain('"NSLocalNetworkUsageDescription" = ');
- expect(shareGerman).toContain('"CFBundleDisplayName" = "OpenClaw Share";');
- expect(activityJapanese).toContain('"CFBundleDisplayName" = "OpenClaw Activity";');
+ expect(shareGerman.trim()).toBe("");
+ expect(activityJapanese.trim()).toBe("");
+
+ for (const root of [
+ "apps/ios/Sources",
+ "apps/ios/WatchApp",
+ "apps/ios/ShareExtension",
+ "apps/ios/ActivityWidget",
+ ]) {
+ const localeDirs = (await readdir(root, { withFileTypes: true })).filter(
+ (entry) => entry.isDirectory() && entry.name.endsWith(".lproj"),
+ );
+ expect(localeDirs).toHaveLength(APPLE_I18N_LOCALES.length);
+ for (const localeDir of localeDirs) {
+ const localizedPlist = await readFile(
+ path.join(root, localeDir.name, "InfoPlist.strings"),
+ "utf8",
+ );
+ expect(localizedPlist).not.toContain("CFBundleDisplayName");
+ expect(localizedPlist).not.toMatch(/\$\([^)]*\)|\$\{[^}]*\}/u);
+ }
+ }
});
it("refreshes InfoPlist copy from translations for the current source", () => {
diff --git a/test/scripts/ios-validate-app-store-ipa.test.ts b/test/scripts/ios-validate-app-store-ipa.test.ts
index e62e6bd3796b..a1909d4f5c40 100644
--- a/test/scripts/ios-validate-app-store-ipa.test.ts
+++ b/test/scripts/ios-validate-app-store-ipa.test.ts
@@ -128,6 +128,10 @@ function writeFakePlutil(filePath: string): void {
filePath,
`#!/usr/bin/env node
const { readFileSync } = require("node:fs");
+if (process.argv[2] === "-convert" && process.argv[3] === "xml1") {
+ process.stdout.write(readFileSync(process.argv[process.argv.length - 1], "utf8"));
+ process.exit(0);
+}
const extractIndex = process.argv.indexOf("-extract");
const expectIndex = process.argv.indexOf("-expect");
if (extractIndex < 0 || expectIndex < 0 || process.argv[expectIndex + 1] !== "string") process.exit(2);
@@ -209,6 +213,8 @@ async function writeValidFixture(
buildCommit?: string;
buildTimestamp?: string;
healthUpdateUsage?: boolean | string | null;
+ displayName?: string;
+ localizedDisplayName?: string;
pushMode?: string;
legacyKey?: boolean;
} = {},
@@ -230,6 +236,7 @@ async function writeValidFixture(
const infoBody = [
plistString("CFBundleIdentifier", "ai.openclawfoundation.app"),
+ plistString("CFBundleDisplayName", options.displayName ?? "OpenClaw"),
plistString("OpenClawGitCommit", options.buildCommit ?? BUILD_COMMIT),
plistString("OpenClawBuildTimestamp", options.buildTimestamp ?? BUILD_TIMESTAMP),
plistString("OpenClawPushMode", options.pushMode ?? "appStore"),
@@ -249,6 +256,17 @@ async function writeValidFixture(
options.legacyKey ? plistString("OpenClawPushRelayProfile", "production") : "",
].join("");
writeFileSync(path.join(appDir, "Info.plist"), plist(infoBody), "utf8");
+ const localizedDir = path.join(appDir, "de.lproj");
+ mkdirSync(localizedDir, { recursive: true });
+ writeFileSync(
+ path.join(localizedDir, "InfoPlist.strings"),
+ plist(
+ options.localizedDisplayName === undefined
+ ? plistString("NSCameraUsageDescription", "OpenClaw verwendet die Kamera.")
+ : plistString("CFBundleDisplayName", options.localizedDisplayName),
+ ),
+ "utf8",
+ );
writeFileSync(path.join(appDir, "embedded.mobileprovision"), "fixture profile", "utf8");
const entitlementsPath = path.join(fixturesDir, "entitlements.plist");
@@ -406,6 +424,30 @@ describe("scripts/ios-validate-app-store-ipa.sh", () => {
expect(result.stderr).toContain("Health update usage description must be a non-empty string");
});
+ it("rejects an IPA with the wrong canonical display name", async () => {
+ const root = mkdtempSync(path.join(os.tmpdir(), "openclaw-ios-ipa-"));
+ tempDirs.push(root);
+ const fixture = await writeValidFixture(root, { displayName: "OpenClaw Debug" });
+
+ const result = runValidator(fixture);
+
+ expect(result.ok).toBe(false);
+ expect(result.stderr).toContain("display name mismatch");
+ });
+
+ it("rejects unresolved build settings in localized plist resources", async () => {
+ const root = mkdtempSync(path.join(os.tmpdir(), "openclaw-ios-ipa-"));
+ tempDirs.push(root);
+ const fixture = await writeValidFixture(root, {
+ localizedDisplayName: "$(OPENCLAW_APP_DISPLAY_NAME)",
+ });
+
+ const result = runValidator(fixture);
+
+ expect(result.ok).toBe(false);
+ expect(result.stderr).toContain("unresolved build setting in localized plist");
+ });
+
it("rejects a non-string Health update purpose value", async () => {
const root = mkdtempSync(path.join(os.tmpdir(), "openclaw-ios-ipa-"));
tempDirs.push(root);
diff --git a/test/scripts/native-app-i18n.test.ts b/test/scripts/native-app-i18n.test.ts
index b544fa5b6a3b..71037f5a264d 100644
--- a/test/scripts/native-app-i18n.test.ts
+++ b/test/scripts/native-app-i18n.test.ts
@@ -275,6 +275,25 @@ describe("native app i18n inventory", () => {
expect(entries.map((entry) => entry.source)).toEqual(["Gateway ready"]);
});
+ it("extracts only localizable usage descriptions from Apple plists", () => {
+ const entries = extractNativeI18nCandidates(
+ "apple",
+ "apps/ios/Fixture/Info.plist",
+ `
+ CFBundleDisplayName
+ OpenClaw Fixture
+ NSCameraUsageDescription
+ OpenClaw uses the camera to scan setup codes & documents.
+ OpenClawFixtureValue
+ Runtime configuration value
+ `,
+ );
+
+ expect(entries.map((entry) => entry.source)).toEqual([
+ "OpenClaw uses the camera to scan setup codes & documents.",
+ ]);
+ });
+
it("respects non-translatable Android collections and retains lowercase choices", () => {
const entries = extractNativeI18nCandidates(
"android",