Skip to content
Open
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
4 changes: 3 additions & 1 deletion plugins/build-macos-apps/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"websiteURL": "https://openai.com/",
"privacyPolicyURL": "https://openai.com/policies/privacy-policy/",
"termsOfServiceURL": "https://openai.com/policies/terms-of-use/",
"defaultPrompt": "Build/refactor native macOS UI, inspect AppKit interop, add telemetry, or debug a macOS app",
"defaultPrompt": [
"Build/refactor native macOS UI, inspect AppKit interop, add telemetry, or debug a macOS app"
],
"screenshots": [],
"brandColor": "#1F6FEB",
"composerIcon": "./assets/build-macos-apps-small.svg",
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/agents/openai.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ interface:
short_description: "Build, debug, instrument, and implement macOS apps with SwiftUI and AppKit guidance"
icon_small: "./assets/build-macos-apps-small.svg"
icon_large: "./assets/app-icon.png"
default_prompt: "Use Build macOS Apps to build or refactor native macOS UI, inspect windowing and AppKit interop issues, add telemetry, or debug a macOS app."
default_prompt: "Build/refactor native macOS UI, inspect AppKit interop, add telemetry, or debug a macOS app."
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/appkit-interop/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: appkit-interop
description: Decide when and how to bridge a macOS app from SwiftUI into AppKit. Use when implementing NSViewRepresentable or NSViewControllerRepresentable, accessing NSWindow or the responder chain, presenting panels, customizing menus, or handling desktop behaviors that SwiftUI does not model cleanly.
description: Bridge macOS SwiftUI into AppKit narrowly. Use when implementing representables, reaching NSWindow or panels, handling menus, or using the responder chain.
---

# AppKit Interop
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/build-run-debug/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: build-run-debug
description: Build, run, and debug local macOS apps and desktop executables using shell-first Xcode and Swift workflows. Use when asked to build a Mac app, launch it, diagnose compiler or linker failures, inspect startup problems, or debug desktop-only runtime issues.
description: Build, run, and debug macOS apps with shell-first Xcode and Swift workflows. Use when launching apps or diagnosing build, startup, or runtime failures.
---

# Build / Run / Debug
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/liquid-glass/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: liquid-glass
description: Implement, refactor, or review modern macOS SwiftUI UI for the new design system and Liquid Glass. Use when adopting Liquid Glass, updating NavigationSplitView, toolbars, search, sheets, and controls, removing custom backgrounds that fight system materials, or building custom glass surfaces with glassEffect, GlassEffectContainer, and glassEffectID.
description: Implement and review macOS SwiftUI Liquid Glass UI. Use when adopting system glass, removing conflicting custom chrome, or building glass surfaces.
---

# Liquid Glass
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: packaging-notarization
description: Prepare and troubleshoot packaging, signing, and notarization workflows for macOS distribution. Use when asked to archive a Mac app, validate bundle structure, reason about notarization readiness, or explain distribution-only failures.
description: Prepare macOS packaging and notarization workflows. Use when archiving apps, validating bundles, or explaining distribution-only failures.
---

# Packaging & Notarization
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: signing-entitlements
description: Inspect signing, entitlements, hardened runtime, and Gatekeeper issues for macOS apps. Use when asked to diagnose code signing failures, missing entitlements, sandbox problems, notarization prerequisites, or trust-policy launch errors.
description: Inspect macOS signing, entitlements, and Gatekeeper issues. Use when diagnosing code signing, sandbox, hardened runtime, or trust failures.
---

# Signing & Entitlements
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/swiftpm-macos/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: swiftpm-macos
description: Build, run, and test pure SwiftPM-based macOS packages and executables. Use when the repo is package-first, when there is no Xcode project, or when Swift package workflows are the fastest path to diagnosis.
description: Build, run, and test SwiftPM macOS packages and executables. Use when the repo is package-first or has no Xcode project.
---

# SwiftPM for macOS
Expand Down
80 changes: 3 additions & 77 deletions plugins/build-macos-apps/skills/swiftui-patterns/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: swiftui-patterns
description: Best practices and example-driven guidance for building native macOS SwiftUI scenes and components, including windows, commands, toolbars, settings, split views, inspectors, menu bar extras, and keyboard-driven workflows. Use when creating or refactoring macOS SwiftUI UI, choosing scene types, wiring menus or settings, or needing desktop-specific component patterns and examples.
description: Build macOS SwiftUI scenes and components with desktop patterns. Use when shaping windows, commands, toolbars, settings, split views, or inspectors.
---

# SwiftUI Patterns
Expand Down Expand Up @@ -71,82 +71,8 @@ Before writing the full UI:
- Keep primary actions discoverable from both UI chrome and keyboard shortcuts when appropriate.
- Use SwiftUI-native scenes and views first. If you need low-level window, responder-chain, text system, or panel control, switch to `appkit-interop`.

## Recommended Sidebar Row Pattern

Prefer a native source-list row shape:

```swift
List(selection: $selection) {
ForEach(items) { item in
HStack(spacing: 10) {
Image(systemName: item.systemImage)
.foregroundStyle(.secondary)
.frame(width: 16)

VStack(alignment: .leading, spacing: 2) {
Text(item.title)
.lineLimit(1)

if let detail = item.detail {
Text(detail)
.font(.caption)
.foregroundStyle(.secondary)
.lineLimit(1)
}
}
}
.tag(item.id)
}
}
.listStyle(.sidebar)
```

This keeps selection, highlight, spacing, and scanability aligned with standard
macOS sidebars. Keep each row to one icon maximum and one or two text lines
maximum, with the second line reserved for a short detail label. Use richer card
treatments and denser metadata in the detail or inspector content, not in every
sidebar row.

## Recommended Split-View Background Pattern

Prefer letting the sidebar and split container use system backgrounds, while
applying custom surfaces only to detail cards or inspector sections:

```swift
NavigationSplitView {
List(selection: $selection) {
ForEach(items) { item in
Label(item.title, systemImage: item.systemImage)
.tag(item.id)
}
}
.listStyle(.sidebar)
} detail: {
ScrollView {
VStack(alignment: .leading, spacing: 16) {
DetailSummaryCard(item: selectedItem)
DetailMetricsCard(item: selectedItem)
}
.padding()
}
}
```

Avoid painting the sidebar and root split panes with opaque custom fills by
default:

```swift
NavigationSplitView {
List(items) { item in
SidebarCardRow(item: item)
}
.listStyle(.sidebar)
.background(Color(nsColor: .windowBackgroundColor))
} detail: {
DetailView(item: selectedItem)
.background(Color(.white))
}
```
For concrete sidebar row and split-view background examples, read
`references/split-inspectors.md`.

## State Ownership Summary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,79 @@ struct LibraryRootView: View {
}
```

## Example: native sidebar row

Prefer a native source-list row shape:

```swift
List(selection: $selection) {
ForEach(items) { item in
HStack(spacing: 10) {
Image(systemName: item.systemImage)
.foregroundStyle(.secondary)
.frame(width: 16)

VStack(alignment: .leading, spacing: 2) {
Text(item.title)
.lineLimit(1)

if let detail = item.detail {
Text(detail)
.font(.caption)
.foregroundStyle(.secondary)
.lineLimit(1)
}
}
}
.tag(item.id)
}
}
.listStyle(.sidebar)
```

Keep each row to one icon and one or two text lines. Put richer metadata in the
detail or inspector content instead of every sidebar row.

## Example: split-view backgrounds

Let the sidebar and split container keep system backgrounds while detail content
owns custom surfaces:

```swift
NavigationSplitView {
List(selection: $selection) {
ForEach(items) { item in
Label(item.title, systemImage: item.systemImage)
.tag(item.id)
}
}
.listStyle(.sidebar)
} detail: {
ScrollView {
VStack(alignment: .leading, spacing: 16) {
DetailSummaryCard(item: selectedItem)
DetailMetricsCard(item: selectedItem)
}
.padding()
}
}
```

Avoid opaque sidebar and root split-pane fills by default:

```swift
NavigationSplitView {
List(items) { item in
SidebarCardRow(item: item)
}
.listStyle(.sidebar)
.background(Color(nsColor: .windowBackgroundColor))
} detail: {
DetailView(item: selectedItem)
.background(Color(.white))
}
```

## Pitfalls

- Avoid swapping the whole root layout with top-level conditionals when selection changes.
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/telemetry/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: telemetry
description: Add lightweight runtime telemetry and debug instrumentation to macOS apps, then verify those events after building and running. Use when wiring `Logger` / `os.Logger`, adding log points for window/sidebar/menu-bar actions, reading runtime logs from Console or `log stream`, or confirming that expected events fire after a local run.
description: Add and verify lightweight macOS runtime telemetry. Use when wiring Logger events or inspecting logs for windows, sidebars, menus, and actions.
---

# Telemetry
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/test-triage/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: test-triage
description: Triage failing macOS tests across Xcode and SwiftPM workflows. Use when asked to run macOS tests, narrow failing scopes, explain assertion or crash failures, or separate real test regressions from setup and environment problems.
description: Triage macOS tests across Xcode and SwiftPM. Use when narrowing failures, explaining assertions or crashes, or separating setup from regressions.
---

# Test Triage
Expand Down
2 changes: 1 addition & 1 deletion plugins/build-macos-apps/skills/view-refactor/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: view-refactor
description: Refactor macOS SwiftUI views and scenes with strong defaults for small dedicated subviews, stable sidebar and selection structure, explicit command and toolbar ownership, scene-aware state, and narrow AppKit escape hatches. Use when cleaning up a macOS view file, splitting oversized scene roots, removing iOS-centric patterns, or tightening mixed SwiftUI/AppKit architecture.
description: Refactor macOS SwiftUI views and scenes into stable structure. Use when splitting large views, tightening scene state, or narrowing AppKit escapes.
---

# View Refactor
Expand Down
61 changes: 2 additions & 59 deletions plugins/build-macos-apps/skills/window-management/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: window-management
description: Customize macOS 15+ SwiftUI windows and scene behavior using Window, WindowGroup, and macOS window modifiers. Use when styling or hiding window toolbars and titles, extending drag regions with WindowDragGesture, replacing window backgrounds with materials, disabling minimize or restoration for utility windows, setting default or ideal window placement from content/display size, creating borderless windows, or tuning default launch behavior.
description: Customize macOS SwiftUI windows and scene behavior. Use when tuning window chrome, drag regions, placement, restoration, launch behavior, or borderless windows.
---

# Window Management
Expand Down Expand Up @@ -124,64 +124,7 @@ deployment targets, expect to use more AppKit bridging or availability guards.
- Keep one clear path back to regular window management if the plain style makes
the window feel invisible or hard to move.

## API Snippets

```swift
WindowGroup("Destination Video") {
CatalogView()
.toolbar(removing: .title)
.toolbarBackgroundVisibility(.hidden, for: .windowToolbar)
}
```

```swift
Window("About", id: "about") {
AboutView()
.toolbar(removing: .title)
.toolbarBackgroundVisibility(.hidden, for: .windowToolbar)
.containerBackground(.thickMaterial, for: .window)
}
.windowMinimizeBehavior(.disabled)
.restorationBehavior(.disabled)
```

```swift
WindowGroup("Player", for: Video.self) { $video in
PlayerView(video: video)
}
.defaultWindowPlacement { content, context in
let idealSize = content.sizeThatFits(.unspecified)
let displayBounds = context.defaultDisplay.visibleRect
let fittedSize = clampToDisplay(idealSize, displayBounds: displayBounds)
return WindowPlacement(size: fittedSize)
}
.windowIdealPlacement { content, context in
let idealSize = content.sizeThatFits(.unspecified)
let displayBounds = context.defaultDisplay.visibleRect
let zoomedSize = zoomToFit(idealSize, displayBounds: displayBounds)
let position = centeredPosition(for: zoomedSize, in: displayBounds)
return WindowPlacement(position, size: zoomedSize)
}
```

```swift
PlayerView(video: video)
.overlay(alignment: .top) {
Color.clear
.frame(height: 48)
.contentShape(Rectangle())
.gesture(WindowDragGesture())
.allowsWindowActivationEvents(true)
}
```

```swift
Window("Welcome", id: "welcome") {
WelcomeView()
}
.windowStyle(.plain)
.defaultLaunchBehavior(.presented)
```
For concrete window modifier examples, read `references/api-snippets.md`.

## Review Checklist

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Window API Snippets

Use these examples after the window role and modifier choices are clear.

```swift
WindowGroup("Destination Video") {
CatalogView()
.toolbar(removing: .title)
.toolbarBackgroundVisibility(.hidden, for: .windowToolbar)
}
```

```swift
Window("About", id: "about") {
AboutView()
.toolbar(removing: .title)
.toolbarBackgroundVisibility(.hidden, for: .windowToolbar)
.containerBackground(.thickMaterial, for: .window)
}
.windowMinimizeBehavior(.disabled)
.restorationBehavior(.disabled)
```

```swift
WindowGroup("Player", for: Video.self) { $video in
PlayerView(video: video)
}
.defaultWindowPlacement { content, context in
let idealSize = content.sizeThatFits(.unspecified)
let displayBounds = context.defaultDisplay.visibleRect
let fittedSize = clampToDisplay(idealSize, displayBounds: displayBounds)
return WindowPlacement(size: fittedSize)
}
.windowIdealPlacement { content, context in
let idealSize = content.sizeThatFits(.unspecified)
let displayBounds = context.defaultDisplay.visibleRect
let zoomedSize = zoomToFit(idealSize, displayBounds: displayBounds)
let position = centeredPosition(for: zoomedSize, in: displayBounds)
return WindowPlacement(position, size: zoomedSize)
}
```

```swift
PlayerView(video: video)
.overlay(alignment: .top) {
Color.clear
.frame(height: 48)
.contentShape(Rectangle())
.gesture(WindowDragGesture())
.allowsWindowActivationEvents(true)
}
```

```swift
Window("Welcome", id: "welcome") {
WelcomeView()
}
.windowStyle(.plain)
.defaultLaunchBehavior(.presented)
```