diff --git a/apps/.i18n/native-source.json b/apps/.i18n/native-source.json index aa63d6b5e8a..ae843ea5d58 100644 --- a/apps/.i18n/native-source.json +++ b/apps/.i18n/native-source.json @@ -3,7 +3,7 @@ "entries": [ { "kind": "conditional-branch", - "line": 218, + "line": 217, "path": "apps/android/app/src/main/java/ai/openclaw/app/CronJobDetail.kt", "source": "Off", "surface": "android", @@ -11,7 +11,7 @@ }, { "kind": "conditional-branch", - "line": 219, + "line": 218, "path": "apps/android/app/src/main/java/ai/openclaw/app/CronJobDetail.kt", "source": "Default", "surface": "android", @@ -1795,7 +1795,7 @@ }, { "kind": "ui-call", - "line": 693, + "line": 694, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Trust", "surface": "android", @@ -1803,7 +1803,7 @@ }, { "kind": "ui-call", - "line": 698, + "line": 699, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Cancel", "surface": "android", @@ -1811,7 +1811,7 @@ }, { "kind": "ui-named-argument", - "line": 889, + "line": 890, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Welcome to OpenClaw", "surface": "android", @@ -1819,7 +1819,7 @@ }, { "kind": "ui-named-argument", - "line": 890, + "line": 891, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Turn this device into a secure OpenClaw node for chat, voice, camera, and device tools.", "surface": "android", @@ -1827,7 +1827,7 @@ }, { "kind": "ui-named-argument", - "line": 915, + "line": 916, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "OpenClaw logo", "surface": "android", @@ -1835,7 +1835,7 @@ }, { "kind": "ui-named-argument", - "line": 971, + "line": 972, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Connect to your Gateway", "surface": "android", @@ -1843,7 +1843,7 @@ }, { "kind": "ui-named-argument", - "line": 972, + "line": 973, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Choose device permissions", "surface": "android", @@ -1851,7 +1851,7 @@ }, { "kind": "ui-named-argument", - "line": 973, + "line": 974, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Use OpenClaw from your phone", "surface": "android", @@ -1859,7 +1859,7 @@ }, { "kind": "ui-named-argument", - "line": 995, + "line": 996, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Security notice", "surface": "android", @@ -1867,7 +1867,7 @@ }, { "kind": "ui-named-argument", - "line": 997, + "line": 998, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "The connected OpenClaw agent can use device capabilities you enable. Continue only if you trust the Gateway and agent you connect to.", "surface": "android", @@ -1875,7 +1875,7 @@ }, { "kind": "ui-named-argument", - "line": 1038, + "line": 1039, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Connect Gateway", "surface": "android", @@ -1883,7 +1883,7 @@ }, { "kind": "ui-named-argument", - "line": 1039, + "line": 1040, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Scan a QR code or use the setup code from your OpenClaw Gateway.", "surface": "android", @@ -1891,7 +1891,7 @@ }, { "kind": "ui-toast", - "line": 1048, + "line": 1049, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Could not open setup guide.", "surface": "android", @@ -1899,7 +1899,7 @@ }, { "kind": "ui-named-argument", - "line": 1056, + "line": 1057, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Scan QR or setup code", "surface": "android", @@ -1907,7 +1907,7 @@ }, { "kind": "ui-named-argument", - "line": 1062, + "line": 1063, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Set up manually", "surface": "android", @@ -1915,7 +1915,7 @@ }, { "kind": "ui-named-argument", - "line": 1084, + "line": 1085, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Before you start", "surface": "android", @@ -1923,7 +1923,7 @@ }, { "kind": "ui-named-argument", - "line": 1090, + "line": 1091, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Access to the Gateway device", "surface": "android", @@ -1931,7 +1931,7 @@ }, { "kind": "ui-named-argument", - "line": 1091, + "line": 1092, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Have a terminal open on the device running OpenClaw.", "surface": "android", @@ -1939,7 +1939,7 @@ }, { "kind": "ui-named-argument", - "line": 1094, + "line": 1095, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Phone can reach the Gateway", "surface": "android", @@ -1947,7 +1947,7 @@ }, { "kind": "ui-named-argument", - "line": 1095, + "line": 1096, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Use the same network, or a secure remote Gateway URL.", "surface": "android", @@ -1955,7 +1955,7 @@ }, { "kind": "ui-named-argument", - "line": 1101, + "line": 1102, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Android setup guide", "surface": "android", @@ -1963,7 +1963,7 @@ }, { "kind": "ui-named-argument", - "line": 1144, + "line": 1145, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Setup Gateway", "surface": "android", @@ -1971,7 +1971,7 @@ }, { "kind": "ui-named-argument", - "line": 1150, + "line": 1151, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Start your Gateway.", "surface": "android", @@ -1979,7 +1979,7 @@ }, { "kind": "ui-named-argument", - "line": 1151, + "line": 1152, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "openclaw gateway", "surface": "android", @@ -1987,7 +1987,7 @@ }, { "kind": "ui-named-argument", - "line": 1156, + "line": 1157, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Generate a QR code.", "surface": "android", @@ -1995,7 +1995,7 @@ }, { "kind": "ui-named-argument", - "line": 1157, + "line": 1158, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "openclaw qr", "surface": "android", @@ -2003,7 +2003,7 @@ }, { "kind": "ui-named-argument", - "line": 1177, + "line": 1178, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Choose from gallery", "surface": "android", @@ -2011,7 +2011,7 @@ }, { "kind": "ui-named-argument", - "line": 1231, + "line": 1232, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "QR code not accepted", "surface": "android", @@ -2019,7 +2019,7 @@ }, { "kind": "ui-named-argument", - "line": 1246, + "line": 1247, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Choose another image", "surface": "android", @@ -2027,7 +2027,7 @@ }, { "kind": "ui-named-argument", - "line": 1299, + "line": 1300, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Scan QR code", "surface": "android", @@ -2035,7 +2035,7 @@ }, { "kind": "ui-named-argument", - "line": 1301, + "line": 1302, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Open the camera and frame the code from openclaw qr.", "surface": "android", @@ -2043,7 +2043,7 @@ }, { "kind": "ui-named-argument", - "line": 1335, + "line": 1336, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Align the QR code inside the square.", "surface": "android", @@ -2051,7 +2051,7 @@ }, { "kind": "ui-named-argument", - "line": 1353, + "line": 1354, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Camera access is needed to scan the setup QR.", "surface": "android", @@ -2059,7 +2059,7 @@ }, { "kind": "ui-named-argument", - "line": 1358, + "line": 1359, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Allow camera", "surface": "android", @@ -2067,7 +2067,7 @@ }, { "kind": "ui-named-argument", - "line": 1379, + "line": 1380, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Close scanner", "surface": "android", @@ -2075,7 +2075,7 @@ }, { "kind": "ui-named-argument", - "line": 1541, + "line": 1542, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Enter setup code", "surface": "android", @@ -2083,7 +2083,7 @@ }, { "kind": "ui-named-argument", - "line": 1542, + "line": 1543, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Setup code", "surface": "android", @@ -2091,7 +2091,7 @@ }, { "kind": "ui-named-argument", - "line": 1546, + "line": 1547, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Paste setup code", "surface": "android", @@ -2099,7 +2099,7 @@ }, { "kind": "ui-named-argument", - "line": 1550, + "line": 1551, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Setup code was not accepted", "surface": "android", @@ -2107,7 +2107,7 @@ }, { "kind": "ui-named-argument", - "line": 1554, + "line": 1555, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Use setup code", "surface": "android", @@ -2115,7 +2115,7 @@ }, { "kind": "ui-named-argument", - "line": 1585, + "line": 1586, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Manual setup", "surface": "android", @@ -2123,7 +2123,7 @@ }, { "kind": "ui-named-argument", - "line": 1588, + "line": 1589, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway URL", "surface": "android", @@ -2131,7 +2131,7 @@ }, { "kind": "ui-named-argument", - "line": 1590, + "line": 1591, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Host", "surface": "android", @@ -2139,7 +2139,7 @@ }, { "kind": "ui-named-argument", - "line": 1591, + "line": 1592, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Port", "surface": "android", @@ -2147,7 +2147,7 @@ }, { "kind": "ui-named-argument", - "line": 1594, + "line": 1595, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Use the Gateway computer's LAN address or secure remote hostname.", "surface": "android", @@ -2155,7 +2155,7 @@ }, { "kind": "ui-named-argument", - "line": 1601, + "line": 1602, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Token", "surface": "android", @@ -2163,7 +2163,7 @@ }, { "kind": "ui-named-argument", - "line": 1602, + "line": 1603, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Paste token", "surface": "android", @@ -2171,7 +2171,7 @@ }, { "kind": "ui-named-argument", - "line": 1604, + "line": 1605, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Paste a shared Gateway token or operator-issued token.", "surface": "android", @@ -2179,7 +2179,7 @@ }, { "kind": "ui-named-argument", - "line": 1611, + "line": 1612, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Password", "surface": "android", @@ -2187,7 +2187,7 @@ }, { "kind": "ui-named-argument", - "line": 1612, + "line": 1613, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Password optional", "surface": "android", @@ -2195,7 +2195,7 @@ }, { "kind": "ui-named-argument", - "line": 1616, + "line": 1617, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Connection type", "surface": "android", @@ -2203,7 +2203,7 @@ }, { "kind": "ui-named-argument", - "line": 1618, + "line": 1619, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Local network", "surface": "android", @@ -2211,7 +2211,7 @@ }, { "kind": "ui-named-argument", - "line": 1619, + "line": 1620, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Secure remote", "surface": "android", @@ -2219,7 +2219,7 @@ }, { "kind": "ui-named-argument", - "line": 1622, + "line": 1623, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Local works for LAN or emulator hosts. Secure remote is for wss:// or Tailscale Serve/Funnel.", "surface": "android", @@ -2227,7 +2227,7 @@ }, { "kind": "ui-named-argument", - "line": 1630, + "line": 1631, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Could not test connection", "surface": "android", @@ -2235,7 +2235,7 @@ }, { "kind": "ui-named-argument", - "line": 1635, + "line": 1636, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Test connection", "surface": "android", @@ -2243,7 +2243,7 @@ }, { "kind": "ui-call", - "line": 1813, + "line": 1814, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "View details", "surface": "android", @@ -2251,7 +2251,7 @@ }, { "kind": "ui-call", - "line": 1846, + "line": 1847, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Connection details", "surface": "android", @@ -2259,7 +2259,7 @@ }, { "kind": "ui-call", - "line": 1858, + "line": 1859, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Copy", "surface": "android", @@ -2267,7 +2267,7 @@ }, { "kind": "ui-call", - "line": 1863, + "line": 1864, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Close", "surface": "android", @@ -2275,7 +2275,7 @@ }, { "kind": "ui-toast", - "line": 1875, + "line": 1876, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Details copied", "surface": "android", @@ -2283,7 +2283,7 @@ }, { "kind": "ui-named-argument", - "line": 1960, + "line": 1961, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Approve node access", "surface": "android", @@ -2291,7 +2291,7 @@ }, { "kind": "ui-named-argument", - "line": 1967, + "line": 1968, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway pairing is complete. Approve this phone as a node so OpenClaw can use the device capabilities you enable.", "surface": "android", @@ -2299,7 +2299,7 @@ }, { "kind": "ui-named-argument", - "line": 1975, + "line": 1976, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "On the Gateway computer, run:", "surface": "android", @@ -2307,7 +2307,7 @@ }, { "kind": "ui-named-argument", - "line": 1984, + "line": 1985, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Use the requestId from the pending command in the approve command.", "surface": "android", @@ -2315,7 +2315,7 @@ }, { "kind": "ui-named-argument", - "line": 1995, + "line": 1996, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "I have approved", "surface": "android", @@ -2323,7 +2323,7 @@ }, { "kind": "ui-named-argument", - "line": 1996, + "line": 1997, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Checking approval…", "surface": "android", @@ -2331,7 +2331,7 @@ }, { "kind": "ui-named-argument", - "line": 2008, + "line": 2009, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Still waiting for approval", "surface": "android", @@ -2339,7 +2339,7 @@ }, { "kind": "ui-named-argument", - "line": 2011, + "line": 2012, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Run the approve command on the Gateway computer, then check again.", "surface": "android", @@ -2347,7 +2347,7 @@ }, { "kind": "ui-named-argument", - "line": 2018, + "line": 2019, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "OK", "surface": "android", @@ -2355,7 +2355,7 @@ }, { "kind": "ui-named-argument", - "line": 2168, + "line": 2169, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Copy approval command", "surface": "android", @@ -2363,7 +2363,7 @@ }, { "kind": "ui-named-argument", - "line": 2194, + "line": 2195, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Only enable access you are comfortable letting OpenClaw use while this phone is connected. You can change these later in Android Settings.", "surface": "android", @@ -2371,7 +2371,7 @@ }, { "kind": "ui-named-argument", - "line": 2206, + "line": 2207, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Continue", "surface": "android", @@ -2379,7 +2379,7 @@ }, { "kind": "ui-named-argument", - "line": 2233, + "line": 2234, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Back", "surface": "android", @@ -2387,7 +2387,7 @@ }, { "kind": "ui-named-argument", - "line": 2280, + "line": 2281, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Permissions", "surface": "android", @@ -2395,7 +2395,7 @@ }, { "kind": "conditional-branch", - "line": 2605, + "line": 2606, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "The code may have expired or been generated for another Gateway.", "surface": "android", @@ -2403,7 +2403,7 @@ }, { "kind": "conditional-branch", - "line": 2609, + "line": 2610, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway password is required. Enter it again or edit this connection.", "surface": "android", @@ -2411,7 +2411,7 @@ }, { "kind": "conditional-branch", - "line": 2610, + "line": 2611, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway password is invalid. Re-enter it or reset this gateway connection.", "surface": "android", @@ -2419,7 +2419,7 @@ }, { "kind": "conditional-branch", - "line": 2611, + "line": 2612, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway token is required. Enter it again or edit this connection.", "surface": "android", @@ -2427,7 +2427,7 @@ }, { "kind": "conditional-branch", - "line": 2613, + "line": 2614, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway requires this device identity. Re-authenticate or reset this gateway connection.", "surface": "android", @@ -2435,7 +2435,7 @@ }, { "kind": "conditional-branch", - "line": 2617, + "line": 2618, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Saved authentication is invalid. Re-authenticate or reset this gateway connection.", "surface": "android", @@ -2443,7 +2443,7 @@ }, { "kind": "conditional-branch", - "line": 2618, + "line": 2619, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway authentication is not configured. Edit this connection and try again.", "surface": "android", @@ -2451,7 +2451,7 @@ }, { "kind": "conditional-branch", - "line": 2619, + "line": 2620, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Gateway authentication needs review. Check gateway settings, then retry.", "surface": "android", @@ -2459,7 +2459,7 @@ }, { "kind": "conditional-branch", - "line": 2636, + "line": 2637, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "$summary $it", "surface": "android", @@ -2467,7 +2467,7 @@ }, { "kind": "ui-toast", - "line": 2758, + "line": 2759, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Approval command copied", "surface": "android", @@ -2475,7 +2475,7 @@ }, { "kind": "conditional-branch", - "line": 2820, + "line": 2821, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Granted", "surface": "android", @@ -2483,7 +2483,7 @@ }, { "kind": "conditional-branch", - "line": 2820, + "line": 2821, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt", "source": "Not granted", "surface": "android", @@ -5723,7 +5723,7 @@ }, { "kind": "ui-call", - "line": 201, + "line": 199, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Type a message…", "surface": "android", @@ -5731,7 +5731,7 @@ }, { "kind": "ui-named-argument", - "line": 211, + "line": 209, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Gateway is offline. Text messages are queued and sent after reconnecting.", "surface": "android", @@ -5739,7 +5739,7 @@ }, { "kind": "ui-named-argument", - "line": 240, + "line": 238, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Select thinking level", "surface": "android", @@ -5747,7 +5747,7 @@ }, { "kind": "ui-named-argument", - "line": 264, + "line": 262, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Attach", "surface": "android", @@ -5755,7 +5755,7 @@ }, { "kind": "ui-named-argument", - "line": 272, + "line": 270, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Refresh", "surface": "android", @@ -5763,7 +5763,7 @@ }, { "kind": "ui-named-argument", - "line": 280, + "line": 278, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Abort", "surface": "android", @@ -5771,7 +5771,7 @@ }, { "kind": "ui-named-argument", - "line": 325, + "line": 323, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "Send", "surface": "android", @@ -5779,7 +5779,7 @@ }, { "kind": "ui-named-argument", - "line": 351, + "line": 349, "path": "apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt", "source": "No commands found", "surface": "android", diff --git a/apps/android/app/src/main/java/ai/openclaw/app/CronJobDetail.kt b/apps/android/app/src/main/java/ai/openclaw/app/CronJobDetail.kt index cb341a21d0d..78725c7d262 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/CronJobDetail.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/CronJobDetail.kt @@ -206,25 +206,23 @@ private fun cronDeliveryLabel(delivery: JsonObject?): String { val value = delivery ?: return "Default" val mode = value.string("mode") ?: return "Default" return listOfNotNull( - mode.replaceFirstChar { it.uppercaseChar() }, - value.string("channel"), - value.string("to"), - value.string("accountId")?.let { "Account $it" }, - ) - .joinToString(" · ") + mode.replaceFirstChar { it.uppercaseChar() }, + value.string("channel"), + value.string("to"), + value.string("accountId")?.let { "Account $it" }, + ).joinToString(" · ") } private fun cronFailureAlertLabel(failureAlert: JsonElement?): String { if ((failureAlert as? JsonPrimitive)?.booleanOrNull == false) return "Off" val alert = failureAlert.asObjectOrNull() ?: return "Default" return listOfNotNull( - alert.long("after")?.let { "After $it" }, - alert.string("mode")?.replaceFirstChar { it.uppercaseChar() }, - alert.string("channel"), - alert.string("to"), - alert.long("cooldownMs")?.takeIf { it > 0L }?.let { "Cooldown ${formatCronInterval(it)}" }, - ) - .joinToString(" · ") + alert.long("after")?.let { "After $it" }, + alert.string("mode")?.replaceFirstChar { it.uppercaseChar() }, + alert.string("channel"), + alert.string("to"), + alert.long("cooldownMs")?.takeIf { it > 0L }?.let { "Cooldown ${formatCronInterval(it)}" }, + ).joinToString(" · ") .ifBlank { "On" } } diff --git a/apps/android/app/src/main/java/ai/openclaw/app/gateway/NetworkMonitor.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/NetworkMonitor.kt index 942dcca05c5..6b22a10e705 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/gateway/NetworkMonitor.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/NetworkMonitor.kt @@ -107,5 +107,4 @@ internal class ValidatedNetworkState( * True when the network reports a validated internet capability. Exposed internal so the * predicate can be unit-tested without a Robolectric ConnectivityManager shadow. */ -internal fun isTransportValidated(capabilities: NetworkCapabilities): Boolean = - capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) +internal fun isTransportValidated(capabilities: NetworkCapabilities): Boolean = capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) diff --git a/apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt b/apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt index 19a689c484a..7b2bb746ae0 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt @@ -4,9 +4,9 @@ import ai.openclaw.app.BuildConfig import ai.openclaw.app.CameraHudKind import ai.openclaw.app.gateway.GatewaySession import android.content.Context +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.CancellationException import kotlinx.coroutines.withContext import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.buildJsonArray @@ -173,6 +173,5 @@ class CameraHandler( } } - private fun parseIncludeAudio(paramsJson: String?): Boolean? = - parseJsonBooleanFlag(parseJsonParamsObject(paramsJson), "includeAudio") + private fun parseIncludeAudio(paramsJson: String?): Boolean? = parseJsonBooleanFlag(parseJsonParamsObject(paramsJson), "includeAudio") } diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt index cecdefca4d7..ddc4e2a5717 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/OnboardingFlow.kt @@ -571,7 +571,8 @@ fun OnboardingFlow( val message = when (scanned.error) { GatewayEndpointValidationError.INSECURE_REMOTE_URL, - GatewayEndpointValidationError.IPV6_ZONE_ID_UNSUPPORTED -> + GatewayEndpointValidationError.IPV6_ZONE_ID_UNSUPPORTED, + -> gatewayEndpointValidationMessage(scanned.error, GatewayEndpointInputSource.QR_SCAN) else -> "That QR code is not an OpenClaw setup QR. Generate a fresh code with openclaw qr, then try again." } diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/WorkspaceFilesScreen.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/WorkspaceFilesScreen.kt index dec1a783cad..b34d3dc8dad 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/WorkspaceFilesScreen.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/WorkspaceFilesScreen.kt @@ -376,8 +376,7 @@ private fun WorkspaceFileContent(file: GatewayWorkspaceFile) { } /** File extensions double as fence language hints; unknown ones render plain. */ -private fun workspaceLanguageHint(name: String): String? = - name.substringAfterLast('.', missingDelimiterValue = "").lowercase().ifEmpty { null } +private fun workspaceLanguageHint(name: String): String? = name.substringAfterLast('.', missingDelimiterValue = "").lowercase().ifEmpty { null } /** Exports one previewed file through the system share sheet via FileProvider. */ private fun shareWorkspaceFile( diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCodeHighlight.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCodeHighlight.kt index 5c4ade8c6ed..6b24945390a 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCodeHighlight.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCodeHighlight.kt @@ -50,10 +50,50 @@ private val kotlinSpec = CodeLanguageSpec( keywords = setOf( - "as", "break", "by", "catch", "class", "companion", "constructor", "continue", "data", "do", "else", - "enum", "false", "finally", "for", "fun", "if", "import", "in", "init", "interface", "internal", "is", - "lateinit", "null", "object", "override", "package", "private", "protected", "public", "return", - "sealed", "super", "suspend", "this", "throw", "true", "try", "typealias", "val", "var", "when", "while", + "as", + "break", + "by", + "catch", + "class", + "companion", + "constructor", + "continue", + "data", + "do", + "else", + "enum", + "false", + "finally", + "for", + "fun", + "if", + "import", + "in", + "init", + "interface", + "internal", + "is", + "lateinit", + "null", + "object", + "override", + "package", + "private", + "protected", + "public", + "return", + "sealed", + "super", + "suspend", + "this", + "throw", + "true", + "try", + "typealias", + "val", + "var", + "when", + "while", ), lineComment = "//", blockComment = "/*" to "*/", @@ -67,11 +107,59 @@ private val swiftSpec = CodeLanguageSpec( keywords = setOf( - "actor", "as", "associatedtype", "async", "await", "break", "case", "catch", "class", "continue", - "default", "defer", "deinit", "do", "else", "enum", "extension", "fallthrough", "false", "fileprivate", - "for", "func", "guard", "if", "import", "in", "init", "internal", "is", "let", "mutating", "nil", "open", - "override", "private", "protocol", "public", "repeat", "return", "self", "some", "static", "struct", - "super", "switch", "throw", "throws", "true", "try", "typealias", "var", "where", "while", + "actor", + "as", + "associatedtype", + "async", + "await", + "break", + "case", + "catch", + "class", + "continue", + "default", + "defer", + "deinit", + "do", + "else", + "enum", + "extension", + "fallthrough", + "false", + "fileprivate", + "for", + "func", + "guard", + "if", + "import", + "in", + "init", + "internal", + "is", + "let", + "mutating", + "nil", + "open", + "override", + "private", + "protocol", + "public", + "repeat", + "return", + "self", + "some", + "static", + "struct", + "super", + "switch", + "throw", + "throws", + "true", + "try", + "typealias", + "var", + "where", + "while", ), lineComment = "//", blockComment = "/*" to "*/", @@ -84,12 +172,62 @@ private val typescriptSpec = CodeLanguageSpec( keywords = setOf( - "abstract", "any", "as", "async", "await", "boolean", "break", "case", "catch", "class", "const", - "continue", "declare", "default", "delete", "do", "else", "enum", "export", "extends", "false", - "finally", "for", "from", "function", "if", "implements", "import", "in", "instanceof", "interface", - "let", "namespace", "never", "new", "null", "number", "of", "readonly", "return", "static", "string", - "super", "switch", "this", "throw", "true", "try", "type", "typeof", "undefined", "unknown", "var", - "void", "while", "yield", + "abstract", + "any", + "as", + "async", + "await", + "boolean", + "break", + "case", + "catch", + "class", + "const", + "continue", + "declare", + "default", + "delete", + "do", + "else", + "enum", + "export", + "extends", + "false", + "finally", + "for", + "from", + "function", + "if", + "implements", + "import", + "in", + "instanceof", + "interface", + "let", + "namespace", + "never", + "new", + "null", + "number", + "of", + "readonly", + "return", + "static", + "string", + "super", + "switch", + "this", + "throw", + "true", + "try", + "type", + "typeof", + "undefined", + "unknown", + "var", + "void", + "while", + "yield", ), lineComment = "//", blockComment = "/*" to "*/", @@ -100,9 +238,42 @@ private val pythonSpec = CodeLanguageSpec( keywords = setOf( - "and", "as", "assert", "async", "await", "break", "case", "class", "continue", "def", "del", "elif", - "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "match", - "nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with", "yield", "False", "None", + "and", + "as", + "assert", + "async", + "await", + "break", + "case", + "class", + "continue", + "def", + "del", + "elif", + "else", + "except", + "finally", + "for", + "from", + "global", + "if", + "import", + "in", + "is", + "lambda", + "match", + "nonlocal", + "not", + "or", + "pass", + "raise", + "return", + "try", + "while", + "with", + "yield", + "False", + "None", "True", ), lineComment = "#", @@ -114,9 +285,33 @@ private val bashSpec = CodeLanguageSpec( keywords = setOf( - "break", "case", "continue", "declare", "do", "done", "elif", "else", "esac", "exit", "export", "fi", - "for", "function", "if", "in", "local", "readonly", "return", "select", "set", "shift", "source", - "then", "unset", "until", "while", + "break", + "case", + "continue", + "declare", + "do", + "done", + "elif", + "else", + "esac", + "exit", + "export", + "fi", + "for", + "function", + "if", + "in", + "local", + "readonly", + "return", + "select", + "set", + "shift", + "source", + "then", + "unset", + "until", + "while", ), lineComment = "#", lineCommentNeedsBoundary = true, diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCommandControls.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCommandControls.kt index 8200769856d..658a57d4194 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCommandControls.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatCommandControls.kt @@ -34,7 +34,11 @@ internal fun slashCommandText(command: ChatCommandEntry): String { command.textAliases .firstOrNull { alias -> alias.startsWith("/") && alias.length > 1 } ?.let { return it } - val name = command.name.trim().removePrefix("/").takeIf { it.isNotEmpty() } ?: "help" + val name = + command.name + .trim() + .removePrefix("/") + .takeIf { it.isNotEmpty() } ?: "help" return "/$name" } diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt index 351b591d7d5..da15060c7a2 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatComposer.kt @@ -91,11 +91,9 @@ internal data class SheetComposerSendAction( val sendMessage: Boolean, ) -internal fun resolveSheetSlashCommandSelection(command: ChatCommandEntry): SheetSlashCommandSelection = - SheetSlashCommandSelection(input = slashCommandCompletion(command)) +internal fun resolveSheetSlashCommandSelection(command: ChatCommandEntry): SheetSlashCommandSelection = SheetSlashCommandSelection(input = slashCommandCompletion(command)) -internal fun resolveSheetComposerSendAction(input: String): SheetComposerSendAction = - SheetComposerSendAction(sendMessage = input.trim().isNotEmpty()) +internal fun resolveSheetComposerSendAction(input: String): SheetComposerSendAction = SheetComposerSendAction(sendMessage = input.trim().isNotEmpty()) /** Applies a draft exactly once so restored prompts do not overwrite user edits. */ internal fun applyDraftText( diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageActions.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageActions.kt index be8ae2a9a6d..04e400bbe31 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageActions.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/chat/ChatMessageActions.kt @@ -8,10 +8,10 @@ import android.content.Context import android.content.Intent import android.widget.Toast import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/design/OpenClawMascot.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/design/OpenClawMascot.kt index 460de42720a..e239146e70d 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/design/OpenClawMascot.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/design/OpenClawMascot.kt @@ -37,8 +37,7 @@ private val BodyPath = .parsePathString( "M60 10 C30 10 15 35 15 55 C15 75 30 95 45 100 L45 110 L55 110 L55 100 " + "C55 100 60 102 65 100 L65 110 L75 110 L75 100 C90 95 105 75 105 55 C105 35 90 10 60 10Z", - ) - .toPath() + ).toPath() private val LeftClawPath = PathParser().parsePathString("M20 45 C5 40 0 50 5 60 C10 70 20 65 25 55 C28 48 25 45 20 45Z").toPath() private val RightClawPath = @@ -50,6 +49,7 @@ private val CoralBright = Color(0xFFFF4D4D) private val CoralDark = Color(0xFF991B1B) private val EyeDark = Color(0xFF050810) private val EyeGlow = Color(0xFF00E5CC) + // Claws hinge on their body-facing edge, antennae rotate around their own center. private val LeftClawPivot = Offset(26f, 53f) private val RightClawPivot = Offset(94f, 53f) @@ -183,15 +183,19 @@ private fun rememberMascotPose(): MascotPose { } } -private fun clawSnapKeyframes() = keyframes { - durationMillis = 4000 - 0f at 0 using EaseInOut - 0f at 3400 using EaseInOut - -8f at 3600 using EaseInOut - 0f at 3800 using EaseInOut -} +private fun clawSnapKeyframes() = + keyframes { + durationMillis = 4000 + 0f at 0 using EaseInOut + 0f at 3400 using EaseInOut + -8f at 3600 using EaseInOut + 0f at 3800 using EaseInOut + } -private fun DrawScope.drawMascot(pose: MascotPose, tint: Color?) { +private fun DrawScope.drawMascot( + pose: MascotPose, + tint: Color?, +) { val bodyBrush = if (tint == null) { Brush.linearGradient( diff --git a/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt index fd860dce9b5..66259eb36e4 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/voice/TalkDirectiveParser.kt @@ -204,8 +204,7 @@ object TalkDirectiveParser { return null } - private fun JsonObject.valueForKey(key: String): JsonElement? = - this[key] ?: entries.firstOrNull { it.key.equals(key, ignoreCase = true) }?.value + private fun JsonObject.valueForKey(key: String): JsonElement? = this[key] ?: entries.firstOrNull { it.key.equals(key, ignoreCase = true) }?.value } private fun JsonElement?.asStringOrNull(): String? = (this as? JsonPrimitive)?.takeIf { it.isString }?.content diff --git a/apps/android/app/src/test/java/ai/openclaw/app/CronJobDetailTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/CronJobDetailTest.kt index 57c0b79d60c..e30eac5dbcc 100644 --- a/apps/android/app/src/test/java/ai/openclaw/app/CronJobDetailTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/CronJobDetailTest.kt @@ -79,7 +79,8 @@ class CronJobDetailTest { payload: String = """{"kind":"agentTurn","message":"Summarize the day","model":"openai/gpt-5.5","thinking":"high"}""", ): JsonObject = - Json.parseToJsonElement( + Json + .parseToJsonElement( """ { "id": "job-1", @@ -108,6 +109,5 @@ class CronJobDetailTest { } } """.trimIndent(), - ) - .jsonObject + ).jsonObject } diff --git a/apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt index 3740da8cdb0..4dff79e796a 100644 --- a/apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/gateway/InvokeErrorParserTest.kt @@ -26,17 +26,16 @@ class InvokeErrorParserTest { @Test fun parseInvokeErrorMessage_rejectsNonCanonicalCodePrefix() { listOf( - "IllegalStateException: boom", - "2FAST: boom", - "_PRIVATE: boom", - "CAMERA-PERMISSION: boom", - ) - .forEach { raw -> - val parsed = parseInvokeErrorMessage(raw) - assertEquals("UNAVAILABLE", parsed.code) - assertEquals(raw, parsed.message) - assertFalse(parsed.hadExplicitCode) - } + "IllegalStateException: boom", + "2FAST: boom", + "_PRIVATE: boom", + "CAMERA-PERMISSION: boom", + ).forEach { raw -> + val parsed = parseInvokeErrorMessage(raw) + assertEquals("UNAVAILABLE", parsed.code) + assertEquals(raw, parsed.message) + assertFalse(parsed.hadExplicitCode) + } } @Test diff --git a/apps/android/app/src/test/java/ai/openclaw/app/node/NodeUtilsTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/NodeUtilsTest.kt index 2555ad40342..559d342f8c4 100644 --- a/apps/android/app/src/test/java/ai/openclaw/app/node/NodeUtilsTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/NodeUtilsTest.kt @@ -31,10 +31,11 @@ class NodeUtilsTest { @Test fun parseJsonBooleanFlag_acceptsJsonBooleanLiterals() { - val params = buildJsonObject { - put("enabled", true) - put("disabled", false) - } + val params = + buildJsonObject { + put("enabled", true) + put("disabled", false) + } assertEquals(true, parseJsonBooleanFlag(params, "enabled")) assertEquals(false, parseJsonBooleanFlag(params, "disabled"))