Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
2077371
Merge tag '0.34.0' into develop
intitni Sep 13, 2024
27589fc
chore: Fix some typos
Sajjon Sep 1, 2024
5106228
Merge pull request #570 from Sajjon/cyon_fix_typos
intitni Sep 13, 2024
54d7a80
Fix that the app can't be built in Xcode 16
intitni Sep 16, 2024
9e2a109
Bump TCA and SwiftSyntax
intitni Sep 16, 2024
b5a2e2a
Remove some warnings
intitni Sep 16, 2024
04c805a
Merge tag '0.34.1' into develop
intitni Sep 18, 2024
f4403de
Remove warnings
intitni Sep 18, 2024
bc34a0f
Update packages
intitni Sep 17, 2024
970bc84
Support async truncation
intitni Sep 26, 2024
abf479a
Update definition of ChatAgent
intitni Sep 26, 2024
192669e
Hide pro chat tabs from opensource code
intitni Sep 26, 2024
e19db0b
Support multiple status
intitni Sep 28, 2024
603ddfd
Update default values
intitni Sep 28, 2024
5551e1f
Update open mode to better handle builtin extensions
intitni Sep 28, 2024
f51079a
Make chat tab definition in extensions more flexible
intitni Sep 28, 2024
1b149a4
Update open chat command handler
intitni Sep 29, 2024
8fab2d2
Update
intitni Sep 30, 2024
ae71065
Fixx trigger menu fallback
intitni Sep 30, 2024
06e38e7
Remove the placeholder models
intitni Sep 30, 2024
3d8e66e
Use Accessibility API to make an app active
intitni Oct 2, 2024
9db6704
Update error message
intitni Oct 2, 2024
d8fbd7c
Add empty()
intitni Oct 5, 2024
22ac6af
Update
intitni Oct 6, 2024
aa59c01
Add ThrottleRunner
intitni Oct 6, 2024
9f5552c
Prevent filespace of workspace files
intitni Oct 6, 2024
f5ff3db
Remove logs
intitni Oct 6, 2024
fd7bb9b
Update entitlements
intitni Oct 6, 2024
bda2eb3
Merge tag '0.34.2' into develop
intitni Oct 6, 2024
626aa5e
Merge branch 'feature/chat-agent-prepare' into develop
intitni Oct 6, 2024
802fa30
Add OpenAI embedding models
intitni Oct 7, 2024
33a785c
Add reference kind error
intitni Oct 7, 2024
f0e4b88
Get open chat command handler from service
intitni Oct 7, 2024
af2e417
Update MemoryTemplate
intitni Oct 11, 2024
c03b403
Rename PromptToCodeBasic to ModificationBasic
intitni Oct 11, 2024
53a5d3e
Add presentModification and presentFile to command handler
intitni Oct 14, 2024
2b86abb
Update the style of copy button
intitni Oct 14, 2024
0f6a311
Add cacheIfPossible to chat message
intitni Oct 14, 2024
cb77f0e
Update presentModification to also take a source
intitni Oct 14, 2024
ea3b823
Update to always create instead of activating existing panels
intitni Oct 14, 2024
d6b59e3
WIP
intitni Oct 7, 2024
5569f84
Call ChatTab.close when closing tabs
intitni Oct 15, 2024
14e0a84
Merge branch 'feature/custom-chat-tab' into develop
intitni Oct 15, 2024
747fbfd
Fix that isSuggestionFeatureInUse is incorrect
intitni Oct 17, 2024
eb8f1ec
Remove suggestionServiceId
intitni Oct 17, 2024
8b5445e
Move CustomCommandTemplateProcessor to Tool
intitni Oct 17, 2024
226bc25
Add asTexts
intitni Oct 17, 2024
46b84c6
Update dependencies
intitni Oct 17, 2024
27cf396
Fix dependency
intitni Oct 18, 2024
6a5fe79
Add cache if possible to chat message
intitni Oct 18, 2024
4079a0f
Update filespace expire duration
intitni Oct 18, 2024
bcb0b57
Add prompt cache support for ClaudeChatCompletionsService
intitni Oct 19, 2024
e430646
Track usage in OpenAI and Claude models
intitni Oct 19, 2024
e831cea
Rename extraContext to topics
intitni Oct 19, 2024
a81fd9d
Update topics to be references
intitni Oct 20, 2024
0864650
Update to call the batch embedding method
intitni Oct 20, 2024
f8f5a49
Fix unit tests
intitni Oct 20, 2024
cb95060
Fix history resolving
intitni Oct 20, 2024
405edfe
Add warning if AXUIElement access is too deep
intitni Oct 20, 2024
b673f9c
Change old chat tab new
intitni Oct 20, 2024
1bea881
Bump build number
intitni Oct 20, 2024
93215bf
Bump build number
intitni Oct 22, 2024
a59fb49
Rename ChatPlugin to LegacyChatPlugin
intitni Oct 21, 2024
84244c0
Reimplemnt plugins with ChatPlugin
intitni Oct 21, 2024
490c781
Update ChatAgentResponse
intitni Oct 24, 2024
c197801
Remove warnings
intitni Oct 24, 2024
d09622d
Fix action result
intitni Oct 24, 2024
d9d5818
Add plugin description
intitni Oct 24, 2024
7b35faf
Update
intitni Oct 24, 2024
b335e96
Merge branch 'feature/plugin-in-new-chat-tab' into develop
intitni Oct 24, 2024
9638941
Move xcodeStyleFrame to shared UI components
intitni Oct 28, 2024
635a027
Merge tag '0.34.3' into develop
intitni Oct 30, 2024
ee4bd9d
Rename to ModificationState
intitni Nov 4, 2024
ebbf15f
Rename to acceptModification
intitni Nov 4, 2024
0aaf5ce
Move ModificationState to ModificationBasic
intitni Nov 4, 2024
d3be179
Fix prompt caching
intitni Nov 4, 2024
57f00a5
Merge branch 'feature/modification-task' into develop
intitni Nov 4, 2024
dbc3fa8
Add AsyncDiffCodeBlock
intitni Nov 4, 2024
b79e344
Add description
intitni Nov 4, 2024
7290b2a
Fix offset
intitni Nov 4, 2024
3388747
Support full code diff in modification
intitni Nov 4, 2024
93257e8
Update modification to not always trigger immediately
intitni Nov 6, 2024
a2a9c87
Tweak display
intitni Nov 6, 2024
308df4a
Bump build number
intitni Nov 7, 2024
e7bde03
Replace PromptToCodeServiceType with ModificationAgent
intitni Nov 12, 2024
41290ee
Fix PromptToCodeCustomization
intitni Nov 12, 2024
620c74e
Remove scroll view invert
intitni Nov 12, 2024
4cdbf9a
Prevent modification from resetting when error
intitni Nov 13, 2024
8d8aeee
Handle claude error events
intitni Nov 13, 2024
658e77e
Remove messages with empty dynamic content
intitni Nov 13, 2024
86477f0
Merge branch 'feature/modification-customization-update' into develop
intitni Nov 14, 2024
60e7592
Remove snippet reverse
intitni Nov 15, 2024
749dc32
Remove scope settings from host app
intitni Nov 15, 2024
0db47bd
Add claude35Haiku
intitni Nov 15, 2024
1a4f931
Add error logging
intitni Nov 16, 2024
f0dcf32
Extend warning duration
intitni Nov 16, 2024
a547c49
Add custom header info
intitni Nov 17, 2024
3a5b599
Add custom header settings to OpenAI compatible
intitni Nov 17, 2024
a8f5b0a
Setup header fields in services
intitni Nov 17, 2024
40e005e
Merge branch 'feature/custom-header-openai' into develop
intitni Nov 17, 2024
0c277c1
Add task limiter
intitni Nov 17, 2024
2917628
Add dimensions settings to embedding models
intitni Nov 18, 2024
8b7234d
Make OpenAIEmbeddingService less strict about the response
intitni Nov 18, 2024
178aa95
Update
intitni Nov 18, 2024
93242c4
Fix that dimensions is not saved
intitni Nov 18, 2024
dbf303f
Change the way custom command is handled
intitni Nov 18, 2024
0030f6a
Fix embedding
intitni Nov 18, 2024
63e78e3
Add logs to TabToAcceptSuggestion
intitni Nov 18, 2024
152bd20
Fix tests
intitni Nov 18, 2024
954e4a9
Fix code diff
intitni Nov 18, 2024
b53adde
Remove generate description from modification settings
intitni Nov 19, 2024
f994626
Disable skills in GitHubCopilotChatService
intitni Nov 19, 2024
7fde5b4
Fix crashing
intitni Nov 19, 2024
213c277
Bump build number
intitni Nov 19, 2024
630d038
Add DraggableCopyButton
intitni Nov 19, 2024
b938d7d
Remove default system prompt
intitni Nov 20, 2024
273bea2
Update copy button of modification
intitni Nov 20, 2024
23561b6
Bump build number
intitni Nov 20, 2024
1f68309
Update readme
intitni Nov 20, 2024
582fed6
Merge branch 'release/0.35.0'
intitni Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ChatPlugins/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ChatPlugins"
BuildableName = "ChatPlugins"
BlueprintName = "ChatPlugins"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ChatPlugins"
BuildableName = "ChatPlugins"
BlueprintName = "ChatPlugins"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
37 changes: 37 additions & 0 deletions ChatPlugins/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "ChatPlugins",
platforms: [.macOS(.v12)],
products: [
.library(
name: "ChatPlugins",
targets: ["TerminalChatPlugin", "ShortcutChatPlugin"]
),
],
dependencies: [
.package(path: "../Tool"),
],
targets: [
.target(
name: "TerminalChatPlugin",
dependencies: [
.product(name: "Chat", package: "Tool"),
.product(name: "Terminal", package: "Tool"),
.product(name: "AppMonitoring", package: "Tool"),
]
),
.target(
name: "ShortcutChatPlugin",
dependencies: [
.product(name: "Chat", package: "Tool"),
.product(name: "Terminal", package: "Tool"),
.product(name: "AppMonitoring", package: "Tool"),
]
),
]
)

118 changes: 118 additions & 0 deletions ChatPlugins/Sources/ShortcutChatPlugin/ShortcutChatPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import ChatBasic
import Foundation
import Terminal

public final class ShortcutChatPlugin: ChatPlugin {
public static var id: String { "com.intii.shortcut" }
public static var command: String { "shortcut" }
public static var name: String { "Shortcut" }
public static var description: String { """
Run a shortcut and use message content as input. You need to provide the shortcut name as an argument, for example, `/shortcut(Shortcut Name)`.
""" }

let terminal: TerminalType

init(terminal: TerminalType) {
self.terminal = terminal
}

public init() {
terminal = Terminal()
}

public func send(_ request: Request) async -> AsyncThrowingStream<Response, any Error> {
return .init { continuation in
let task = Task {
let id = "\(Self.command)-\(UUID().uuidString)"

guard let shortcutName = request.arguments.first, !shortcutName.isEmpty else {
continuation.yield(.content(.text(
"Please provide the shortcut name in format: `/\(Self.command)(shortcut name)`"
)))
return
}

var input = String(request.text).trimmingCharacters(in: .whitespacesAndNewlines)
if input.isEmpty {
// if no input detected, use the previous message as input
input = request.history.last?.content ?? ""
}

do {
continuation.yield(.startAction(
id: "run",
task: "Run shortcut `\(shortcutName)`"
))

let env = ProcessInfo.processInfo.environment
let shell = env["SHELL"] ?? "/bin/bash"
let temporaryURL = FileManager.default.temporaryDirectory
let temporaryInputFileURL = temporaryURL
.appendingPathComponent("\(id)-input.txt")
let temporaryOutputFileURL = temporaryURL
.appendingPathComponent("\(id)-output")

try input.write(to: temporaryInputFileURL, atomically: true, encoding: .utf8)

let command = """
shortcuts run "\(shortcutName)" \
-i "\(temporaryInputFileURL.path)" \
-o "\(temporaryOutputFileURL.path)"
"""

continuation.yield(.startAction(
id: "run",
task: "Run shortcut \(shortcutName)"
))

do {
let result = try await terminal.runCommand(
shell,
arguments: ["-i", "-l", "-c", command],
currentDirectoryURL: nil,
environment: [:]
)
continuation.yield(.finishAction(id: "run", result: .success(result)))
} catch {
continuation.yield(.finishAction(
id: "run",
result: .failure(error.localizedDescription)
))
throw error
}

await Task.yield()
try Task.checkCancellation()

if FileManager.default.fileExists(atPath: temporaryOutputFileURL.path) {
let data = try Data(contentsOf: temporaryOutputFileURL)
if let text = String(data: data, encoding: .utf8) {
var response = text
if response.isEmpty {
response = "Finished"
}
continuation.yield(.content(.text(response)))
} else {
let content = """
[View File](\(temporaryOutputFileURL))
"""
continuation.yield(.content(.text(content)))
}
} else {
continuation.yield(.content(.text("Finished")))
}

} catch {
continuation.yield(.content(.text(error.localizedDescription)))
}

continuation.finish()
}

continuation.onTermination = { _ in
task.cancel()
}
}
}
}

120 changes: 120 additions & 0 deletions ChatPlugins/Sources/TerminalChatPlugin/TerminalChatPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import ChatBasic
import Foundation
import Terminal
import XcodeInspector

public final class TerminalChatPlugin: ChatPlugin {
public static var id: String { "com.intii.terminal" }
public static var command: String { "run" }
public static var name: String { "Terminal" }
public static var description: String { """
Run the command in the message from terminal.

You can use environment variable `$FILE_PATH` and `$PROJECT_ROOT` to access the current file path and project root.
""" }

let terminal: TerminalType

init(terminal: TerminalType) {
self.terminal = terminal
}

public init() {
terminal = Terminal()
}

public func formatContent(_ content: Response.Content) -> Response.Content {
switch content {
case let .text(content):
return .text("""
```sh
\(content)
```
""")
}
}

public func send(_ request: Request) async -> AsyncThrowingStream<Response, any Error> {
return .init { continuation in
let task = Task {
var updateTime = Date()

func streamOutput(_ content: String) {
defer { updateTime = Date() }
if Date().timeIntervalSince(updateTime) > 60 * 2 {
continuation.yield(.startNewMessage)
continuation.yield(.startAction(
id: "run",
task: "Continue `\(request.text)`"
))
continuation.yield(.finishAction(
id: "run",
result: .success("Executed.")
))
continuation.yield(.content(.text("[continue]\n")))
continuation.yield(.content(.text(content)))
} else {
continuation.yield(.content(.text(content)))
}
}

do {
let fileURL = await XcodeInspector.shared.safe.realtimeActiveDocumentURL
let projectURL = await XcodeInspector.shared.safe.realtimeActiveProjectURL

var environment = [String: String]()
if let fileURL {
environment["FILE_PATH"] = fileURL.path
}
if let projectURL {
environment["PROJECT_ROOT"] = projectURL.path
}

try Task.checkCancellation()

let env = ProcessInfo.processInfo.environment
let shell = env["SHELL"] ?? "/bin/bash"

continuation.yield(.startAction(id: "run", task: "Run `\(request.text)`"))

let output = terminal.streamCommand(
shell,
arguments: ["-i", "-l", "-c", request.text],
currentDirectoryURL: projectURL,
environment: environment
)

continuation.yield(.finishAction(
id: "run",
result: .success("Executed.")
))

for try await content in output {
try Task.checkCancellation()
streamOutput(content)
}
} catch let error as Terminal.TerminationError {
continuation.yield(.content(.text("""

[error: \(error.reason)]
""")))
} catch {
continuation.yield(.content(.text("""

[error: \(error.localizedDescription)]
""")))
}

continuation.finish()
}

continuation.onTermination = { _ in
task.cancel()
Task {
await self.terminal.terminate()
}
}
}
}
}

6 changes: 6 additions & 0 deletions ChatPlugins/Tests/ChatPluginsTests/ChatPluginsTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Testing
@testable import ChatPlugins

@Test func example() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
}
6 changes: 4 additions & 2 deletions Copilot for Xcode.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
C8216B772980370100AD38C7 /* ReloadLaunchAgent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReloadLaunchAgent.swift; sourceTree = "<group>"; };
C828B27D2B1F241500E7612A /* ExtensionPoint.appextensionpoint */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = ExtensionPoint.appextensionpoint; sourceTree = "<group>"; };
C82E38492A1F025F00D4EADF /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
C84FD9D72CC671C600BE5093 /* ChatPlugins */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = ChatPlugins; sourceTree = "<group>"; };
C8520300293C4D9000460097 /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
C8520308293D805800460097 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
C861A6A229E5503F005C41A3 /* PromptToCodeCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromptToCodeCommand.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -341,6 +342,7 @@
C81458AE293A009800135263 /* Config.debug.xcconfig */,
C8CD828229B88006008D044D /* TestPlan.xctestplan */,
C828B27D2B1F241500E7612A /* ExtensionPoint.appextensionpoint */,
C84FD9D72CC671C600BE5093 /* ChatPlugins */,
C81D181E2A1B509B006C1B70 /* Tool */,
C8189B282938979000C9DCDA /* Core */,
C8189B182938972F00C9DCDA /* Copilot for Xcode */,
Expand Down Expand Up @@ -775,7 +777,7 @@
DEVELOPMENT_TEAM = 5YKZ4Y3DAW;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = EditorExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(EXTESNION_BUNDLE_NAME)";
INFOPLIST_KEY_CFBundleDisplayName = "$(EXTENSION_BUNDLE_NAME)";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -803,7 +805,7 @@
DEVELOPMENT_TEAM = 5YKZ4Y3DAW;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = EditorExtension/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(EXTESNION_BUNDLE_NAME)";
INFOPLIST_KEY_CFBundleDisplayName = "$(EXTENSION_BUNDLE_NAME)";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down
Loading