Skip to content

Commit 70feae2

Browse files
committed
Merge branch 'release/0.13.3'
2 parents eb4d3d8 + a9ffa16 commit 70feae2

30 files changed

+263
-139
lines changed

Copilot for Xcode/CustomCommandView.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ struct CustomCommandView: View {
1616
"Real-time Suggestions",
1717
"Prefetch Suggestions",
1818
"Chat with Selection",
19-
"Prompt to Code",
20-
"# Custom Commands:",
19+
"Prompt to Code"
2120
]
2221

2322
return existed + builtin
@@ -65,6 +64,7 @@ struct CustomCommandView: View {
6564
Spacer()
6665
Button(action: {
6766
editingCommand = .init(isNew: true, command: CustomCommand(
67+
commandId: UUID().uuidString,
6868
name: "New Command",
6969
feature: .chatWithSelection(
7070
extraSystemPrompt: nil,
@@ -236,6 +236,7 @@ struct EditCustomCommandView: View {
236236
}
237237

238238
lazy var newCommand = CustomCommand(
239+
commandId: editingCommand?.command.id ?? UUID().uuidString,
239240
name: name,
240241
feature: {
241242
switch commandType {
@@ -283,7 +284,7 @@ struct EditCustomCommandView: View {
283284
}
284285

285286
if let index = settings.customCommands.firstIndex(where: {
286-
$0.name == originalName
287+
$0.id == newCommand.id
287288
}) {
288289
settings.customCommands[index] = newCommand
289290
} else {
@@ -351,10 +352,12 @@ struct CustomCommandView_Preview: PreviewProvider {
351352
isOpen: .constant(true),
352353
settings: .init(customCommands: .init(wrappedValue: [
353354
.init(
355+
commandId: "1",
354356
name: "Explain Code",
355357
feature: .chatWithSelection(extraSystemPrompt: nil, prompt: "Hello")
356358
),
357359
.init(
360+
commandId: "2",
358361
name: "Refactor Code",
359362
feature: .promptToCode(
360363
extraSystemPrompt: nil,
@@ -363,6 +366,7 @@ struct CustomCommandView_Preview: PreviewProvider {
363366
)
364367
),
365368
.init(
369+
commandId: "3",
366370
name: "Tell Me A Joke",
367371
feature: .customChat(systemPrompt: "Joke", prompt: "")
368372
),
@@ -378,6 +382,7 @@ struct EditCustomCommandView_Preview: PreviewProvider {
378382
editingCommand: .constant(CustomCommandView.EditingCommand(
379383
isNew: false,
380384
command: .init(
385+
commandId: "4",
381386
name: "Explain Code",
382387
feature: .promptToCode(
383388
extraSystemPrompt: nil,

Copilot for Xcode/DebugView.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ final class DebugSettings: ObservableObject {
77
var disableLazyVStack: Bool
88
@AppStorage(\.preCacheOnFileOpen)
99
var preCacheOnFileOpen: Bool
10-
@AppStorage(\.runNodeWithInteractiveLoggedInShell)
11-
var runNodeWithInteractiveLoggedInShell: Bool
1210
@AppStorage(\.useCustomScrollViewWorkaround) var useCustomScrollViewWorkaround
1311
init() {}
1412
}
@@ -27,16 +25,13 @@ struct DebugSettingsView: View {
2725
Text("Cache editor information on file open")
2826
}
2927
.toggleStyle(.switch)
30-
Toggle(isOn: $settings.runNodeWithInteractiveLoggedInShell) {
31-
Text("Run node with interactive logged-in bash")
32-
}
33-
.toggleStyle(.switch)
3428
Toggle(isOn: $settings.useCustomScrollViewWorkaround) {
3529
Text("Use custom scroll view workaround for smooth scrolling")
3630
}
3731
.toggleStyle(.switch)
3832
}
39-
}.buttonStyle(.copilot)
33+
}
34+
.buttonStyle(.copilot)
4035
}
4136
}
4237

Copilot for Xcode/LaunchAgentView.swift

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
import LaunchAgentManager
2-
import SwiftUI
32
import Preferences
3+
import SwiftUI
44

55
struct LaunchAgentView: View {
6+
class Settings: ObservableObject {
7+
@AppStorage(\.nodePath) var nodePath: String
8+
@AppStorage(\.runNodeWith) var runNodeWith
9+
10+
init() {}
11+
}
12+
613
@State var errorMessage: String?
714
@State var isDidRemoveLaunchAgentAlertPresented = false
815
@State var isDidSetupLaunchAgentAlertPresented = false
916
@State var isDidRestartLaunchAgentAlertPresented = false
10-
@AppStorage(\.nodePath) var nodePath: String
17+
@StateObject var settings = Settings()
1118

1219
var body: some View {
1320
Section {
@@ -85,14 +92,31 @@ struct LaunchAgentView: View {
8592
}
8693
}
8794

88-
HStack {
89-
Text("Path to Node: ")
90-
TextField("node", text: $nodePath)
91-
.textFieldStyle(.copilot)
95+
Form {
96+
TextField(text: $settings.nodePath, prompt: Text("node")) {
97+
Text("Path to Node")
98+
}
99+
100+
Picker(selection: $settings.runNodeWith) {
101+
ForEach(NodeRunner.allCases, id: \.rawValue) { runner in
102+
switch runner {
103+
case .env:
104+
Text("/usr/bin/env").tag(runner)
105+
case .bash:
106+
Text("/bin/bash -i -l").tag(runner)
107+
case .shell:
108+
Text("$SHELL -i -l").tag(runner)
109+
}
110+
}
111+
} label: {
112+
Text("Run Node with")
113+
}
92114
}
93-
94-
Text("You may have to restart the helper app to apply the changes. To do so, simply close the helper app by clicking on the menu bar icon that looks like a steer wheel, it will automatically restart as needed.")
95-
.foregroundColor(.secondary)
115+
116+
Text(
117+
"You may have to restart the helper app to apply the changes. To do so, simply close the helper app by clicking on the menu bar icon that looks like a steer wheel, it will automatically restart as needed."
118+
)
119+
.foregroundColor(.secondary)
96120

97121
HStack {
98122
Button(action: {

Copilot for Xcode/OpenAIView.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ struct OpenAIView: View {
6262
Image(systemName: "questionmark.circle.fill")
6363
}.buttonStyle(.plain)
6464
}
65-
.onChange(of: settings.chatGPTModel) { newValue in
66-
if let model = ChatGPTModel(rawValue: newValue) {
67-
settings.chatGPTEndpoint = model.endpoint
68-
}
69-
}
7065

7166
TextField(
7267
text: $settings.chatGPTEndpoint,

Core/Sources/ChatPlugins/AITerminalChatPlugin.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public actor AITerminalChatPlugin: ChatPlugin {
1919
self.delegate = delegate
2020
}
2121

22-
public func send(content: String) async {
22+
public func send(content: String, originalMessage: String) async {
2323
if !isStarted {
2424
isStarted = true
2525
delegate?.pluginDidStart(self)
@@ -69,7 +69,11 @@ public actor AITerminalChatPlugin: ChatPlugin {
6969
}
7070
} else {
7171
await chatGPTService.mutateHistory { history in
72-
history.append(.init(role: .user, content: "Run a command to \(content)"))
72+
history.append(.init(
73+
role: .user,
74+
content: originalMessage,
75+
summary: "Run a command to \(content)")
76+
)
7377
}
7478
delegate?.pluginDidStartResponding(self)
7579
let result = try await generateCommand(task: content)

Core/Sources/ChatPlugins/ChatPlugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public protocol ChatPlugin: AnyObject {
77
var name: String { get }
88

99
init(inside chatGPTService: any ChatGPTServiceType, delegate: ChatPluginDelegate)
10-
func send(content: String) async
10+
func send(content: String, originalMessage: String) async
1111
func cancel() async
1212
func stopResponding() async
1313
}

Core/Sources/ChatPlugins/TerminalChatPlugin.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public actor TerminalChatPlugin: ChatPlugin {
1717
self.delegate = delegate
1818
}
1919

20-
public func send(content: String) async {
20+
public func send(content: String, originalMessage: String) async {
2121
delegate?.pluginDidStart(self)
2222
delegate?.pluginDidStartResponding(self)
2323

@@ -38,7 +38,11 @@ public actor TerminalChatPlugin: ChatPlugin {
3838
let projectURL = try await Environment.fetchCurrentProjectRootURL(fileURL)
3939

4040
await chatGPTService.mutateHistory { history in
41-
history.append(.init(role: .user, content: "Run command: \(content)"))
41+
history.append(.init(
42+
role: .user,
43+
content: originalMessage,
44+
summary: "Run command: \(content)")
45+
)
4246
}
4347

4448
if isCancelled { throw CancellationError() }

Core/Sources/ChatService/ChatService.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,28 @@ public final class ChatService: ObservableObject {
5353
}
5454
}
5555
} else if let runningPlugin {
56-
await runningPlugin.send(content: content)
56+
await runningPlugin.send(content: content, originalMessage: content)
5757
} else if let pluginType = plugins[command] {
5858
let plugin = pluginType.init(inside: chatGPTService, delegate: self)
5959
if #available(macOS 13.0, *) {
6060
await plugin.send(
6161
content: String(
6262
content.dropFirst(command.count + 1)
6363
.trimmingPrefix(while: { $0 == " " })
64-
)
64+
),
65+
originalMessage: content
6566
)
6667
} else {
67-
await plugin.send(content: String(content.dropFirst(command.count + 1)))
68+
await plugin.send(
69+
content: String(content.dropFirst(command.count + 1)),
70+
originalMessage: content
71+
)
6872
}
6973
} else {
7074
_ = try await chatGPTService.send(content: content, summary: nil)
7175
}
7276
} else if let runningPlugin {
73-
await runningPlugin.send(content: content)
77+
await runningPlugin.send(content: content, originalMessage: content)
7478
} else {
7579
_ = try await chatGPTService.send(content: content, summary: nil)
7680
}
@@ -89,13 +93,13 @@ public final class ChatService: ObservableObject {
8993
}
9094
await chatGPTService.clearHistory()
9195
}
92-
96+
9397
public func deleteMessage(id: String) async {
9498
await chatGPTService.mutateHistory { messages in
9599
messages.removeAll(where: { $0.id == id })
96100
}
97101
}
98-
102+
99103
public func resendMessage(id: String) async throws {
100104
if let message = (await chatGPTService.history).first(where: { $0.id == id }) {
101105
try await send(content: message.content)
@@ -133,7 +137,7 @@ extension ChatService: ChatPluginDelegate {
133137
public func shouldStartAnotherPlugin(_ type: ChatPlugin.Type, withContent content: String) {
134138
let plugin = type.init(inside: chatGPTService, delegate: self)
135139
Task {
136-
await plugin.send(content: content)
140+
await plugin.send(content: content, originalMessage: content)
137141
}
138142
}
139143
}

Core/Sources/Client/AsyncXPCService.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,13 @@ public struct AsyncXPCService {
198198
}
199199

200200
public func customCommand(
201-
name: String,
201+
id: String,
202202
editorContent: EditorContent
203203
) async throws -> UpdatedContent? {
204204
try await suggestionRequest(
205205
connection,
206206
editorContent,
207-
{ service in { service.customCommand(name: name, editorContent: $0, withReply: $1) } }
207+
{ service in { service.customCommand(id: id, editorContent: $0, withReply: $1) } }
208208
)
209209
}
210210
}

Core/Sources/CopilotService/CopilotService.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ public class CopilotBaseService {
5656
userEnvPath = "/usr/bin:/usr/local/bin" // fallback
5757
}
5858
let executionParams: Process.ExecutionParameters
59-
if UserDefaults.shared.value(for: \.runNodeWithInteractiveLoggedInShell) {
59+
let runner = UserDefaults.shared.value(for: \.runNodeWith)
60+
61+
switch runner {
62+
case .bash:
6063
let nodePath = UserDefaults.shared.value(for: \.nodePath)
6164
let command = [
6265
nodePath.isEmpty ? "node" : nodePath,
@@ -71,7 +74,23 @@ public class CopilotBaseService {
7174
currentDirectoryURL: supportURL
7275
)
7376
}()
74-
} else {
77+
case .shell:
78+
let shell = ProcessInfo.processInfo.userEnvironment["SHELL"] ?? "/bin/bash"
79+
let nodePath = UserDefaults.shared.value(for: \.nodePath)
80+
let command = [
81+
nodePath.isEmpty ? "node" : nodePath,
82+
"\"\(Bundle.main.url(forResource: "agent", withExtension: "js", subdirectory: "copilot/dist")!.path)\"",
83+
"--stdio",
84+
].joined(separator: " ")
85+
executionParams = {
86+
Process.ExecutionParameters(
87+
path: shell,
88+
arguments: ["-i", "-l", "-c", command],
89+
environment: [:],
90+
currentDirectoryURL: supportURL
91+
)
92+
}()
93+
case .env:
7594
executionParams = {
7695
let nodePath = UserDefaults.shared.value(for: \.nodePath)
7796
return Process.ExecutionParameters(

0 commit comments

Comments
 (0)