Skip to content

Commit 77b2c02

Browse files
committed
Pre-release 0.34.118
1 parent 12fbb8f commit 77b2c02

23 files changed

+422
-210
lines changed

Copilot for Xcode/App.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import SharedUIComponents
66
import UpdateChecker
77
import XPCShared
88
import HostAppActivator
9+
import ComposableArchitecture
910

1011
struct VisualEffect: NSViewRepresentable {
1112
func makeNSView(context: Self.Context) -> NSView { return NSVisualEffectView() }
@@ -192,14 +193,16 @@ struct CopilotForXcodeApp: App {
192193
}
193194

194195
var body: some Scene {
195-
Settings {
196-
TabContainer()
197-
.frame(minWidth: 800, minHeight: 600)
198-
.background(VisualEffect().ignoresSafeArea())
199-
.environment(\.updateChecker, UpdateChecker(
200-
hostBundle: Bundle.main,
201-
checkerDelegate: AppUpdateCheckerDelegate()
202-
))
196+
WithPerceptionTracking {
197+
Settings {
198+
TabContainer()
199+
.frame(minWidth: 800, minHeight: 600)
200+
.background(VisualEffect().ignoresSafeArea())
201+
.environment(\.updateChecker, UpdateChecker(
202+
hostBundle: Bundle.main,
203+
checkerDelegate: AppUpdateCheckerDelegate()
204+
))
205+
}
203206
}
204207
}
205208
}

Core/Sources/ChatService/ChatService.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ public final class ChatService: ChatServiceType, ObservableObject {
379379
public func stopReceivingMessage() async {
380380
if let activeRequestId = activeRequestId {
381381
do {
382-
try await conversationProvider?.stopReceivingMessage(activeRequestId)
382+
try await conversationProvider?.stopReceivingMessage(activeRequestId, workspaceURL: getWorkspaceURL())
383383
} catch {
384384
print("Failed to cancel ongoing request with WDT: \(activeRequestId)")
385385
}
@@ -393,7 +393,7 @@ public final class ChatService: ChatServiceType, ObservableObject {
393393
await memory.clearHistory()
394394
if let activeRequestId = activeRequestId {
395395
do {
396-
try await conversationProvider?.stopReceivingMessage(activeRequestId)
396+
try await conversationProvider?.stopReceivingMessage(activeRequestId, workspaceURL: getWorkspaceURL())
397397
} catch {
398398
print("Failed to cancel ongoing request with WDT: \(activeRequestId)")
399399
}
@@ -491,13 +491,20 @@ public final class ChatService: ChatServiceType, ObservableObject {
491491
try await send(UUID().uuidString, content: templateProcessor.process(sendingMessageImmediately), skillSet: [], references: [])
492492
}
493493
}
494-
494+
495+
public func getWorkspaceURL() -> URL? {
496+
guard !chatTabInfo.workspacePath.isEmpty else {
497+
return nil
498+
}
499+
return URL(fileURLWithPath: chatTabInfo.workspacePath)
500+
}
501+
495502
public func upvote(_ id: String, _ rating: ConversationRating) async {
496-
try? await conversationProvider?.rateConversation(turnId: id, rating: rating)
503+
try? await conversationProvider?.rateConversation(turnId: id, rating: rating, workspaceURL: getWorkspaceURL())
497504
}
498505

499506
public func downvote(_ id: String, _ rating: ConversationRating) async {
500-
try? await conversationProvider?.rateConversation(turnId: id, rating: rating)
507+
try? await conversationProvider?.rateConversation(turnId: id, rating: rating, workspaceURL: getWorkspaceURL())
501508
}
502509

503510
public func copyCode(_ id: String) async {
@@ -725,7 +732,7 @@ public final class ChatService: ChatServiceType, ObservableObject {
725732

726733
do {
727734
if let conversationId = conversationId {
728-
try await conversationProvider?.createTurn(with: conversationId, request: request)
735+
try await conversationProvider?.createTurn(with: conversationId, request: request, workspaceURL: getWorkspaceURL())
729736
} else {
730737
var requestWithTurns = request
731738

@@ -738,7 +745,7 @@ public final class ChatService: ChatServiceType, ObservableObject {
738745
requestWithTurns.turns = turns
739746
}
740747

741-
try await conversationProvider?.createConversation(requestWithTurns)
748+
try await conversationProvider?.createConversation(requestWithTurns, workspaceURL: getWorkspaceURL())
742749
}
743750
} catch {
744751
resetOngoingRequest()

Core/Sources/ConversationTab/Chat.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct Chat {
6666
var fileEditMap: OrderedDictionary<URL, FileEdit> = [:]
6767
var diffViewerController: DiffViewWindowController? = nil
6868
var isAgentMode: Bool = AppState.shared.isAgentModeEnabled()
69+
var workspaceURL: URL? = nil
6970
enum Field: String, Hashable {
7071
case textField
7172
case fileSearchBar
@@ -564,4 +565,3 @@ private actor TimedDebounceFunction {
564565
await block()
565566
}
566567
}
567-

Core/Sources/ConversationTab/ChatPanel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ struct ChatPanelInputArea: View {
488488
}
489489
)
490490
.onAppear() {
491-
allFiles = ContextUtils.getFilesInActiveWorkspace()
491+
allFiles = ContextUtils.getFilesInActiveWorkspace(workspaceURL: chat.workspaceURL)
492492
}
493493
}
494494

Core/Sources/ConversationTab/ContextUtils.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import Workspace
66

77
public struct ContextUtils {
88

9-
public static func getFilesInActiveWorkspace() -> [FileReference] {
9+
public static func getFilesInActiveWorkspace(workspaceURL: URL?) -> [FileReference] {
10+
if let workspaceURL = workspaceURL, let info = WorkspaceFile.getWorkspaceInfo(workspaceURL: workspaceURL) {
11+
return WorkspaceFile.getFilesInActiveWorkspace(workspaceURL: info.workspaceURL, workspaceRootURL: info.projectURL)
12+
}
13+
1014
guard let workspaceURL = XcodeInspector.shared.realtimeActiveWorkspaceURL,
1115
let workspaceRootURL = XcodeInspector.shared.realtimeActiveProjectURL else {
1216
return []

Core/Sources/ConversationTab/ConversationTab.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public class ConversationTab: ChatTab {
114114

115115
let service = ChatService.service(for: info)
116116
self.service = service
117-
chat = .init(initialState: .init(), reducer: { Chat(service: service) })
117+
chat = .init(initialState: .init(workspaceURL: service.getWorkspaceURL()), reducer: { Chat(service: service) })
118118
super.init(store: store)
119119

120120
// Start to observe changes of Chat Message
@@ -128,7 +128,7 @@ public class ConversationTab: ChatTab {
128128
@MainActor
129129
public init(service: ChatService, store: StoreOf<ChatTabItem>, with chatTabInfo: ChatTabInfo) {
130130
self.service = service
131-
chat = .init(initialState: .init(), reducer: { Chat(service: service) })
131+
chat = .init(initialState: .init(workspaceURL: service.getWorkspaceURL()), reducer: { Chat(service: service) })
132132
super.init(store: store)
133133
}
134134

Core/Sources/HostApp/MCPConfigView.swift

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import SwiftUI
66
import Toast
77
import ConversationServiceProvider
88
import GitHubCopilotService
9+
import ComposableArchitecture
910

1011
struct MCPConfigView: View {
1112
@State private var mcpConfig: String = ""
@@ -16,20 +17,24 @@ struct MCPConfigView: View {
1617
@State private var fileMonitorTask: Task<Void, Error>? = nil
1718
@Environment(\.colorScheme) var colorScheme
1819

20+
private static var lastSyncTimestamp: Date? = nil
21+
1922
var body: some View {
20-
ScrollView {
21-
VStack(alignment: .leading, spacing: 8) {
22-
MCPIntroView()
23-
MCPToolsListView()
24-
}
25-
.padding(20)
26-
.onAppear {
27-
setupConfigFilePath()
28-
startMonitoringConfigFile()
29-
refreshConfiguration(())
30-
}
31-
.onDisappear {
32-
stopMonitoringConfigFile()
23+
WithPerceptionTracking {
24+
ScrollView {
25+
VStack(alignment: .leading, spacing: 8) {
26+
MCPIntroView()
27+
MCPToolsListView()
28+
}
29+
.padding(20)
30+
.onAppear {
31+
setupConfigFilePath()
32+
startMonitoringConfigFile()
33+
refreshConfiguration(())
34+
}
35+
.onDisappear {
36+
stopMonitoringConfigFile()
37+
}
3338
}
3439
}
3540
}
@@ -145,6 +150,12 @@ struct MCPConfigView: View {
145150
}
146151

147152
func refreshConfiguration(_: Any) {
153+
if MCPConfigView.lastSyncTimestamp == lastModificationDate {
154+
return
155+
}
156+
157+
MCPConfigView.lastSyncTimestamp = lastModificationDate
158+
148159
let fileURL = URL(fileURLWithPath: configFilePath)
149160
if let jsonString = readAndValidateJSON(from: fileURL) {
150161
UserDefaults.shared.set(jsonString, for: \.gitHubCopilotMCPConfig)

Core/Sources/HostApp/MCPSettings/MCPIntroView.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ struct MCPIntroView: View {
1313
"my-mcp-server": {
1414
"type": "stdio",
1515
"command": "my-command",
16-
"args": []
16+
"args": [],
17+
"env": {
18+
"TOKEN": "my_token"
19+
}
1720
}
1821
}
1922
}
@@ -75,7 +78,7 @@ struct MCPIntroView: View {
7578
.overlay(
7679
RoundedRectangle(cornerRadius: 4)
7780
.inset(by: 0.5)
78-
.stroke(Color(red: 0.9, green: 0.9, blue: 0.9), lineWidth: 1)
81+
.stroke(Color("GroupBoxStrokeColor"), lineWidth: 1)
7982
)
8083
}
8184

0 commit comments

Comments
 (0)