fix(mac): webchat ws connect
parent
5f48abb451
commit
c8ca5803fc
|
|
@ -2,7 +2,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' data: blob:;">
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' data: blob:; connect-src 'self' ws://127.0.0.1:* ws://localhost:*;">
|
||||||
<title>Clawd Web Chat</title>
|
<title>Clawd Web Chat</title>
|
||||||
<link rel="stylesheet" href="app.css">
|
<link rel="stylesheet" href="app.css">
|
||||||
<style>
|
<style>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ final class WebChatWindowController: NSWindowController, WKNavigationDelegate, N
|
||||||
private var tunnel: WebChatTunnel?
|
private var tunnel: WebChatTunnel?
|
||||||
private var baseEndpoint: URL?
|
private var baseEndpoint: URL?
|
||||||
private let remotePort: Int
|
private let remotePort: Int
|
||||||
|
private var resolvedGatewayPort: Int?
|
||||||
private var reachabilityTask: Task<Void, Never>?
|
private var reachabilityTask: Task<Void, Never>?
|
||||||
private var tunnelRestartEnabled = false
|
private var tunnelRestartEnabled = false
|
||||||
private var bootWatchTask: Task<Void, Never>?
|
private var bootWatchTask: Task<Void, Never>?
|
||||||
|
|
@ -163,6 +164,7 @@ final class WebChatWindowController: NSWindowController, WKNavigationDelegate, N
|
||||||
code: 5,
|
code: 5,
|
||||||
userInfo: [NSLocalizedDescriptionKey: "Web chat disabled in settings"])
|
userInfo: [NSLocalizedDescriptionKey: "Web chat disabled in settings"])
|
||||||
}
|
}
|
||||||
|
self.resolvedGatewayPort = try await self.prepareGatewayPort()
|
||||||
let endpoint = try await self.prepareEndpoint(remotePort: self.remotePort)
|
let endpoint = try await self.prepareEndpoint(remotePort: self.remotePort)
|
||||||
self.baseEndpoint = endpoint
|
self.baseEndpoint = endpoint
|
||||||
self.reachabilityTask?.cancel()
|
self.reachabilityTask?.cancel()
|
||||||
|
|
@ -182,6 +184,14 @@ final class WebChatWindowController: NSWindowController, WKNavigationDelegate, N
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func prepareGatewayPort() async throws -> Int {
|
||||||
|
if CommandResolver.connectionModeIsRemote() {
|
||||||
|
let forwarded = try await RemoteTunnelManager.shared.ensureControlTunnel()
|
||||||
|
return Int(forwarded)
|
||||||
|
}
|
||||||
|
return GatewayEnvironment.gatewayPort()
|
||||||
|
}
|
||||||
|
|
||||||
private func prepareEndpoint(remotePort: Int) async throws -> URL {
|
private func prepareEndpoint(remotePort: Int) async throws -> URL {
|
||||||
if CommandResolver.connectionModeIsRemote() {
|
if CommandResolver.connectionModeIsRemote() {
|
||||||
try await self.startOrRestartTunnel()
|
try await self.startOrRestartTunnel()
|
||||||
|
|
@ -196,6 +206,9 @@ final class WebChatWindowController: NSWindowController, WKNavigationDelegate, N
|
||||||
comps?.path = "/"
|
comps?.path = "/"
|
||||||
}
|
}
|
||||||
var items = [URLQueryItem(name: "session", value: self.sessionKey)]
|
var items = [URLQueryItem(name: "session", value: self.sessionKey)]
|
||||||
|
let gatewayPort = self.resolvedGatewayPort ?? GatewayEnvironment.gatewayPort()
|
||||||
|
items.append(URLQueryItem(name: "gatewayPort", value: String(gatewayPort)))
|
||||||
|
items.append(URLQueryItem(name: "gatewayHost", value: baseEndpoint.host ?? "127.0.0.1"))
|
||||||
if let hostName = Host.current().localizedName ?? Host.current().name {
|
if let hostName = Host.current().localizedName ?? Host.current().name {
|
||||||
items.append(URLQueryItem(name: "host", value: hostName))
|
items.append(URLQueryItem(name: "host", value: hostName))
|
||||||
}
|
}
|
||||||
|
|
@ -621,12 +634,15 @@ final class WebChatManager {
|
||||||
func openInBrowser(sessionKey: String) async {
|
func openInBrowser(sessionKey: String) async {
|
||||||
let port = AppStateStore.webChatPort
|
let port = AppStateStore.webChatPort
|
||||||
let base: URL
|
let base: URL
|
||||||
|
let gatewayPort: Int
|
||||||
if CommandResolver.connectionModeIsRemote() {
|
if CommandResolver.connectionModeIsRemote() {
|
||||||
do {
|
do {
|
||||||
// Prefer the configured port; fall back if busy.
|
// Prefer the configured port; fall back if busy.
|
||||||
let tunnel = try await WebChatTunnel.create(
|
let tunnel = try await WebChatTunnel.create(
|
||||||
remotePort: port,
|
remotePort: port,
|
||||||
preferredLocalPort: UInt16(port))
|
preferredLocalPort: UInt16(port))
|
||||||
|
let forwarded = try await RemoteTunnelManager.shared.ensureControlTunnel()
|
||||||
|
gatewayPort = Int(forwarded)
|
||||||
self.browserTunnel?.terminate()
|
self.browserTunnel?.terminate()
|
||||||
self.browserTunnel = tunnel
|
self.browserTunnel = tunnel
|
||||||
guard let local = tunnel.localPort else {
|
guard let local = tunnel.localPort else {
|
||||||
|
|
@ -641,12 +657,17 @@ final class WebChatManager {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
gatewayPort = GatewayEnvironment.gatewayPort()
|
||||||
base = URL(string: "http://127.0.0.1:\(port)/")!
|
base = URL(string: "http://127.0.0.1:\(port)/")!
|
||||||
}
|
}
|
||||||
|
|
||||||
var comps = URLComponents(url: base, resolvingAgainstBaseURL: false)
|
var comps = URLComponents(url: base, resolvingAgainstBaseURL: false)
|
||||||
comps?.path = "/webchat/"
|
comps?.path = "/webchat/"
|
||||||
comps?.queryItems = [URLQueryItem(name: "session", value: sessionKey)]
|
comps?.queryItems = [
|
||||||
|
URLQueryItem(name: "session", value: sessionKey),
|
||||||
|
URLQueryItem(name: "gatewayPort", value: String(gatewayPort)),
|
||||||
|
URLQueryItem(name: "gatewayHost", value: base.host ?? "127.0.0.1"),
|
||||||
|
]
|
||||||
guard let url = comps?.url else { return }
|
guard let url = comps?.url else { return }
|
||||||
NSWorkspace.shared.open(url)
|
NSWorkspace.shared.open(url)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue