Skip to content

Commit 8a3f073

Browse files
committed
Merge tag '0.18.3' into develop
# Conflicts: # Core/Sources/Service/SuggestionCommandHandler/PseudoCommandHandler.swift # Tool/Package.swift
2 parents 0e06566 + ccdf016 commit 8a3f073

39 files changed

+974
-1039
lines changed

Core/Package.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ let package = Package(
107107
dependencies: [
108108
"ActiveApplicationMonitor",
109109
"AXExtension",
110-
"SuggestionService",
110+
.product(name: "Preferences", package: "Tool"),
111111
]
112112
),
113113

@@ -261,6 +261,7 @@ let package = Package(
261261
name: "XcodeInspector",
262262
dependencies: [
263263
"AXExtension",
264+
"SuggestionModel",
264265
"Environment",
265266
"AXNotificationStream",
266267
.product(name: "Logger", package: "Tool"),
@@ -294,6 +295,7 @@ let package = Package(
294295
"LanguageClient",
295296
"SuggestionModel",
296297
"KeychainAccess",
298+
"XcodeInspector",
297299
.product(name: "Preferences", package: "Tool"),
298300
.product(name: "Terminal", package: "Tool"),
299301
]

Core/Sources/AXExtension/AXUIElement.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ public extension AXUIElement {
6363
var isEnabled: Bool {
6464
(try? copyValue(key: kAXEnabledAttribute)) ?? false
6565
}
66+
67+
var isHidden: Bool {
68+
(try? copyValue(key: kAXHiddenAttribute)) ?? false
69+
}
6670
}
6771

6872
// MARK: - Rect

Core/Sources/AXNotificationStream/AXNotificationStream.swift

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public final class AXNotificationStream: AsyncSequence {
66
public typealias Stream = AsyncStream<Element>
77
public typealias Continuation = Stream.Continuation
88
public typealias AsyncIterator = Stream.AsyncIterator
9-
public typealias Element = (name: String, info: CFDictionary)
9+
public typealias Element = (name: String, element: AXUIElement, info: CFDictionary)
1010

1111
private var continuation: Continuation
1212
private let stream: Stream
@@ -48,7 +48,7 @@ public final class AXNotificationStream: AsyncSequence {
4848
) {
4949
guard let pointer = pointer?.assumingMemoryBound(to: Continuation.self)
5050
else { return }
51-
pointer.pointee.yield((notificationName as String, userInfo))
51+
pointer.pointee.yield((notificationName as String, element, userInfo))
5252
}
5353

5454
_ = AXObserverCreateWithInfoCallback(
@@ -72,13 +72,24 @@ public final class AXNotificationStream: AsyncSequence {
7272
.commonModes
7373
)
7474
}
75-
for name in notificationNames {
76-
AXObserverAddNotification(observer, observingElement, name as CFString, &continuation)
75+
76+
Task {
77+
for name in notificationNames {
78+
var error = AXError.cannotComplete
79+
var retryCount = 0
80+
while error == AXError.cannotComplete, retryCount < 5 {
81+
error = AXObserverAddNotification(observer, observingElement, name as CFString, &continuation)
82+
if error == .cannotComplete {
83+
try await Task.sleep(nanoseconds: 1_000_000_000)
84+
}
85+
retryCount += 1
86+
}
87+
}
88+
CFRunLoopAddSource(
89+
CFRunLoopGetMain(),
90+
AXObserverGetRunLoopSource(observer),
91+
.commonModes
92+
)
7793
}
78-
CFRunLoopAddSource(
79-
CFRunLoopGetMain(),
80-
AXObserverGetRunLoopSource(observer),
81-
.commonModes
82-
)
8394
}
8495
}

Core/Sources/CodeiumService/CodeiumInstallationManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Terminal
33

44
public struct CodeiumInstallationManager {
55
private static var isInstalling = false
6-
static let latestSupportedVersion = "1.2.25"
6+
static let latestSupportedVersion = "1.2.40"
77

88
public init() {}
99

Core/Sources/CodeiumService/CodeiumService.swift

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import LanguageClient
33
import LanguageServerProtocol
44
import Logger
55
import SuggestionModel
6+
import XcodeInspector
67

78
public protocol CodeiumSuggestionServiceType {
89
func getCompletions(
@@ -54,9 +55,9 @@ public class CodeiumSuggestionService {
5455

5556
let authService = CodeiumAuthService()
5657

57-
var xcodeVersion = "14.0.0"
58+
var fallbackXcodeVersion = "14.0.0"
5859
var languageServerVersion = CodeiumInstallationManager.latestSupportedVersion
59-
60+
6061
private var ongoingTasks = Set<Task<[CodeSuggestion], Error>>()
6162

6263
init(designatedServer: CodeiumLSP) {
@@ -95,13 +96,6 @@ public class CodeiumSuggestionService {
9596
}
9697

9798
let metadata = try getMetadata()
98-
xcodeVersion = (try? await getXcodeVersion()) ?? xcodeVersion
99-
let versionNumberSegmentCount = xcodeVersion.split(separator: ".").count
100-
if versionNumberSegmentCount == 2 {
101-
xcodeVersion += ".0"
102-
} else if versionNumberSegmentCount == 1 {
103-
xcodeVersion += ".0.0"
104-
}
10599
let tempFolderURL = FileManager.default.temporaryDirectory
106100
let managerDirectoryURL = tempFolderURL
107101
.appendingPathComponent("com.intii.CopilotForXcode")
@@ -192,9 +186,16 @@ extension CodeiumSuggestionService {
192186
}
193187
throw E()
194188
}
189+
var ideVersion = XcodeInspector.shared.latestActiveXcode?.version ?? fallbackXcodeVersion
190+
let versionNumberSegmentCount = ideVersion.split(separator: ".").count
191+
if versionNumberSegmentCount == 2 {
192+
ideVersion += ".0"
193+
} else if versionNumberSegmentCount == 1 {
194+
ideVersion += ".0.0"
195+
}
195196
return Metadata(
196197
ide_name: "xcode",
197-
ide_version: xcodeVersion,
198+
ide_version: ideVersion,
198199
extension_version: languageServerVersion,
199200
api_key: key,
200201
session_id: CodeiumSuggestionService.sessionId,
@@ -231,11 +232,11 @@ extension CodeiumSuggestionService: CodeiumSuggestionServiceType {
231232
ongoingTasks.forEach { $0.cancel() }
232233
ongoingTasks.removeAll()
233234
await cancelRequest()
234-
235+
235236
requestCounter += 1
236237
let languageId = languageIdentifierFromFileURL(fileURL)
237238
let relativePath = getRelativePath(of: fileURL)
238-
239+
239240
let task = Task {
240241
let request = await CodeiumRequest.GetCompletion(requestBody: .init(
241242
metadata: try getMetadata(),
@@ -263,11 +264,11 @@ extension CodeiumSuggestionService: CodeiumSuggestionServiceType {
263264
)
264265
}
265266
))
266-
267+
267268
try Task.checkCancellation()
268269

269270
let result = try await (try await setupServerIfNeeded()).sendRequest(request)
270-
271+
271272
try Task.checkCancellation()
272273

273274
return result.completionItems?.filter { item in
@@ -294,7 +295,7 @@ extension CodeiumSuggestionService: CodeiumSuggestionServiceType {
294295
)
295296
} ?? []
296297
}
297-
298+
298299
ongoingTasks.insert(task)
299300

300301
return try await task.value

Core/Sources/Environment/Environment.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import ActiveApplicationMonitor
22
import AppKit
33
import AXExtension
44
import Foundation
5-
import GitHubCopilotService
65
import Logger
7-
import SuggestionService
6+
import Preferences
87

98
public struct NoAccessToAccessibilityAPIError: Error, LocalizedError {
109
public var errorDescription: String? {
@@ -134,13 +133,6 @@ public enum Environment {
134133
}
135134
}
136135

137-
public static var createSuggestionService: (
138-
_ projectRootURL: URL,
139-
_ onServiceLaunched: @escaping (SuggestionServiceType) -> Void
140-
) -> SuggestionServiceType = { projectRootURL, onServiceLaunched in
141-
SuggestionService(projectRootURL: projectRootURL, onServiceLaunched: onServiceLaunched)
142-
}
143-
144136
public static var triggerAction: (_ name: String) async throws -> Void = { name in
145137
guard let activeXcode = ActiveApplicationMonitor.activeXcode
146138
?? ActiveApplicationMonitor.latestXcode

Core/Sources/HostApp/DebugView.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ final class DebugSettings: ObservableObject {
88
@AppStorage(\.preCacheOnFileOpen) var preCacheOnFileOpen
99
@AppStorage(\.useCustomScrollViewWorkaround) var useCustomScrollViewWorkaround
1010
@AppStorage(\.triggerActionWithAccessibilityAPI) var triggerActionWithAccessibilityAPI
11+
@AppStorage(\.alwaysAcceptSuggestionWithAccessibilityAPI)
12+
var alwaysAcceptSuggestionWithAccessibilityAPI
1113
init() {}
1214
}
1315

@@ -35,6 +37,9 @@ struct DebugSettingsView: View {
3537
Toggle(isOn: $settings.triggerActionWithAccessibilityAPI) {
3638
Text("Trigger command with AccessibilityAPI")
3739
}
40+
Toggle(isOn: $settings.alwaysAcceptSuggestionWithAccessibilityAPI) {
41+
Text("Always accept suggestion with AccessibilityAPI")
42+
}
3843
}
3944
.padding()
4045
}

Core/Sources/HostApp/FeatureSettings/SuggestionSettingsView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ struct SuggestionSettingsView: View {
3232
Picker(selection: $settings.suggestionPresentationMode) {
3333
ForEach(PresentationMode.allCases, id: \.rawValue) {
3434
switch $0 {
35-
case .comment:
36-
Text("Comment (Deprecating Soon)").tag($0)
35+
case .nearbyTextCursor:
36+
Text("Nearby Text Cursor").tag($0)
3737
case .floatingWidget:
3838
Text("Floating Widget").tag($0)
3939
}

Core/Sources/HostApp/LaunchAgentManager.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ extension LaunchAgentManager {
1313
.appendingPathComponent(
1414
"CopilotForXcodeExtensionService.app/Contents/MacOS/CopilotForXcodeExtensionService"
1515
)
16-
.path
16+
.path,
17+
bundleIdentifier: Bundle.main
18+
.object(forInfoDictionaryKey: "BUNDLE_IDENTIFIER_BASE") as! String
1719
)
1820
}
1921
}

Core/Sources/LaunchAgentManager/LaunchAgentManager.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import Foundation
22

3+
#warning("TODO: Migrate to SMAppService")
34
public struct LaunchAgentManager {
45
let lastLaunchAgentVersionKey = "LastLaunchAgentVersion"
56
let serviceIdentifier: String
67
let executablePath: String
8+
let bundleIdentifier: String
79

810
var launchAgentDirURL: URL {
911
FileManager.default.homeDirectoryForCurrentUser
@@ -14,9 +16,10 @@ public struct LaunchAgentManager {
1416
launchAgentDirURL.appendingPathComponent("\(serviceIdentifier).plist").path
1517
}
1618

17-
public init(serviceIdentifier: String, executablePath: String) {
19+
public init(serviceIdentifier: String, executablePath: String, bundleIdentifier: String) {
1820
self.serviceIdentifier = serviceIdentifier
1921
self.executablePath = executablePath
22+
self.bundleIdentifier = bundleIdentifier
2023
}
2124

2225
public func setupLaunchAgentForTheFirstTimeIfNeeded() async throws {
@@ -44,6 +47,11 @@ public struct LaunchAgentManager {
4447
<key>\(serviceIdentifier)</key>
4548
<true/>
4649
</dict>
50+
<key>AssociatedBundleIdentifiers</key>
51+
<array>
52+
<string>\(bundleIdentifier)</string>
53+
<string>\(serviceIdentifier)</string>
54+
</array>
4755
</dict>
4856
</plist>
4957
"""

0 commit comments

Comments
 (0)