Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc32cc7c

Browse files
committed
Pre-release 0.32.111
1 parenta50045a commitc32cc7c

File tree

11 files changed

+132
-20
lines changed

11 files changed

+132
-20
lines changed

‎Copilot for Xcode/App.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,28 @@ struct VisualEffect: NSViewRepresentable {
1313
}
1414

1515
classAppDelegate:NSObject,NSApplicationDelegate{
16+
privatevarpermissionAlertShown=false
17+
1618
// Launch modes supported by the app
1719
enumLaunchMode{
1820
case chat
1921
case settings
2022
}
2123

2224
func applicationDidFinishLaunching(_ notification:Notification){
25+
if #available(macOS13.0,*){
26+
checkBackgroundPermissions()
27+
}
28+
2329
letlaunchMode=determineLaunchMode()
2430
handleLaunchMode(launchMode)
2531
}
2632

2733
func applicationShouldHandleReopen(_ sender:NSApplication, hasVisibleWindows flag:Bool)->Bool{
34+
if #available(macOS13.0,*){
35+
checkBackgroundPermissions()
36+
}
37+
2838
letlaunchMode=determineLaunchMode()
2939
handleLaunchMode(launchMode)
3040
returntrue
@@ -73,6 +83,28 @@ class AppDelegate: NSObject, NSApplicationDelegate {
7383
}
7484
}
7585

86+
@available(macOS13.0,*)
87+
privatefunc checkBackgroundPermissions(){
88+
Task{
89+
// Direct check of permission status
90+
letlaunchAgentManager=LaunchAgentManager()
91+
letisPermissionGranted=await launchAgentManager.isBackgroundPermissionGranted()
92+
93+
if !isPermissionGranted{
94+
// Only show alert if permission isn't granted
95+
DispatchQueue.main.async{
96+
if !self.permissionAlertShown{
97+
showBackgroundPermissionAlert()
98+
self.permissionAlertShown=true
99+
}
100+
}
101+
}else{
102+
// Permission is granted, reset flag
103+
self.permissionAlertShown=false
104+
}
105+
}
106+
}
107+
76108
// MARK: - Application Termination
77109

78110
func applicationShouldTerminate(_ sender:NSApplication)->NSApplication.TerminateReply{

‎Core/Sources/ConversationTab/ChatPanel.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -761,11 +761,24 @@ struct ChatPanelInputArea: View {
761761
return result
762762
}
763763
func subscribeToActiveDocumentChangeEvent(){
764-
XcodeInspector.shared.$activeDocumentURL.receive(on:DispatchQueue.main)
765-
.sink{ newDocURLin
766-
if supportedFileExtensions.contains(newDocURL?.pathExtension??""){
767-
letcurrentEditor=FileReference(url: newDocURL!, isCurrentEditor:true)
768-
chat.send(.setCurrentEditor(currentEditor))
764+
Publishers.CombineLatest(
765+
XcodeInspector.shared.$latestActiveXcode,
766+
XcodeInspector.shared.$activeDocumentURL
767+
.removeDuplicates()
768+
)
769+
.receive(on:DispatchQueue.main)
770+
.sink{ newXcode, newDocURLin
771+
// First check for realtimeWorkspaceURL if activeWorkspaceURL is nil
772+
iflet realtimeURL= newXcode?.realtimeDocumentURL, newDocURL==nil{
773+
if supportedFileExtensions.contains(realtimeURL.pathExtension){
774+
letcurrentEditor=FileReference(url: realtimeURL, isCurrentEditor:true)
775+
chat.send(.setCurrentEditor(currentEditor))
776+
}
777+
}else{
778+
if supportedFileExtensions.contains(newDocURL?.pathExtension??""){
779+
letcurrentEditor=FileReference(url: newDocURL!, isCurrentEditor:true)
780+
chat.send(.setCurrentEditor(currentEditor))
781+
}
769782
}
770783
}
771784
.store(in:&cancellable)

‎Core/Sources/HostApp/General.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public struct General {
5858
.setupLaunchAgentForTheFirstTimeIfNeeded()
5959
}catch{
6060
Logger.ui.error("Failed to setup launch agent.\(error.localizedDescription)")
61-
toast(error.localizedDescription,.error)
61+
toast("Operation failed: permission denied. This may be due to missing background permissions.",.error)
6262
}
6363
awaitsend(.reloadStatus)
6464
}
@@ -103,7 +103,7 @@ public struct General {
103103
}catchlet error asXPCCommunicationBridgeError{
104104
Logger.ui.error("Failed to reach communication bridge.\(error.localizedDescription)")
105105
toast(
106-
"Failed toreachcommunication bridge.\(error.localizedDescription)",
106+
"Unable toconnect to thecommunication bridge.The helper application didn't respond. This may be due to missing background permissions.",
107107
.error
108108
)
109109
awaitsend(.failedReloading)

‎Core/Sources/HostApp/LaunchAgentManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Foundation
22
import LaunchAgentManager
33

4-
extensionLaunchAgentManager{
4+
publicextensionLaunchAgentManager{
55
init(){
66
self.init(
77
serviceIdentifier:Bundle.main

‎Core/Sources/LaunchAgentManager/LaunchAgentManager.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ public struct LaunchAgentManager {
3333
awaitremoveObsoleteLaunchAgent()
3434
}
3535
}
36+
37+
@available(macOS13.0,*)
38+
publicfunc isBackgroundPermissionGranted()async->Bool{
39+
// On macOS 13+, check SMAppService status
40+
letbridgeLaunchAgent=SMAppService.agent(plistName:"bridgeLaunchAgent.plist")
41+
letstatus= bridgeLaunchAgent.status
42+
return status!=.requiresApproval
43+
}
3644

3745
publicfunc setupLaunchAgent()asyncthrows{
3846
if #available(macOS13,*){

‎Core/Sources/Service/Service.swift

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,28 @@ public final class Service {
114114
}.store(in:&cancellable)
115115

116116
// Combine both workspace and auth status changes into a single stream
117-
awaitPublishers.CombineLatest(
117+
awaitPublishers.CombineLatest3(
118+
XcodeInspector.shared.safe.$latestActiveXcode,
118119
XcodeInspector.shared.safe.$activeWorkspaceURL
119120
.removeDuplicates(),
120121
StatusObserver.shared.$authStatus
121122
.removeDuplicates()
122123
)
123124
.receive(on:DispatchQueue.main)
124-
.sink{[weak self] newURL, newStatusin
125-
self?.onNewActiveWorkspaceURLOrAuthStatus(newURL: newURL, newStatus: newStatus)
125+
.sink{[weak self] newXcode, newURL, newStatusin
126+
// First check for realtimeWorkspaceURL if activeWorkspaceURL is nil
127+
iflet realtimeURL= newXcode?.realtimeWorkspaceURL, newURL==nil{
128+
self?.onNewActiveWorkspaceURLOrAuthStatus(
129+
newURL: realtimeURL,
130+
newStatus: newStatus
131+
)
132+
}elseiflet newURL= newURL{
133+
// Then use activeWorkspaceURL if available
134+
self?.onNewActiveWorkspaceURLOrAuthStatus(
135+
newURL: newURL,
136+
newStatus: newStatus
137+
)
138+
}
126139
}
127140
.store(in:&cancellable)
128141
}
@@ -137,7 +150,7 @@ public final class Service {
137150

138151
privatefunc getDisplayNameOfXcodeWorkspace(url:URL)->String{
139152
varname= url.lastPathComponent
140-
letsuffixes=[".xcworkspace",".xcodeproj"]
153+
letsuffixes=[".xcworkspace",".xcodeproj",".playground"]
141154
forsuffixin suffixes{
142155
if name.hasSuffix(suffix){
143156
name=String(name.dropLast(suffix.count))

‎ExtensionService/XPCController.swift

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,38 @@ final class XPCController: XPCServiceDelegate {
3939
func createPingTask(){
4040
pingTask?.cancel()
4141
pingTask=Task{[weak self]in
42+
varconsecutiveFailures=0
43+
varbackoffDelay=1_000_000_000 // Start with 1 second
44+
4245
while !Task.isCancelled{
4346
guardlet selfelse{return}
4447
do{
4548
tryawaitself.bridge.updateServiceEndpoint(self.xpcListener.endpoint)
46-
tryawaitTask.sleep(nanoseconds:60_000_000_000)
49+
// Reset on success
50+
consecutiveFailures=0
51+
backoffDelay=1_000_000_000
52+
tryawaitTask.sleep(nanoseconds:60_000_000_000) // 60 seconds between successful pings
4753
}catch{
48-
tryawaitTask.sleep(nanoseconds:1_000_000_000)
54+
consecutiveFailures+=1
55+
// Log only on 1st, 5th (31 sec), 10th failures, etc. to avoid flooding
56+
letshouldLog= consecutiveFailures==1 || consecutiveFailures%5==0
57+
4958
#if DEBUG
5059
// No log, but you should run CommunicationBridge, too.
5160
#else
52-
Logger.service
53-
.error("Failed to connect to bridge:\(error.localizedDescription)")
61+
if consecutiveFailures==5{
62+
if #available(macOS13.0,*){
63+
showBackgroundPermissionAlert()
64+
}
65+
}
66+
if shouldLog{
67+
Logger.service.error("Failed to connect to bridge (\(consecutiveFailures) consecutive failures):\(error.localizedDescription)")
68+
}
5469
#endif
70+
71+
// Exponential backoff with a cap
72+
backoffDelay=min(backoffDelay*2,120_000_000_000) // Cap at 120 seconds
73+
tryawaitTask.sleep(nanoseconds:UInt64(backoffDelay))
5574
}
5675
}
5776
}

‎Tool/Sources/GitHubCopilotService/LanguageServer/CopilotLocalProcessServer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ extension CustomJSONRPCLanguageServer {
311311
.updateCLSStatus(
312312
payload.kind.clsStatus,
313313
busy: payload.busy,
314-
message: payload.message
314+
message: payload.message??""
315315
)
316316
}
317317
}

‎Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotRequest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ public enum GitHubCopilotNotification {
423423

424424
publicvarkind:StatusKind
425425
publicvarbusy:Bool
426-
publicvarmessage:String
426+
publicvarmessage:String?
427427

428428
publicstaticfunc decode(fromParams params:JSONValue?)->StatusNotification?{
429429
try?JSONDecoder().decode(Self.self, from:(try?JSONEncoder().encode(params))??Data())

‎Tool/Sources/GitHubCopilotService/LanguageServer/GitHubCopilotService.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,18 @@ public class GitHubCopilotBaseService {
207207
server.defaultTimeout=60
208208
server.initializeParamsProvider={
209209
letcapabilities=ClientCapabilities(
210-
workspace:nil,
210+
workspace:.init(
211+
applyEdit:false,
212+
workspaceEdit:nil,
213+
didChangeConfiguration:nil,
214+
didChangeWatchedFiles:nil,
215+
symbol:nil,
216+
executeCommand:nil,
217+
/// enable for "watchedFiles capability", set others to default value
218+
workspaceFolders:true,
219+
configuration:nil,
220+
semanticTokens:nil
221+
),
211222
textDocument:nil,
212223
window:nil,
213224
general:nil,
@@ -726,13 +737,13 @@ public final class GitHubCopilotService:
726737
privatefunc updateServiceAuthStatus(_ status:GitHubCopilotRequest.CheckStatus.Response)async{
727738
Logger.gitHubCopilot.info("check status response:\(status)")
728739
if status.status==.ok || status.status==.maybeOk{
740+
awaitStatus.shared.updateAuthStatus(.loggedIn, username: status.user)
729741
if !CopilotModelManager.hasLLMs(){
730742
letmodels=try?awaitmodels()
731743
iflet models= models, !models.isEmpty{
732744
CopilotModelManager.updateLLMs(models)
733745
}
734746
}
735-
awaitStatus.shared.updateAuthStatus(.loggedIn, username: status.user)
736747
awaitunwatchAuthStatus()
737748
}elseif status.status==.notAuthorized{
738749
awaitStatus.shared

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp