-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathCustomCopilotHelper.swift
More file actions
140 lines (122 loc) · 4.17 KB
/
CustomCopilotHelper.swift
File metadata and controls
140 lines (122 loc) · 4.17 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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import AppKit
import Client
import Foundation
import SwiftUI
import Toast
import XcodeInspector
import SystemUtils
public enum PromptType: String, CaseIterable, Equatable {
case instructions = "instructions"
case prompt = "prompt"
/// The directory name under .github where files of this type are stored
var directoryName: String {
switch self {
case .instructions:
return "instructions"
case .prompt:
return "prompts"
}
}
/// The file extension for this prompt type
var fileExtension: String {
switch self {
case .instructions:
return ".instructions.md"
case .prompt:
return ".prompt.md"
}
}
/// Human-readable name for display purposes
var displayName: String {
switch self {
case .instructions:
return "Instruction File"
case .prompt:
return "Prompt File"
}
}
/// Human-readable name for settings
var settingTitle: String {
switch self {
case .instructions:
return "Custom Instructions"
case .prompt:
return "Prompt Files"
}
}
/// Description for the prompt type
var description: String {
switch self {
case .instructions:
return "Configure `.github/instructions/*.instructions.md` files scoped to specific file patterns or tasks."
case .prompt:
return "Configure `.github/prompts/*.prompt.md` files for reusable prompts. Trigger with '/' commands in the Chat view."
}
}
/// Default template content for new files
var defaultTemplate: String {
switch self {
case .instructions:
return """
---
applyTo: '**'
---
Provide project context and coding guidelines that AI should follow when generating code, or answering questions.
"""
case .prompt:
return """
---
description: Prompt Description
---
Define the task to achieve, including specific requirements, constraints, and success criteria.
"""
}
}
var helpLink: String {
var editorPluginVersion = SystemUtils.editorPluginVersionString
if editorPluginVersion == "0.0.0" {
editorPluginVersion = "main"
}
switch self {
case .instructions:
return "https://github.com/github/CopilotForXcode/blob/\(editorPluginVersion)/Docs/CustomInstructions.md"
case .prompt:
return "https://github.com/github/CopilotForXcode/blob/\(editorPluginVersion)/Docs/PromptFiles.md"
}
}
/// Get the full file path for a given name and project URL
func getFilePath(fileName: String, projectURL: URL) -> URL {
let directory = getDirectoryPath(projectURL: projectURL)
return directory.appendingPathComponent("\(fileName)\(fileExtension)")
}
/// Get the directory path for this prompt type
func getDirectoryPath(projectURL: URL) -> URL {
return projectURL.appendingPathComponent(".github/\(directoryName)")
}
}
func getCurrentProjectURL() async -> URL? {
let service = try? getService()
let inspectorData = try? await service?.getXcodeInspectorData()
var currentWorkspace: URL?
if let url = inspectorData?.realtimeActiveWorkspaceURL,
let workspaceURL = URL(string: url),
workspaceURL.path != "/" {
currentWorkspace = workspaceURL
} else if let url = inspectorData?.latestNonRootWorkspaceURL {
currentWorkspace = URL(string: url)
}
guard let workspaceURL = currentWorkspace,
let projectURL = WorkspaceXcodeWindowInspector.extractProjectURL(
workspaceURL: workspaceURL,
documentURL: nil
) else {
return nil
}
return projectURL
}
func ensureDirectoryExists(at url: URL) throws {
let fileManager = FileManager.default
if !fileManager.fileExists(atPath: url.path) {
try fileManager.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
}
}