From d754c3add0a8edc0dae1304c46816dd228e0b1f7 Mon Sep 17 00:00:00 2001 From: Eva Date: Tue, 26 May 2026 03:43:54 +0700 Subject: [PATCH] feat(macos): open OpenWorlds play surface --- .../Sources/ClawDnDApp/Models/LocalEndpoint.swift | 4 ++++ .../ClawDnDApp/Services/AppProcessService.swift | 14 +++++++------- .../Sources/ClawDnDApp/Views/CampaignsView.swift | 2 +- .../Sources/ClawDnDApp/Views/MonitorView.swift | 4 ++-- .../Sources/ClawDnDApp/Views/PlayView.swift | 2 +- .../Sources/ClawDnDApp/Views/WebView.swift | 4 ++-- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/macos/ClawDnDApp/Sources/ClawDnDApp/Models/LocalEndpoint.swift b/macos/ClawDnDApp/Sources/ClawDnDApp/Models/LocalEndpoint.swift index 6016c952..e124b345 100644 --- a/macos/ClawDnDApp/Sources/ClawDnDApp/Models/LocalEndpoint.swift +++ b/macos/ClawDnDApp/Sources/ClawDnDApp/Models/LocalEndpoint.swift @@ -22,6 +22,10 @@ struct LocalEndpoint: Identifiable, Equatable { url.appendingPathComponent("dashboard") } + var openWorldsURL: URL { + url.appendingPathComponent("openworlds") + } + var monitorURL: URL { url.appendingPathComponent("monitor") } diff --git a/macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift b/macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift index 335e8692..2e7bd6f9 100644 --- a/macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift +++ b/macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift @@ -70,7 +70,6 @@ final class AppProcessService: ObservableObject { try throwAndRecord("Could not find a free viewer port near \(preferredPort).") } let baseURL = URL(string: "http://127.0.0.1:\(port)")! - let dashboard = baseURL.appendingPathComponent("dashboard") var env: [String: String] = [:] if !stateDir.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { env["CLAWDND_STATE_DIR"] = (stateDir as NSString).expandingTildeInPath @@ -86,14 +85,15 @@ final class AppProcessService: ObservableObject { ) viewerProcess = managed activeCampaignID = campaignID - viewerEndpoint = LocalEndpoint( + let endpoint = LocalEndpoint( name: "Viewer", url: baseURL, healthPath: "/state", status: .running ) - append("Started viewer pid \(managed.pid) on \(dashboard.absoluteString)", stream: .supervisor) - return dashboard + viewerEndpoint = endpoint + append("Started viewer pid \(managed.pid) on \(endpoint.openWorldsURL.absoluteString)", stream: .supervisor) + return endpoint.openWorldsURL } func stopViewer() { @@ -177,15 +177,15 @@ final class AppProcessService: ObservableObject { providerProcess = managed runningProvider = kind let baseURL = URL(string: "http://127.0.0.1:\(port)")! - let dashboard = baseURL.appendingPathComponent("dashboard") - viewerEndpoint = LocalEndpoint( + let endpoint = LocalEndpoint( name: "Provider viewer", url: baseURL, healthPath: "/state", status: .starting ) + viewerEndpoint = endpoint append("\(request.message) pid \(managed.pid)", stream: .provider) - return dashboard + return endpoint.openWorldsURL } func stopProvider() { diff --git a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/CampaignsView.swift b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/CampaignsView.swift index 7875991e..a965045a 100644 --- a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/CampaignsView.swift +++ b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/CampaignsView.swift @@ -39,7 +39,7 @@ struct CampaignsView: View { CampaignRow(campaign: campaign) .tag(campaign.id) .contextMenu { - Button("Open in Dashboard") { + Button("Open in Play Surface") { open(campaign) } } diff --git a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/MonitorView.swift b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/MonitorView.swift index e5dfbc7d..6d51b642 100644 --- a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/MonitorView.swift +++ b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/MonitorView.swift @@ -50,13 +50,13 @@ struct MonitorView: View { private func openMonitor() { do { webViewErrorMessage = nil - let dashboard = try processService.startViewer( + let surface = try processService.startViewer( repoPath: repoPath, preferredPort: preferredPort, stateDir: stateDir ) webURL = processService.viewerEndpoint?.monitorURL - ?? dashboard.deletingLastPathComponent().appendingPathComponent("monitor") + ?? surface.deletingLastPathComponent().appendingPathComponent("monitor") } catch { alertMessage = error.localizedDescription } diff --git a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/PlayView.swift b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/PlayView.swift index 71378702..333bcb8e 100644 --- a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/PlayView.swift +++ b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/PlayView.swift @@ -64,7 +64,7 @@ struct PlayView: View { Button { startViewer() } label: { - Label("Open Dashboard", systemImage: "rectangle.on.rectangle") + Label("Open Play Surface", systemImage: "rectangle.on.rectangle") } Button { startProvider() diff --git a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/WebView.swift b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/WebView.swift index 72a04451..a6405b52 100644 --- a/macos/ClawDnDApp/Sources/ClawDnDApp/Views/WebView.swift +++ b/macos/ClawDnDApp/Sources/ClawDnDApp/Views/WebView.swift @@ -48,7 +48,7 @@ struct WebView: NSViewRepresentable { private func report(_ error: Error) { let nsError = error as NSError guard nsError.domain != NSURLErrorDomain || nsError.code != NSURLErrorCancelled else { return } - navigationError.wrappedValue = "Dashboard failed to load: \(error.localizedDescription)" + navigationError.wrappedValue = "Surface failed to load: \(error.localizedDescription)" } } } @@ -62,7 +62,7 @@ struct WebViewErrorView: View { Image(systemName: "exclamationmark.triangle") .font(.system(size: 42, weight: .regular)) .foregroundStyle(.orange) - Text("Dashboard Unavailable") + Text("Surface Unavailable") .font(.title3.weight(.semibold)) Text(message) .font(.callout)