diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt b/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt index 823d312a212..89af1b159fa 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt +++ b/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeCommandRegistry.kt @@ -87,9 +87,18 @@ object InvokeCommandRegistry { InvokeCommandSpec( name = OpenClawDeviceCommand.Info.rawValue, ), + InvokeCommandSpec( + name = OpenClawDeviceCommand.Permissions.rawValue, + ), + InvokeCommandSpec( + name = OpenClawDeviceCommand.Health.rawValue, + ), InvokeCommandSpec( name = OpenClawNotificationsCommand.List.rawValue, ), + InvokeCommandSpec( + name = OpenClawNotificationsCommand.Actions.rawValue, + ), InvokeCommandSpec( name = OpenClawSmsCommand.Send.rawValue, availability = InvokeCommandAvailability.SmsAvailable, diff --git a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt b/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt index 8ef070f25a3..365ca8ea999 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt +++ b/apps/android/app/src/main/java/ai/openclaw/android/node/InvokeDispatcher.kt @@ -122,9 +122,12 @@ class InvokeDispatcher( // Device commands OpenClawDeviceCommand.Status.rawValue -> deviceHandler.handleDeviceStatus(paramsJson) OpenClawDeviceCommand.Info.rawValue -> deviceHandler.handleDeviceInfo(paramsJson) + OpenClawDeviceCommand.Permissions.rawValue -> deviceHandler.handleDevicePermissions(paramsJson) + OpenClawDeviceCommand.Health.rawValue -> deviceHandler.handleDeviceHealth(paramsJson) // Notifications command OpenClawNotificationsCommand.List.rawValue -> notificationsHandler.handleNotificationsList(paramsJson) + OpenClawNotificationsCommand.Actions.rawValue -> notificationsHandler.handleNotificationsActions(paramsJson) // Screen command OpenClawScreenCommand.Record.rawValue -> screenHandler.handleScreenRecord(paramsJson) diff --git a/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt b/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt index 1a97a546a42..7e1a3d6538d 100644 --- a/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt +++ b/apps/android/app/src/main/java/ai/openclaw/android/protocol/OpenClawProtocolConstants.kt @@ -75,6 +75,8 @@ enum class OpenClawLocationCommand(val rawValue: String) { enum class OpenClawDeviceCommand(val rawValue: String) { Status("device.status"), Info("device.info"), + Permissions("device.permissions"), + Health("device.health"), ; companion object { @@ -84,6 +86,7 @@ enum class OpenClawDeviceCommand(val rawValue: String) { enum class OpenClawNotificationsCommand(val rawValue: String) { List("notifications.list"), + Actions("notifications.actions"), ; companion object { diff --git a/apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt b/apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt index 353f0e8c7aa..db72f0f842a 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/android/node/InvokeCommandRegistryTest.kt @@ -26,7 +26,10 @@ class InvokeCommandRegistryTest { assertFalse(commands.contains(OpenClawLocationCommand.Get.rawValue)) assertTrue(commands.contains(OpenClawDeviceCommand.Status.rawValue)) assertTrue(commands.contains(OpenClawDeviceCommand.Info.rawValue)) + assertTrue(commands.contains(OpenClawDeviceCommand.Permissions.rawValue)) + assertTrue(commands.contains(OpenClawDeviceCommand.Health.rawValue)) assertTrue(commands.contains(OpenClawNotificationsCommand.List.rawValue)) + assertTrue(commands.contains(OpenClawNotificationsCommand.Actions.rawValue)) assertFalse(commands.contains(OpenClawSmsCommand.Send.rawValue)) assertFalse(commands.contains("debug.logs")) assertFalse(commands.contains("debug.ed25519")) @@ -49,7 +52,10 @@ class InvokeCommandRegistryTest { assertTrue(commands.contains(OpenClawLocationCommand.Get.rawValue)) assertTrue(commands.contains(OpenClawDeviceCommand.Status.rawValue)) assertTrue(commands.contains(OpenClawDeviceCommand.Info.rawValue)) + assertTrue(commands.contains(OpenClawDeviceCommand.Permissions.rawValue)) + assertTrue(commands.contains(OpenClawDeviceCommand.Health.rawValue)) assertTrue(commands.contains(OpenClawNotificationsCommand.List.rawValue)) + assertTrue(commands.contains(OpenClawNotificationsCommand.Actions.rawValue)) assertTrue(commands.contains(OpenClawSmsCommand.Send.rawValue)) assertTrue(commands.contains("debug.logs")) assertTrue(commands.contains("debug.ed25519")) diff --git a/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt b/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt index 2268246a87d..2bbf59193ee 100644 --- a/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/android/protocol/OpenClawProtocolConstantsTest.kt @@ -46,11 +46,14 @@ class OpenClawProtocolConstantsTest { @Test fun notificationsCommandsUseStableStrings() { assertEquals("notifications.list", OpenClawNotificationsCommand.List.rawValue) + assertEquals("notifications.actions", OpenClawNotificationsCommand.Actions.rawValue) } @Test fun deviceCommandsUseStableStrings() { assertEquals("device.status", OpenClawDeviceCommand.Status.rawValue) assertEquals("device.info", OpenClawDeviceCommand.Info.rawValue) + assertEquals("device.permissions", OpenClawDeviceCommand.Permissions.rawValue) + assertEquals("device.health", OpenClawDeviceCommand.Health.rawValue) } } diff --git a/src/gateway/gateway-misc.test.ts b/src/gateway/gateway-misc.test.ts index e6f65ed1b77..bc9396c9567 100644 --- a/src/gateway/gateway-misc.test.ts +++ b/src/gateway/gateway-misc.test.ts @@ -334,7 +334,7 @@ describe("resolveNodeCommandAllowlist", () => { } }); - it("includes Android notifications.list by default", () => { + it("includes Android notifications and device diagnostics commands by default", () => { const allow = resolveNodeCommandAllowlist( {}, { @@ -344,6 +344,9 @@ describe("resolveNodeCommandAllowlist", () => { ); expect(allow.has("notifications.list")).toBe(true); + expect(allow.has("notifications.actions")).toBe(true); + expect(allow.has("device.permissions")).toBe(true); + expect(allow.has("device.health")).toBe(true); expect(allow.has("system.notify")).toBe(false); }); diff --git a/src/gateway/node-command-policy.ts b/src/gateway/node-command-policy.ts index e074b6681f7..39390329de7 100644 --- a/src/gateway/node-command-policy.ts +++ b/src/gateway/node-command-policy.ts @@ -24,8 +24,10 @@ const SCREEN_DANGEROUS_COMMANDS = ["screen.record"]; const LOCATION_COMMANDS = ["location.get"]; const NOTIFICATION_COMMANDS = ["notifications.list"]; +const ANDROID_NOTIFICATION_COMMANDS = [...NOTIFICATION_COMMANDS, "notifications.actions"]; const DEVICE_COMMANDS = ["device.info", "device.status"]; +const ANDROID_DEVICE_COMMANDS = [...DEVICE_COMMANDS, "device.permissions", "device.health"]; const CONTACTS_COMMANDS = ["contacts.search"]; const CONTACTS_DANGEROUS_COMMANDS = ["contacts.add"]; @@ -79,8 +81,8 @@ const PLATFORM_DEFAULTS: Record = { ...CANVAS_COMMANDS, ...CAMERA_COMMANDS, ...LOCATION_COMMANDS, - ...NOTIFICATION_COMMANDS, - ...DEVICE_COMMANDS, + ...ANDROID_NOTIFICATION_COMMANDS, + ...ANDROID_DEVICE_COMMANDS, ...CONTACTS_COMMANDS, ...CALENDAR_COMMANDS, ...REMINDERS_COMMANDS,