Skip to content

Commit e09d808

Browse files
committed
Merge branch 'feature/github-copilot-enterprise' into develop
2 parents dbbb30c + 079ad69 commit e09d808

10 files changed

Lines changed: 128 additions & 34 deletions

File tree

Core/Sources/HostApp/AccountSettings/GitHubCopilotView.swift

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct GitHubCopilotView: View {
1919
@AppStorage(\.gitHubCopilotProxyUsername) var gitHubCopilotProxyUsername
2020
@AppStorage(\.gitHubCopilotProxyPassword) var gitHubCopilotProxyPassword
2121
@AppStorage(\.gitHubCopilotUseStrictSSL) var gitHubCopilotUseStrictSSL
22+
@AppStorage(\.gitHubCopilotEnterpriseURI) var gitHubCopilotEnterpriseURI
2223
@AppStorage(\.gitHubCopilotIgnoreTrailingNewLines)
2324
var gitHubCopilotIgnoreTrailingNewLines
2425
@AppStorage(\.disableGitHubCopilotSettingsAutoRefreshOnAppear)
@@ -157,15 +158,15 @@ struct GitHubCopilotView: View {
157158
) {
158159
Text("Path to Node (v18+)")
159160
}
160-
161+
161162
Text(
162163
"Provide the path to the executable if it can't be found by the app, shim executable is not supported"
163164
)
164165
.lineLimit(10)
165166
.foregroundColor(.secondary)
166167
.font(.callout)
167168
.dynamicHeightTextInFormWorkaround()
168-
169+
169170
Picker(selection: $settings.runNodeWith) {
170171
ForEach(NodeRunner.allCases, id: \.rawValue) { runner in
171172
switch runner {
@@ -180,7 +181,7 @@ struct GitHubCopilotView: View {
180181
} label: {
181182
Text("Run Node with")
182183
}
183-
184+
184185
Group {
185186
switch settings.runNodeWith {
186187
case .env:
@@ -257,6 +258,10 @@ struct GitHubCopilotView: View {
257258
}
258259
.opacity(isRunningAction ? 0.8 : 1)
259260
.disabled(isRunningAction)
261+
262+
Button("Refresh Configuration for Enterprise and Proxy") {
263+
refreshConfiguration()
264+
}
260265
}
261266

262267
SettingsDivider("Advanced")
@@ -276,6 +281,17 @@ struct GitHubCopilotView: View {
276281
Toggle("Verbose Log", isOn: $settings.gitHubCopilotVerboseLog)
277282
}
278283

284+
SettingsDivider("Enterprise")
285+
286+
Form {
287+
TextField(
288+
text: $settings.gitHubCopilotEnterpriseURI,
289+
prompt: Text("Leave it blank if non is available.")
290+
) {
291+
Text("Auth Provider URL")
292+
}
293+
}
294+
279295
SettingsDivider("Proxy")
280296

281297
Form {
@@ -403,6 +419,25 @@ struct GitHubCopilotView: View {
403419
}
404420
}
405421
}
422+
423+
func refreshConfiguration() {
424+
NotificationCenter.default.post(
425+
name: .gitHubCopilotShouldRefreshEditorInformation,
426+
object: nil
427+
)
428+
429+
Task {
430+
let service = try getService()
431+
do {
432+
try await service.postNotification(
433+
name: Notification.Name
434+
.gitHubCopilotShouldRefreshEditorInformation.rawValue
435+
)
436+
} catch {
437+
toast(error.localizedDescription, .error)
438+
}
439+
}
440+
}
406441
}
407442

408443
struct ActivityIndicatorView: NSViewRepresentable {

Core/Sources/Service/XPCService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ public class XPCService: NSObject, XPCServiceProtocol {
187187

188188
public func postNotification(name: String, withReply reply: @escaping () -> Void) {
189189
reply()
190-
NSWorkspace.shared.notificationCenter.post(name: .init(name), object: nil)
190+
NotificationCenter.default.post(name: .init(name), object: nil)
191191
}
192192

193193
// MARK: - Requests

Pro

Submodule Pro updated from 9c11324 to 528831a

Tool/Sources/AsyncPassthroughSubject/AsyncPassthroughSubject.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public actor AsyncPassthroughSubject<Element> {
2020
AsyncStream { [weak self, name] continuation in
2121
let task = Task { [weak self] in
2222
await self?.storeContinuation(continuation)
23-
let notifications = NSWorkspace.shared.notificationCenter.notifications(named: name)
23+
let notifications = NotificationCenter.default.notifications(named: name)
2424
.compactMap {
2525
$0.object as? Element
2626
}
@@ -46,7 +46,7 @@ public actor AsyncPassthroughSubject<Element> {
4646
}
4747

4848
func _send(_ element: Element) {
49-
NSWorkspace.shared.notificationCenter.post(name: name, object: element)
49+
NotificationCenter.default.post(name: name, object: element)
5050
}
5151

5252
func storeContinuation(_ continuation: AsyncStream<Element>.Continuation) {

Tool/Sources/GitHubCopilotService/GitHubCopilotInstallationManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public struct GitHubCopilotInstallationManager {
1010
return URL(string: link)!
1111
}
1212

13-
static let latestSupportedVersion = "1.17.0"
13+
static let latestSupportedVersion = "1.19.2"
1414

1515
public init() {}
1616

Tool/Sources/GitHubCopilotService/GitHubCopilotRequest.swift

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ public struct GitHubCopilotCodeSuggestion: Codable, Equatable {
4949
public var displayText: String
5050
}
5151

52-
5352
enum GitHubCopilotRequest {
5453
struct SetEditorInfo: GitHubCopilotRequestType {
5554
struct Response: Codable {}
@@ -81,22 +80,58 @@ enum GitHubCopilotRequest {
8180
}
8281
}
8382

84-
var request: ClientRequest {
85-
if let networkProxy {
86-
return .custom("setEditorInfo", .hash([
87-
"editorInfo": .hash([
88-
"name": "Xcode",
89-
"version": "",
90-
]),
91-
"editorPluginInfo": .hash([
92-
"name": "Copilot for Xcode",
93-
"version": "",
94-
]),
95-
"networkProxy": networkProxy,
96-
]))
83+
var http: JSONValue? {
84+
var dict: [String: JSONValue] = [:]
85+
let host = UserDefaults.shared.value(for: \.gitHubCopilotProxyHost)
86+
if host.isEmpty { return nil }
87+
var port = UserDefaults.shared.value(for: \.gitHubCopilotProxyPort)
88+
if port.isEmpty { port = "80" }
89+
let username = UserDefaults.shared.value(for: \.gitHubCopilotProxyUsername)
90+
let password = UserDefaults.shared.value(for: \.gitHubCopilotProxyPassword)
91+
let strictSSL = UserDefaults.shared.value(for: \.gitHubCopilotUseStrictSSL)
92+
93+
let url = if !username.isEmpty {
94+
"http://\(username):\(password)@\(host):\(port)"
95+
} else {
96+
"http://\(host):\(port)"
9797
}
9898

99-
return .custom("setEditorInfo", .hash([
99+
dict["proxy"] = .string(url)
100+
dict["proxyStrictSSL"] = .bool(strictSSL)
101+
102+
if dict.isEmpty { return nil }
103+
104+
return .hash(dict)
105+
}
106+
107+
var editorConfiguration: JSONValue? {
108+
var dict: [String: JSONValue] = [:]
109+
dict["http"] = http
110+
111+
let enterpriseURI = UserDefaults.shared.value(for: \.gitHubCopilotEnterpriseURI)
112+
if !enterpriseURI.isEmpty {
113+
dict["github-enterprise"] = .hash([
114+
"uri": .string(enterpriseURI),
115+
])
116+
}
117+
118+
if dict.isEmpty { return nil }
119+
return .hash(dict)
120+
}
121+
122+
var authProvider: JSONValue? {
123+
var dict: [String: JSONValue] = [:]
124+
let enterpriseURI = UserDefaults.shared.value(for: \.gitHubCopilotEnterpriseURI)
125+
if !enterpriseURI.isEmpty {
126+
dict["url"] = .string(enterpriseURI)
127+
}
128+
129+
if dict.isEmpty { return nil }
130+
return .hash(dict)
131+
}
132+
133+
var request: ClientRequest {
134+
var dict: [String: JSONValue] = [
100135
"editorInfo": .hash([
101136
"name": "Xcode",
102137
"version": "",
@@ -105,7 +140,13 @@ enum GitHubCopilotRequest {
105140
"name": "Copilot for Xcode",
106141
"version": "",
107142
]),
108-
]))
143+
]
144+
145+
dict["editorConfiguration"] = editorConfiguration
146+
dict["authProvider"] = authProvider
147+
dict["networkProxy"] = networkProxy
148+
149+
return .custom("setEditorInfo", .hash(dict))
109150
}
110151
}
111152

Tool/Sources/GitHubCopilotService/GitHubCopilotService.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import AppKit
12
import Foundation
23
import LanguageClient
34
import LanguageServerProtocol
@@ -51,6 +52,11 @@ enum GitHubCopilotError: Error, LocalizedError {
5152
}
5253
}
5354

55+
public extension Notification.Name {
56+
static let gitHubCopilotShouldRefreshEditorInformation = Notification
57+
.Name("com.intii.CopilotForXcode.GitHubCopilotShouldRefreshEditorInformation")
58+
}
59+
5460
public class GitHubCopilotBaseService {
5561
let projectRootURL: URL
5662
var server: GitHubCopilotLSP
@@ -160,8 +166,16 @@ public class GitHubCopilotBaseService {
160166
self.server = server
161167
localProcessServer = localServer
162168

163-
Task {
164-
try await server.sendRequest(GitHubCopilotRequest.SetEditorInfo())
169+
Task { [weak self] in
170+
_ = try? await server.sendRequest(GitHubCopilotRequest.SetEditorInfo())
171+
172+
for await notification in NotificationCenter.default
173+
.notifications(named: .gitHubCopilotShouldRefreshEditorInformation)
174+
{
175+
print("Yes!")
176+
guard let self else { return }
177+
_ = try? await server.sendRequest(GitHubCopilotRequest.SetEditorInfo())
178+
}
165179
}
166180
}
167181

Tool/Sources/OpenAIService/Debug/Debug.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ enum Debugger {
99
static func didSendRequestBody(body: CompletionRequestBody) {
1010
do {
1111
let json = try JSONEncoder().encode(body)
12-
let center = NSWorkspace.shared.notificationCenter
12+
let center = NotificationCenter.default
1313
center.post(
1414
name: .init("ServiceDebugger.ChatRequestDebug.requestSent"),
1515
object: nil,
@@ -24,7 +24,7 @@ enum Debugger {
2424
}
2525

2626
static func didReceiveFunction(name: String, arguments: String) {
27-
let center = NSWorkspace.shared.notificationCenter
27+
let center = NotificationCenter.default
2828
center.post(
2929
name: .init("ServiceDebugger.ChatRequestDebug.receivedFunctionCall"),
3030
object: nil,
@@ -37,7 +37,7 @@ enum Debugger {
3737
}
3838

3939
static func didReceiveFunctionResult(result: String) {
40-
let center = NSWorkspace.shared.notificationCenter
40+
let center = NotificationCenter.default
4141
center.post(
4242
name: .init("ServiceDebugger.ChatRequestDebug.receivedFunctionResult"),
4343
object: nil,
@@ -49,7 +49,7 @@ enum Debugger {
4949
}
5050

5151
static func didReceiveResponse(content: String) {
52-
let center = NSWorkspace.shared.notificationCenter
52+
let center = NotificationCenter.default
5353
center.post(
5454
name: .init("ServiceDebugger.ChatRequestDebug.responseReceived"),
5555
object: nil,
@@ -61,7 +61,7 @@ enum Debugger {
6161
}
6262

6363
static func didFinish() {
64-
let center = NSWorkspace.shared.notificationCenter
64+
let center = NotificationCenter.default
6565
center.post(
6666
name: .init("ServiceDebugger.ChatRequestDebug.finished"),
6767
object: nil,

Tool/Sources/Preferences/Keys.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ public extension UserDefaultPreferenceKeys {
163163
var gitHubCopilotProxyPort: PreferenceKey<String> {
164164
.init(defaultValue: "", key: "GitHubCopilotProxyPort")
165165
}
166+
167+
var gitHubCopilotEnterpriseURI: PreferenceKey<String> {
168+
.init(defaultValue: "", key: "GitHubCopilotEnterpriseURI")
169+
}
166170

167171
var gitHubCopilotUseStrictSSL: PreferenceKey<Bool> {
168172
.init(defaultValue: true, key: "GitHubCopilotUseStrictSSL")

Tool/Sources/XcodeInspector/XcodeInspector.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public final class XcodeInspector: ObservableObject {
222222
}
223223

224224
group.addTask { [weak self] in // malfunctioning
225-
let sequence = NSWorkspace.shared.notificationCenter
225+
let sequence = NotificationCenter.default
226226
.notifications(named: .accessibilityAPIMalfunctioning)
227227
for await notification in sequence {
228228
try Task.checkCancellation()
@@ -347,15 +347,15 @@ public final class XcodeInspector: ObservableObject {
347347
else { return }
348348

349349
if let editor = focusedEditor, !editor.element.isSourceEditor {
350-
NSWorkspace.shared.notificationCenter.post(
350+
NotificationCenter.default.post(
351351
name: .accessibilityAPIMalfunctioning,
352352
object: "Source Editor Element Corrupted: \(source)"
353353
)
354354
} else if let element = activeXcode?.appElement.focusedElement {
355355
if element.description != focusedElement?.description ||
356356
element.role != focusedElement?.role
357357
{
358-
NSWorkspace.shared.notificationCenter.post(
358+
NotificationCenter.default.post(
359359
name: .accessibilityAPIMalfunctioning,
360360
object: "Element Inconsistency: \(source)"
361361
)

0 commit comments

Comments
 (0)