feat(ios): distinguish debug app builds (#100222)
* feat(ios): distinguish debug app builds * feat(ios): distinguish debug app builds * feat(ios): emphasize debug app icons * feat(ios): emphasize debug app icons
@@ -2,6 +2,7 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Debug builds now use separate app, extension, widget, and Watch identifiers plus a distinct debug icon, so they can remain installed beside release builds.
|
||||
- Animated the OpenClaw mascot (float, blink, antenna wiggle, claw snaps) across onboarding, sidebar, and command center, matching openclaw.ai.
|
||||
|
||||
## 2026.6.11 - 2026-07-01
|
||||
|
||||
@@ -19,6 +19,12 @@ OPENCLAW_WATCH_APP_PROFILE =
|
||||
#include? "../.local-signing.xcconfig"
|
||||
#include? "../LocalSigning.xcconfig"
|
||||
|
||||
// Debug products install alongside release products and keep their app-group data separate.
|
||||
OPENCLAW_DEBUG_APP_BUNDLE_ID = $(OPENCLAW_APP_BUNDLE_ID).debug
|
||||
OPENCLAW_DEBUG_ACTIVITY_WIDGET_BUNDLE_ID = $(OPENCLAW_DEBUG_APP_BUNDLE_ID).activitywidget
|
||||
OPENCLAW_DEBUG_WATCH_APP_BUNDLE_ID = $(OPENCLAW_DEBUG_APP_BUNDLE_ID).watchkitapp
|
||||
OPENCLAW_DEBUG_APP_GROUP_ID = $(OPENCLAW_APP_GROUP_ID).debug
|
||||
|
||||
CODE_SIGN_STYLE = $(OPENCLAW_CODE_SIGN_STYLE)
|
||||
CODE_SIGN_IDENTITY = $(OPENCLAW_CODE_SIGN_IDENTITY)
|
||||
DEVELOPMENT_TEAM = $(OPENCLAW_DEVELOPMENT_TEAM)
|
||||
|
||||
@@ -42,6 +42,6 @@
|
||||
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
|
||||
</dict>
|
||||
<key>OpenClawAppGroupIdentifier</key>
|
||||
<string>$(OPENCLAW_APP_GROUP_ID)</string>
|
||||
<string>$(OPENCLAW_ACTIVE_APP_GROUP_ID)</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>$(OPENCLAW_APP_GROUP_ID)</string>
|
||||
<string>$(OPENCLAW_ACTIVE_APP_GROUP_ID)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -25,3 +25,10 @@ OPENCLAW_WATCH_APP_PROFILE =
|
||||
// so later assignments in local files override the defaults above.
|
||||
#include? ".local-signing.xcconfig"
|
||||
#include? "LocalSigning.xcconfig"
|
||||
|
||||
// Debug products install alongside release products and keep their app-group data separate.
|
||||
OPENCLAW_DEBUG_APP_BUNDLE_ID = $(OPENCLAW_APP_BUNDLE_ID).debug
|
||||
OPENCLAW_DEBUG_SHARE_BUNDLE_ID = $(OPENCLAW_DEBUG_APP_BUNDLE_ID).share
|
||||
OPENCLAW_DEBUG_ACTIVITY_WIDGET_BUNDLE_ID = $(OPENCLAW_DEBUG_APP_BUNDLE_ID).activitywidget
|
||||
OPENCLAW_DEBUG_WATCH_APP_BUNDLE_ID = $(OPENCLAW_DEBUG_APP_BUNDLE_ID).watchkitapp
|
||||
OPENCLAW_DEBUG_APP_GROUP_ID = $(OPENCLAW_APP_GROUP_ID).debug
|
||||
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -4,16 +4,16 @@
|
||||
<dict>
|
||||
<key>BGTaskSchedulerPermittedIdentifiers</key>
|
||||
<array>
|
||||
<string>$(OPENCLAW_APP_BUNDLE_ID).bgrefresh</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).bgrefresh</string>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>OpenClaw</string>
|
||||
<string>$(OPENCLAW_APP_DISPLAY_NAME)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
<string>$(ASSETCATALOG_COMPILER_APPICON_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
@@ -31,7 +31,7 @@
|
||||
<string>ai.openclawfoundation.app</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>openclaw</string>
|
||||
<string>$(OPENCLAW_URL_SCHEME)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
@@ -79,7 +79,7 @@
|
||||
<key>NSSupportsLiveActivities</key>
|
||||
<true/>
|
||||
<key>OpenClawAppGroupIdentifier</key>
|
||||
<string>$(OPENCLAW_APP_GROUP_ID)</string>
|
||||
<string>$(OPENCLAW_ACTIVE_APP_GROUP_ID)</string>
|
||||
<key>OpenClawCanonicalVersion</key>
|
||||
<string>$(OPENCLAW_IOS_VERSION)</string>
|
||||
<key>OpenClawPushMode</key>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<string>$(OPENCLAW_APNS_ENTITLEMENT_ENVIRONMENT)</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>$(OPENCLAW_APP_GROUP_ID)</string>
|
||||
<string>$(OPENCLAW_ACTIVE_APP_GROUP_ID)</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -125,7 +125,7 @@ final class ScreenWebViewCoordinator: NSObject {
|
||||
|
||||
// MARK: - Navigation Delegate
|
||||
|
||||
/// Handles navigation policy to intercept openclaw:// deep links from canvas
|
||||
/// Handles navigation policy to intercept OpenClaw deep links from canvas.
|
||||
@MainActor
|
||||
private final class ScreenNavigationDelegate: NSObject, WKNavigationDelegate {
|
||||
weak var controller: ScreenController?
|
||||
@@ -140,8 +140,8 @@ private final class ScreenNavigationDelegate: NSObject, WKNavigationDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
// Intercept openclaw:// deep links.
|
||||
if url.scheme?.lowercased() == "openclaw" {
|
||||
let scheme = url.scheme?.lowercased()
|
||||
if scheme == "openclaw" || scheme == "openclaw-debug" {
|
||||
decisionHandler(.cancel)
|
||||
self.controller?.onDeepLink?(url)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"images": [
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "notificationCenter",
|
||||
"subtype": "38mm",
|
||||
"size": "24x24",
|
||||
"scale": "2x",
|
||||
"filename": "watch-notification-38@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "notificationCenter",
|
||||
"subtype": "42mm",
|
||||
"size": "27.5x27.5",
|
||||
"scale": "2x",
|
||||
"filename": "watch-notification-42@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "companionSettings",
|
||||
"size": "29x29",
|
||||
"scale": "2x",
|
||||
"filename": "watch-companion-29@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "companionSettings",
|
||||
"size": "29x29",
|
||||
"scale": "3x",
|
||||
"filename": "watch-companion-29@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "appLauncher",
|
||||
"subtype": "38mm",
|
||||
"size": "40x40",
|
||||
"scale": "2x",
|
||||
"filename": "watch-app-38@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "appLauncher",
|
||||
"subtype": "40mm",
|
||||
"size": "44x44",
|
||||
"scale": "2x",
|
||||
"filename": "watch-app-40@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "appLauncher",
|
||||
"subtype": "41mm",
|
||||
"size": "46x46",
|
||||
"scale": "2x",
|
||||
"filename": "watch-app-41@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "appLauncher",
|
||||
"subtype": "44mm",
|
||||
"size": "50x50",
|
||||
"scale": "2x",
|
||||
"filename": "watch-app-44@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "appLauncher",
|
||||
"subtype": "45mm",
|
||||
"size": "51x51",
|
||||
"scale": "2x",
|
||||
"filename": "watch-app-45@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "quickLook",
|
||||
"subtype": "38mm",
|
||||
"size": "86x86",
|
||||
"scale": "2x",
|
||||
"filename": "watch-quicklook-38@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "quickLook",
|
||||
"subtype": "42mm",
|
||||
"size": "98x98",
|
||||
"scale": "2x",
|
||||
"filename": "watch-quicklook-42@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "quickLook",
|
||||
"subtype": "44mm",
|
||||
"size": "108x108",
|
||||
"scale": "2x",
|
||||
"filename": "watch-quicklook-44@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch",
|
||||
"role": "quickLook",
|
||||
"subtype": "45mm",
|
||||
"size": "117x117",
|
||||
"scale": "2x",
|
||||
"filename": "watch-quicklook-45@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom": "watch-marketing",
|
||||
"size": "1024x1024",
|
||||
"scale": "1x",
|
||||
"filename": "watch-marketing-1024.png"
|
||||
}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 69 KiB |
@@ -20,10 +20,6 @@
|
||||
<string>$(OPENCLAW_MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(OPENCLAW_BUILD_VERSION)</string>
|
||||
<key>WKApplication</key>
|
||||
<true/>
|
||||
<key>WKCompanionAppBundleIdentifier</key>
|
||||
<string>$(OPENCLAW_APP_BUNDLE_ID)</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>RedHatDisplay[wght].ttf</string>
|
||||
@@ -33,5 +29,9 @@
|
||||
<string>JetBrainsMono-Medium.ttf</string>
|
||||
<string>JetBrainsMono-SemiBold.ttf</string>
|
||||
</array>
|
||||
<key>WKApplication</key>
|
||||
<true/>
|
||||
<key>WKCompanionAppBundleIdentifier</key>
|
||||
<string>$(OPENCLAW_COMPANION_APP_BUNDLE_ID)</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -113,10 +113,14 @@ targets:
|
||||
swiftlint lint --config "$SRCROOT/.swiftlint.yml" --use-script-input-file-lists
|
||||
settings:
|
||||
base:
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
|
||||
CODE_SIGN_IDENTITY: "$(OPENCLAW_CODE_SIGN_IDENTITY)"
|
||||
CODE_SIGN_ENTITLEMENTS: "$(OPENCLAW_CODE_SIGN_ENTITLEMENTS)"
|
||||
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)"
|
||||
TARGETED_DEVICE_FAMILY: "1,2"
|
||||
@@ -127,8 +131,15 @@ targets:
|
||||
ENABLE_APP_INTENTS_METADATA_GENERATION: NO
|
||||
configs:
|
||||
Debug:
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIconDebug
|
||||
CODE_SIGN_STYLE: Automatic
|
||||
OPENCLAW_ACTIVE_APP_GROUP_ID: "$(OPENCLAW_DEBUG_APP_GROUP_ID)"
|
||||
OPENCLAW_APP_DISPLAY_NAME: OpenClaw Debug
|
||||
OPENCLAW_CODE_SIGN_ENTITLEMENTS: Sources/OpenClaw.entitlements
|
||||
OPENCLAW_APNS_ENTITLEMENT_ENVIRONMENT: development
|
||||
OPENCLAW_URL_SCHEME: openclaw-debug
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_APP_BUNDLE_ID)"
|
||||
PROVISIONING_PROFILE_SPECIFIER: ""
|
||||
OPENCLAW_PUSH_MODE: localSandbox
|
||||
OPENCLAW_PUSH_RELAY_BASE_URL: ""
|
||||
Release:
|
||||
@@ -139,15 +150,15 @@ targets:
|
||||
info:
|
||||
path: Sources/Info.plist
|
||||
properties:
|
||||
CFBundleDisplayName: OpenClaw
|
||||
CFBundleIconName: AppIcon
|
||||
CFBundleDisplayName: "$(OPENCLAW_APP_DISPLAY_NAME)"
|
||||
CFBundleIconName: "$(ASSETCATALOG_COMPILER_APPICON_NAME)"
|
||||
CFBundleURLTypes:
|
||||
- CFBundleURLName: ai.openclawfoundation.app
|
||||
CFBundleURLSchemes:
|
||||
- openclaw
|
||||
- "$(OPENCLAW_URL_SCHEME)"
|
||||
CFBundleShortVersionString: "$(OPENCLAW_MARKETING_VERSION)"
|
||||
OpenClawCanonicalVersion: "$(OPENCLAW_IOS_VERSION)"
|
||||
OpenClawAppGroupIdentifier: "$(OPENCLAW_APP_GROUP_ID)"
|
||||
OpenClawAppGroupIdentifier: "$(OPENCLAW_ACTIVE_APP_GROUP_ID)"
|
||||
CFBundleVersion: "$(OPENCLAW_BUILD_VERSION)"
|
||||
UILaunchScreen: {}
|
||||
UIApplicationSceneManifest:
|
||||
@@ -157,7 +168,7 @@ targets:
|
||||
- location
|
||||
- remote-notification
|
||||
BGTaskSchedulerPermittedIdentifiers:
|
||||
- "$(OPENCLAW_APP_BUNDLE_ID).bgrefresh"
|
||||
- "$(PRODUCT_BUNDLE_IDENTIFIER).bgrefresh"
|
||||
NSLocalNetworkUsageDescription: OpenClaw discovers and connects to your OpenClaw gateway on the local network.
|
||||
NSAppTransportSecurity:
|
||||
NSAllowsArbitraryLoadsInWebContent: true
|
||||
@@ -214,17 +225,24 @@ targets:
|
||||
DEVELOPMENT_TEAM: "$(OPENCLAW_DEVELOPMENT_TEAM)"
|
||||
ENABLE_APPINTENTS_METADATA: NO
|
||||
ENABLE_APP_INTENTS_METADATA_GENERATION: NO
|
||||
OPENCLAW_ACTIVE_APP_GROUP_ID: "$(OPENCLAW_APP_GROUP_ID)"
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_SHARE_BUNDLE_ID)"
|
||||
PROVISIONING_PROFILE_SPECIFIER: "$(OPENCLAW_SHARE_PROFILE)"
|
||||
TARGETED_DEVICE_FAMILY: "1,2"
|
||||
SWIFT_VERSION: "6.0"
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
configs:
|
||||
Debug:
|
||||
CODE_SIGN_STYLE: Automatic
|
||||
OPENCLAW_ACTIVE_APP_GROUP_ID: "$(OPENCLAW_DEBUG_APP_GROUP_ID)"
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_SHARE_BUNDLE_ID)"
|
||||
PROVISIONING_PROFILE_SPECIFIER: ""
|
||||
info:
|
||||
path: ShareExtension/Info.plist
|
||||
properties:
|
||||
CFBundleDisplayName: OpenClaw Share
|
||||
CFBundleShortVersionString: "$(OPENCLAW_MARKETING_VERSION)"
|
||||
OpenClawAppGroupIdentifier: "$(OPENCLAW_APP_GROUP_ID)"
|
||||
OpenClawAppGroupIdentifier: "$(OPENCLAW_ACTIVE_APP_GROUP_ID)"
|
||||
CFBundleVersion: "$(OPENCLAW_BUILD_VERSION)"
|
||||
NSExtension:
|
||||
NSExtensionPointIdentifier: com.apple.share-services
|
||||
@@ -263,6 +281,11 @@ targets:
|
||||
SWIFT_VERSION: "6.0"
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
SUPPORTS_LIVE_ACTIVITIES: YES
|
||||
configs:
|
||||
Debug:
|
||||
CODE_SIGN_STYLE: Automatic
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_ACTIVITY_WIDGET_BUNDLE_ID)"
|
||||
PROVISIONING_PROFILE_SPECIFIER: ""
|
||||
info:
|
||||
path: ActivityWidget/Info.plist
|
||||
properties:
|
||||
@@ -310,17 +333,25 @@ targets:
|
||||
DEVELOPMENT_TEAM: "$(OPENCLAW_DEVELOPMENT_TEAM)"
|
||||
ENABLE_APPINTENTS_METADATA: NO
|
||||
ENABLE_APP_INTENTS_METADATA_GENERATION: NO
|
||||
OPENCLAW_COMPANION_APP_BUNDLE_ID: "$(OPENCLAW_APP_BUNDLE_ID)"
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_WATCH_APP_BUNDLE_ID)"
|
||||
PROVISIONING_PROFILE_SPECIFIER: "$(OPENCLAW_WATCH_APP_PROFILE)"
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
SWIFT_VERSION: "6.0"
|
||||
configs:
|
||||
Debug:
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME: AppIconDebug
|
||||
CODE_SIGN_STYLE: Automatic
|
||||
OPENCLAW_COMPANION_APP_BUNDLE_ID: "$(OPENCLAW_DEBUG_APP_BUNDLE_ID)"
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_WATCH_APP_BUNDLE_ID)"
|
||||
PROVISIONING_PROFILE_SPECIFIER: ""
|
||||
info:
|
||||
path: WatchApp/Info.plist
|
||||
properties:
|
||||
CFBundleDisplayName: OpenClaw
|
||||
CFBundleShortVersionString: "$(OPENCLAW_MARKETING_VERSION)"
|
||||
CFBundleVersion: "$(OPENCLAW_BUILD_VERSION)"
|
||||
WKCompanionAppBundleIdentifier: "$(OPENCLAW_APP_BUNDLE_ID)"
|
||||
WKCompanionAppBundleIdentifier: "$(OPENCLAW_COMPANION_APP_BUNDLE_ID)"
|
||||
WKApplication: true
|
||||
UIAppFonts:
|
||||
- RedHatDisplay[wght].ttf
|
||||
@@ -356,6 +387,9 @@ targets:
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/OpenClaw.app/OpenClaw"
|
||||
BUNDLE_LOADER: "$(TEST_HOST)"
|
||||
configs:
|
||||
Debug:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_APP_BUNDLE_ID).tests"
|
||||
info:
|
||||
path: Tests/Info.plist
|
||||
properties:
|
||||
@@ -383,6 +417,9 @@ targets:
|
||||
SWIFT_EMIT_CONST_VALUE_PROTOCOLS: ""
|
||||
SWIFT_VERSION: "6.0"
|
||||
SWIFT_STRICT_CONCURRENCY: complete
|
||||
configs:
|
||||
Debug:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_APP_BUNDLE_ID).logic-tests"
|
||||
info:
|
||||
path: Tests/Info.plist
|
||||
properties:
|
||||
@@ -412,6 +449,9 @@ targets:
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD: NO
|
||||
TEST_TARGET_NAME: OpenClaw
|
||||
SWIFT_VERSION: "5.0"
|
||||
configs:
|
||||
Debug:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "$(OPENCLAW_DEBUG_APP_BUNDLE_ID).ui-tests"
|
||||
info:
|
||||
path: UITests/Info.plist
|
||||
properties:
|
||||
|
||||
@@ -215,7 +215,7 @@ public struct AgentDeepLink: Codable, Sendable, Equatable {
|
||||
public enum DeepLinkParser {
|
||||
public static func parse(_ url: URL) -> DeepLinkRoute? {
|
||||
guard let scheme = url.scheme?.lowercased(),
|
||||
scheme == "openclaw"
|
||||
scheme == "openclaw" || scheme == "openclaw-debug"
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@ private func setupCode(from payload: String) -> String {
|
||||
#expect(DeepLinkParser.parse(url) == .dashboard)
|
||||
}
|
||||
|
||||
@Test func debugDashboardDeepLinkParses() {
|
||||
let url = URL(string: "openclaw-debug://dashboard")!
|
||||
#expect(DeepLinkParser.parse(url) == .dashboard)
|
||||
}
|
||||
|
||||
@Test func gatewayDeepLinkRejectsInsecureNonLoopbackWs() {
|
||||
let url = URL(
|
||||
string: "openclaw://gateway?host=attacker.example&port=18789&tls=0&token=abc")!
|
||||
|
||||