-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathCopilotPolicyManager.swift
More file actions
107 lines (86 loc) · 3.5 KB
/
CopilotPolicyManager.swift
File metadata and controls
107 lines (86 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import Client
import Combine
import Foundation
import GitHubCopilotService
import Logger
import SwiftUI
/// Centralized manager for GitHub Copilot policies in the HostApp
/// Use as @StateObject or @ObservedObject in SwiftUI views
@MainActor
public class CopilotPolicyManager: ObservableObject {
public static let shared = CopilotPolicyManager()
// MARK: - Published Properties
@Published public private(set) var isMCPContributionPointEnabled = true
@Published public private(set) var isCustomAgentEnabled = true
@Published public private(set) var isSubagentEnabled = true
@Published public private(set) var isCVERemediatorAgentEnabled = true
@Published public private(set) var isAgentModeAutoApprovalEnabled = true
// MARK: - Private Properties
private var cancellables = Set<AnyCancellable>()
private var lastUpdateTime: Date?
private let updateThrottle: TimeInterval = 1.0 // Prevent excessive updates
// MARK: - Initialization
private init() {
setupNotificationObserver()
Task {
await updatePolicy()
}
}
// MARK: - Public Methods
/// Manually refresh policies from the service
public func refresh() async {
await updatePolicy()
}
// MARK: - Private Methods
private func setupNotificationObserver() {
DistributedNotificationCenter.default()
.publisher(for: .gitHubCopilotPolicyDidChange)
.sink { [weak self] _ in
Task { @MainActor [weak self] in
await self?.updatePolicy()
}
}
.store(in: &cancellables)
}
private func updatePolicy() async {
// Throttle updates to prevent excessive calls
if let lastUpdate = lastUpdateTime,
Date().timeIntervalSince(lastUpdate) < updateThrottle {
return
}
lastUpdateTime = Date()
do {
let service = try getService()
guard let policy = try await service.getCopilotPolicy() else {
Logger.client.info("Copilot policy returned nil, using defaults")
return
}
// Update all policies at once
isMCPContributionPointEnabled = policy.mcpContributionPointEnabled
isCustomAgentEnabled = policy.customAgentEnabled
isSubagentEnabled = policy.subagentEnabled
isCVERemediatorAgentEnabled = policy.cveRemediatorAgentEnabled
isAgentModeAutoApprovalEnabled = policy.agentModeAutoApprovalEnabled
Logger.client.info("Copilot policy updated: customAgent=\(policy.customAgentEnabled), mcp=\(policy.mcpContributionPointEnabled), subagent=\(policy.subagentEnabled)")
} catch {
Logger.client.error("Failed to update copilot policy: \(error.localizedDescription)")
}
}
}
// MARK: - Environment Key
private struct CopilotPolicyManagerKey: EnvironmentKey {
static let defaultValue = CopilotPolicyManager.shared
}
public extension EnvironmentValues {
var copilotPolicyManager: CopilotPolicyManager {
get { self[CopilotPolicyManagerKey.self] }
set { self[CopilotPolicyManagerKey.self] = newValue }
}
}
// MARK: - View Extension
public extension View {
/// Inject the copilot policy manager into the environment
func withCopilotPolicyManager(_ manager: CopilotPolicyManager = .shared) -> some View {
self.environment(\.copilotPolicyManager, manager)
}
}