Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/auto-close-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
"At the moment we are not accepting contributions to the repository.
Feedback for GitHub Copilot for Xcode can be given in the [Copilot community discussions](https://github.com/github/CopilotForXcode/discussions)."
if: ${{ !(startsWith(github.head_ref, 'release/') && github.event.pull_request.head.repo.full_name == github.repository) }}
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72 changes: 72 additions & 0 deletions .github/workflows/auto-create-release-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Auto-create Release PR

on:
push:
branches:
- 'release/**'

jobs:
create-pr:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4

- name: Create pull request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
existing_pr_count="$(gh pr list \
--state open \
--base main \
--head "${{ github.ref_name }}" \
--json number \
--jq 'length')"
if [ "${existing_pr_count}" -gt 0 ]; then
echo "Open pull request already exists for branch '${{ github.ref_name }}' into 'main'; skipping creation."
else
gh pr create \
--title "$(git log -1 --pretty=%s)" \
--body "Automated release PR." \
--base main \
--head "${{ github.ref_name }}"
fi

- name: Approve pull request
env:
# PAT stored in github/CopilotForXcode, with write permissions to pull requests
GH_TOKEN: ${{ secrets.XCODE_AUTO_APPROVE }}
run: |
gh pr review --approve "${{ github.ref_name }}"

- name: Wait for required checks
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
for i in $(seq 1 60); do
other_checks=$(gh pr checks "${{ github.ref_name }}" | grep -v "create-pr" || true)
if echo "$other_checks" | grep -wq "fail"; then
echo "Required checks failed."
exit 1
fi
if [ -z "$other_checks" ]; then
echo "No other checks found yet, waiting..."
elif ! echo "$other_checks" | grep -wq "pending"; then
echo "All required checks passed."
exit 0
fi
echo "Waiting for checks..."
sleep 10
done
echo "Timed out waiting for required checks."
exit 1

- name: Merge pull request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr merge "${{ github.ref_name }}" \
--merge \
--delete-branch
8 changes: 6 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ jobs:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
- language: python
build-mode: none
- language: swift
Expand All @@ -37,7 +41,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
Expand Down Expand Up @@ -66,6 +70,6 @@ jobs:
CODE_SIGNING_ALLOWED="NO"

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.50.0 - May 20, 2026
### Added
- Reasoning effort control for supported models: Low, Medium, or High from the model picker to balance response speed and quality.
- Added internal support for upcoming usage-based billing, including billing updates for the usage panel, usage notifications, and model picker. This will be visible to the user once usage-based billing rolls out.

### Changed
- Bring Your Own Key (BYOK) is now generally available.

## 0.49.0 - May 15, 2026
### Added
- Native Anthropic Messages API (`/v1/messages`) endpoint support.
- Thinking support in chat for reasoning-capable models.
- Enhanced rate limit notifications and error messages.

### Changed
- Refined tool call item UI in agent progress: removed border and divider, repositioned chevron, and adjusted spacing for better readability.
- Updated Copilot language server to 1.465.5.

## 0.48.0 - April 23, 2026
### Added
- Context window usage details in chat, including a token breakdown for system instructions, messages, attached files, and tool results.
- Auto Compress setting to compact conversation history and save context tokens.
- Install flow for Xcode's built-in MCP server from settings.

### Changed
- Custom agents and the Auto model are now generally available.
- Removed support for macOS 12.
- Improved UI for model picker tooltips.

### Fixed
- Fixed an issue where GPT-5.4 requests could return a 400 error.
- Fixed an issue where the MCP allowlist did not work correctly.

## 0.47.0 - February 4, 2026
### Added
- Auto approval for MCP tools, sensitive files, and terminal commands.
Expand Down
2 changes: 1 addition & 1 deletion CommunicationBridge/ServiceDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ actor ExtensionServiceLauncher {
return configuration
}()
) { app, error in
if let error = error {
if error != nil {
continuation.resume(returning: nil)
} else {
continuation.resume(returning: app)
Expand Down
24 changes: 12 additions & 12 deletions Copilot for Xcode.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "$(APP_VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE).EditorExtension";
PRODUCT_NAME = Copilot;
Expand Down Expand Up @@ -874,7 +874,7 @@
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "$(APP_VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE).EditorExtension";
PRODUCT_NAME = Copilot;
Expand Down Expand Up @@ -936,7 +936,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -991,7 +991,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
Expand Down Expand Up @@ -1022,7 +1022,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "$(APP_VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE)";
PRODUCT_MODULE_NAME = Copilot_for_Xcode;
Expand Down Expand Up @@ -1056,7 +1056,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "$(APP_VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE)";
PRODUCT_NAME = "$(HOST_APP_NAME)";
Expand All @@ -1072,7 +1072,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = VEKTX9H2N7;
ENABLE_HARDENED_RUNTIME = YES;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
Expand All @@ -1087,7 +1087,7 @@
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = VEKTX9H2N7;
ENABLE_HARDENED_RUNTIME = YES;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
Expand Down Expand Up @@ -1117,7 +1117,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "$(APP_VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE).ExtensionService";
PRODUCT_NAME = "$(EXTENSION_SERVICE_NAME)";
Expand Down Expand Up @@ -1151,7 +1151,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "$(APP_VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE).ExtensionService";
PRODUCT_NAME = "$(EXTENSION_SERVICE_NAME)";
Expand All @@ -1172,7 +1172,7 @@
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE).CommunicationBridge";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
Expand All @@ -1193,7 +1193,7 @@
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 13.0;
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_IDENTIFIER_BASE).CommunicationBridge";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
25 changes: 10 additions & 15 deletions Copilot for Xcode/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationDidFinishLaunching(_ notification: Notification) {
if #available(macOS 13.0, *) {
checkBackgroundPermissions()
}

checkBackgroundPermissions()

let launchMode = determineLaunchMode()
handleLaunchMode(launchMode)
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if #available(macOS 13.0, *) {
checkBackgroundPermissions()
}

checkBackgroundPermissions()

let launchMode = determineLaunchMode()
handleLaunchMode(launchMode)
return true
Expand Down Expand Up @@ -113,7 +109,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}

@available(macOS 13.0, *)
private func checkBackgroundPermissions() {
Task {
// Direct check of permission status
Expand All @@ -122,15 +117,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {

if !isPermissionGranted {
// Only show alert if permission isn't granted
DispatchQueue.main.async {
await MainActor.run {
if !self.permissionAlertShown {
showBackgroundPermissionAlert()
self.permissionAlertShown = true
}
}
} else {
// Permission is granted, reset flag
self.permissionAlertShown = false
await MainActor.run {
self.permissionAlertShown = false
}
}
}
}
Expand All @@ -147,7 +144,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {

// Start cleanup in background without waiting
Task {
let quitTask = Task {
_ = Task {
let service = try? getService()
try? await service?.quitService()
}
Expand Down Expand Up @@ -272,10 +269,8 @@ func activateAndOpenSettings() {
if #available(macOS 14.0, *) {
let environment = SettingsEnvironment()
environment.open()
} else if #available(macOS 13.0, *) {
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
} else {
NSApp.sendAction(Selector(("showPreferencesWindow:")), to: nil, from: nil)
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
}
}

Expand Down
7 changes: 6 additions & 1 deletion Core/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import PackageDescription

let package = Package(
name: "Core",
platforms: [.macOS(.v12)],
platforms: [.macOS(.v13)],
products: [
.library(
name: "Service",
Expand Down Expand Up @@ -75,6 +75,7 @@ let package = Package(
dependencies: [
"SuggestionWidget",
"SuggestionService",
"SuggestionInjector",
"ChatService",
"PromptToCodeService",
"ConversationTab",
Expand Down Expand Up @@ -123,6 +124,7 @@ let package = Package(
"Client",
"LaunchAgentManager",
"GitHubCopilotViewModel",
"UpdateChecker",
.product(name: "SuggestionProvider", package: "Tool"),
.product(name: "Toast", package: "Tool"),
.product(name: "SharedUIComponents", package: "Tool"),
Expand Down Expand Up @@ -202,6 +204,7 @@ let package = Package(
name: "ConversationTab",
dependencies: [
"ChatService",
"GitHubCopilotViewModel",
.product(name: "SharedUIComponents", package: "Tool"),
.product(name: "ChatAPIService", package: "Tool"),
.product(name: "Logger", package: "Tool"),
Expand All @@ -225,6 +228,7 @@ let package = Package(
"ConversationTab",
"GitHubCopilotViewModel",
"PersistMiddleware",
.product(name: "CGEventOverride", package: "CGEventOverride"),
.product(name: "GitHubCopilotService", package: "Tool"),
.product(name: "Toast", package: "Tool"),
.product(name: "UserDefaultsObserver", package: "Tool"),
Expand Down Expand Up @@ -265,6 +269,7 @@ let package = Package(
.product(name: "GitHubCopilotService", package: "Tool"),
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
.product(name: "Status", package: "Tool"),
.product(name: "Logger", package: "Tool"),
]
),

Expand Down
Loading
Loading