From 70be11cc454a17ce9b6cb9a850a109a0b4004c13 Mon Sep 17 00:00:00 2001 From: Okmin Date: Thu, 19 Feb 2026 12:01:18 +0900 Subject: [PATCH 1/8] feat(skills): add liquid-glass-design skill for iOS 26 Liquid Glass UI system Add comprehensive skill covering Apple's Liquid Glass design system introduced in iOS 26, including SwiftUI, UIKit, and WidgetKit patterns. --- skills/liquid-glass-design/SKILL.md | 269 ++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 skills/liquid-glass-design/SKILL.md diff --git a/skills/liquid-glass-design/SKILL.md b/skills/liquid-glass-design/SKILL.md new file mode 100644 index 00000000..bf068910 --- /dev/null +++ b/skills/liquid-glass-design/SKILL.md @@ -0,0 +1,269 @@ +--- +name: liquid-glass-design +description: iOS 26 Liquid Glass design system — dynamic glass material with blur, reflection, and interactive morphing for SwiftUI, UIKit, and WidgetKit. +--- + +# Liquid Glass Design System (iOS 26) + +Patterns for implementing Apple's Liquid Glass — a dynamic material that blurs content behind it, reflects color and light from surrounding content, and reacts to touch and pointer interactions. Covers SwiftUI, UIKit, and WidgetKit integration. + +## When to Activate + +- Building or updating apps for iOS 26+ with the new design language +- Implementing glass-style buttons, cards, toolbars, or containers +- Creating morphing transitions between glass elements +- Applying Liquid Glass effects to widgets +- Migrating existing blur/material effects to the new Liquid Glass API + +## Core Pattern — SwiftUI + +### Basic Glass Effect + +The simplest way to add Liquid Glass to any view: + +```swift +Text("Hello, World!") + .font(.title) + .padding() + .glassEffect() // Default: regular variant, capsule shape +``` + +### Customizing Shape and Tint + +```swift +Text("Hello, World!") + .font(.title) + .padding() + .glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0)) +``` + +Key customization options: +- `.regular` — standard glass effect +- `.tint(Color)` — add color tint for prominence +- `.interactive()` — react to touch and pointer interactions +- Shape: `.capsule` (default), `.rect(cornerRadius:)`, `.circle` + +### Glass Button Styles + +```swift +Button("Click Me") { /* action */ } + .buttonStyle(.glass) + +Button("Important") { /* action */ } + .buttonStyle(.glassProminent) +``` + +### GlassEffectContainer for Multiple Elements + +Always wrap multiple glass views in a container for performance and morphing: + +```swift +GlassEffectContainer(spacing: 40.0) { + HStack(spacing: 40.0) { + Image(systemName: "scribble.variable") + .frame(width: 80.0, height: 80.0) + .font(.system(size: 36)) + .glassEffect() + + Image(systemName: "eraser.fill") + .frame(width: 80.0, height: 80.0) + .font(.system(size: 36)) + .glassEffect() + } +} +``` + +The `spacing` parameter controls merge distance — closer elements blend their glass shapes together. + +### Uniting Glass Effects + +Combine multiple views into a single glass shape with `glassEffectUnion`: + +```swift +@Namespace private var namespace + +GlassEffectContainer(spacing: 20.0) { + HStack(spacing: 20.0) { + ForEach(symbolSet.indices, id: \.self) { item in + Image(systemName: symbolSet[item]) + .frame(width: 80.0, height: 80.0) + .glassEffect() + .glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace) + } + } +} +``` + +### Morphing Transitions + +Create smooth morphing when glass elements appear/disappear: + +```swift +@State private var isExpanded = false +@Namespace private var namespace + +GlassEffectContainer(spacing: 40.0) { + HStack(spacing: 40.0) { + Image(systemName: "scribble.variable") + .frame(width: 80.0, height: 80.0) + .glassEffect() + .glassEffectID("pencil", in: namespace) + + if isExpanded { + Image(systemName: "eraser.fill") + .frame(width: 80.0, height: 80.0) + .glassEffect() + .glassEffectID("eraser", in: namespace) + } + } +} + +Button("Toggle") { + withAnimation { isExpanded.toggle() } +} +.buttonStyle(.glass) +``` + +### Scroll and Sidebar Extensions + +```swift +// Extend horizontal scroll under sidebar +ScrollView(.horizontal) { /* content */ } + .scrollExtensionMode(.underSidebar) +``` + +## Core Pattern — UIKit + +### Basic UIGlassEffect + +```swift +let glassEffect = UIGlassEffect() +glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3) +glassEffect.isInteractive = true + +let visualEffectView = UIVisualEffectView(effect: glassEffect) +visualEffectView.layer.cornerRadius = 20 +visualEffectView.clipsToBounds = true + +// Add content to contentView +let label = UILabel() +label.text = "Liquid Glass" +visualEffectView.contentView.addSubview(label) +``` + +### UIGlassContainerEffect for Multiple Elements + +```swift +let containerEffect = UIGlassContainerEffect() +containerEffect.spacing = 40.0 + +let containerView = UIVisualEffectView(effect: containerEffect) + +let firstGlass = UIVisualEffectView(effect: UIGlassEffect()) +let secondGlass = UIVisualEffectView(effect: UIGlassEffect()) + +containerView.contentView.addSubview(firstGlass) +containerView.contentView.addSubview(secondGlass) +``` + +### Scroll Edge Effects + +```swift +scrollView.topEdgeEffect.style = .automatic +scrollView.bottomEdgeEffect.style = .hard +scrollView.leftEdgeEffect.isHidden = true +``` + +### Toolbar Glass Integration + +```swift +let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction)) +favoriteButton.hidesSharedBackground = true // Opt out of shared glass background +``` + +## Core Pattern — WidgetKit + +### Rendering Mode Detection + +```swift +struct MyWidgetView: View { + @Environment(\.widgetRenderingMode) var renderingMode + + var body: some View { + if renderingMode == .accented { + // Tinted mode: white-tinted, themed glass background + } else { + // Full color mode: standard appearance + } + } +} +``` + +### Accent Groups for Visual Hierarchy + +```swift +HStack { + VStack(alignment: .leading) { + Text("Title") + .widgetAccentable() // Accent group + Text("Subtitle") + // Primary group (default) + } + Image(systemName: "star.fill") + .widgetAccentable() // Accent group +} +``` + +### Image Rendering in Accented Mode + +```swift +Image("myImage") + .widgetAccentedRenderingMode(.monochrome) +``` + +### Container Background + +```swift +VStack { /* content */ } + .containerBackground(for: .widget) { + Color.blue.opacity(0.2) + } +``` + +## Key Design Decisions + +| Decision | Rationale | +|----------|-----------| +| GlassEffectContainer wrapping | Performance optimization, enables morphing between glass elements | +| `spacing` parameter | Controls merge distance — fine-tune how close elements must be to blend | +| `@Namespace` + `glassEffectID` | Enables smooth morphing transitions on view hierarchy changes | +| `interactive()` modifier | Explicit opt-in for touch/pointer reactions — not all glass should respond | +| UIGlassContainerEffect in UIKit | Same container pattern as SwiftUI for consistency | +| Accented rendering mode in widgets | System applies tinted glass when user selects tinted Home Screen | + +## Best Practices + +- **Always use GlassEffectContainer** when applying glass to multiple sibling views — it enables morphing and improves rendering performance +- **Apply `.glassEffect()` after** other appearance modifiers (frame, font, padding) +- **Use `.interactive()`** only on elements that respond to user interaction (buttons, toggleable items) +- **Choose spacing carefully** in containers to control when glass effects merge +- **Use `withAnimation`** when changing view hierarchies to enable smooth morphing transitions +- **Test across appearances** — light mode, dark mode, and accented/tinted modes +- **Ensure accessibility contrast** — text on glass must remain readable + +## Anti-Patterns to Avoid + +- Using multiple standalone `.glassEffect()` views without a GlassEffectContainer +- Nesting too many glass effects — degrades performance and visual clarity +- Applying glass to every view — reserve for interactive elements, toolbars, and cards +- Forgetting `clipsToBounds = true` in UIKit when using corner radii +- Ignoring accented rendering mode in widgets — breaks tinted Home Screen appearance +- Using opaque backgrounds behind glass — defeats the translucency effect + +## When to Use + +- Navigation bars, toolbars, and tab bars with the new iOS 26 design +- Floating action buttons and card-style containers +- Interactive controls that need visual depth and touch feedback +- Widgets that should integrate with the system's Liquid Glass appearance +- Morphing transitions between related UI states From 1fb2e460decfdefaf19c080a043a40f5538c16ba Mon Sep 17 00:00:00 2001 From: Okmin Date: Thu, 19 Feb 2026 12:01:24 +0900 Subject: [PATCH 2/8] feat(skills): add foundation-models-on-device skill for Apple on-device LLM Add skill covering Apple's FoundationModels framework for on-device language model integration, including @Generable guided generation, tool calling, and snapshot streaming patterns. --- skills/foundation-models-on-device/SKILL.md | 231 ++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 skills/foundation-models-on-device/SKILL.md diff --git a/skills/foundation-models-on-device/SKILL.md b/skills/foundation-models-on-device/SKILL.md new file mode 100644 index 00000000..365bd747 --- /dev/null +++ b/skills/foundation-models-on-device/SKILL.md @@ -0,0 +1,231 @@ +--- +name: foundation-models-on-device +description: Apple FoundationModels framework for on-device LLM — text generation, guided generation with @Generable, tool calling, and snapshot streaming in iOS 26+. +--- + +# FoundationModels: On-Device LLM (iOS 26) + +Patterns for integrating Apple's on-device language model into apps using the FoundationModels framework. Covers text generation, structured output with `@Generable`, custom tool calling, and snapshot streaming — all running on-device for privacy and offline support. + +## When to Activate + +- Building AI-powered features using Apple Intelligence on-device +- Generating or summarizing text without cloud dependency +- Extracting structured data from natural language input +- Implementing custom tool calling for domain-specific AI actions +- Streaming structured responses for real-time UI updates +- Need privacy-preserving AI (no data leaves the device) + +## Core Pattern — Availability Check + +Always check model availability before creating a session: + +```swift +struct GenerativeView: View { + private var model = SystemLanguageModel.default + + var body: some View { + switch model.availability { + case .available: + ContentView() + case .unavailable(.deviceNotEligible): + Text("Device not eligible for Apple Intelligence") + case .unavailable(.appleIntelligenceNotEnabled): + Text("Please enable Apple Intelligence in Settings") + case .unavailable(.modelNotReady): + Text("Model is downloading or not ready") + case .unavailable(let other): + Text("Model unavailable: \(other)") + } + } +} +``` + +## Core Pattern — Basic Session + +```swift +// Single-turn: create a new session each time +let session = LanguageModelSession() +let response = try await session.respond(to: "What's a good month to visit Paris?") +print(response.content) + +// Multi-turn: reuse session for conversation context +let session = LanguageModelSession(instructions: """ + You are a cooking assistant. + Provide recipe suggestions based on ingredients. + Keep suggestions brief and practical. + """) + +let first = try await session.respond(to: "I have chicken and rice") +let followUp = try await session.respond(to: "What about a vegetarian option?") +``` + +Key points for instructions: +- Define the model's role ("You are a mentor") +- Specify what to do ("Help extract calendar events") +- Set style preferences ("Respond as briefly as possible") +- Add safety measures ("Respond with 'I can't help with that' for dangerous requests") + +## Core Pattern — Guided Generation with @Generable + +Generate structured Swift types instead of raw strings: + +### 1. Define a Generable Type + +```swift +@Generable(description: "Basic profile information about a cat") +struct CatProfile { + var name: String + + @Guide(description: "The age of the cat", .range(0...20)) + var age: Int + + @Guide(description: "A one sentence profile about the cat's personality") + var profile: String +} +``` + +### 2. Request Structured Output + +```swift +let response = try await session.respond( + to: "Generate a cute rescue cat", + generating: CatProfile.self +) + +// Access structured fields directly +print("Name: \(response.content.name)") +print("Age: \(response.content.age)") +print("Profile: \(response.content.profile)") +``` + +### Supported @Guide Constraints + +- `.range(0...20)` — numeric range +- `.count(3)` — array element count +- `description:` — semantic guidance for generation + +## Core Pattern — Tool Calling + +Let the model invoke custom code for domain-specific tasks: + +### 1. Define a Tool + +```swift +struct RecipeSearchTool: Tool { + struct Arguments: Codable { + var searchTerm: String + var numberOfResults: Int + } + + func call(arguments: Arguments) async throws -> ToolOutput { + let recipes = await searchRecipes( + term: arguments.searchTerm, + limit: arguments.numberOfResults + ) + return .string(recipes.map { "- \($0.name): \($0.description)" }.joined(separator: "\n")) + } +} +``` + +### 2. Create Session with Tools + +```swift +let session = LanguageModelSession(tools: [RecipeSearchTool()]) +let response = try await session.respond(to: "Find me some pasta recipes") +``` + +### 3. Handle Tool Errors + +```swift +do { + let answer = try await session.respond("Find a recipe for tomato soup.") +} catch let error as LanguageModelSession.ToolCallError { + print(error.tool.name) + if case .databaseIsEmpty = error.underlyingError as? RecipeSearchToolError { + // Handle specific tool error + } +} +``` + +## Core Pattern — Snapshot Streaming + +Stream structured responses for real-time UI with `PartiallyGenerated` types: + +```swift +@Generable +struct TripIdeas { + @Guide(description: "Ideas for upcoming trips") + var ideas: [String] +} + +let stream = session.streamResponse( + to: "What are some exciting trip ideas?", + generating: TripIdeas.self +) + +for try await partial in stream { + // partial: TripIdeas.PartiallyGenerated (all properties Optional) + print(partial) +} +``` + +### SwiftUI Integration + +```swift +@State private var partialResult: TripIdeas.PartiallyGenerated? + +var body: some View { + List { + ForEach(partialResult?.ideas ?? [], id: \.self) { idea in + Text(idea) + } + } + .task { + let stream = session.streamResponse(to: prompt, generating: TripIdeas.self) + for try await partial in stream { + partialResult = partial + } + } +} +``` + +## Key Design Decisions + +| Decision | Rationale | +|----------|-----------| +| On-device execution | Privacy — no data leaves the device; works offline | +| 4,096 token limit | On-device model constraint; chunk large data across sessions | +| Snapshot streaming (not deltas) | Structured output friendly; each snapshot is a complete partial state | +| `@Generable` macro | Compile-time safety for structured generation; auto-generates `PartiallyGenerated` type | +| Single request per session | `isResponding` prevents concurrent requests; create multiple sessions if needed | +| `response.content` (not `.output`) | Correct API — always access results via `.content` property | + +## Best Practices + +- **Always check `model.availability`** before creating a session — handle all unavailability cases +- **Use `instructions`** to guide model behavior — they take priority over prompts +- **Check `isResponding`** before sending a new request — sessions handle one request at a time +- **Access `response.content`** for results — not `.output` +- **Break large inputs into chunks** — 4,096 token limit applies to instructions + prompt + output combined +- **Use `@Generable`** for structured output — stronger guarantees than parsing raw strings +- **Use `GenerationOptions(temperature:)`** to tune creativity (higher = more creative) +- **Monitor with Instruments** — use Xcode Instruments to profile request performance + +## Anti-Patterns to Avoid + +- Creating sessions without checking `model.availability` first +- Sending inputs exceeding the 4,096 token context window +- Attempting concurrent requests on a single session +- Using `.output` instead of `.content` to access response data +- Parsing raw string responses when `@Generable` structured output would work +- Building complex multi-step logic in a single prompt — break into multiple focused prompts +- Assuming the model is always available — device eligibility and settings vary + +## When to Use + +- On-device text generation for privacy-sensitive apps +- Structured data extraction from user input (forms, natural language commands) +- AI-assisted features that must work offline +- Streaming UI that progressively shows generated content +- Domain-specific AI actions via tool calling (search, compute, lookup) From 721a2b2840614b0616ac08d87ebbfc09a48b1abf Mon Sep 17 00:00:00 2001 From: Okmin Date: Thu, 19 Feb 2026 12:01:29 +0900 Subject: [PATCH 3/8] feat(skills): add swift-concurrency-6-2 skill for Approachable Concurrency Add skill covering Swift 6.2 Approachable Concurrency model including single-threaded defaults, @concurrent for explicit background offloading, isolated conformances, and MainActor default inference mode. --- skills/swift-concurrency-6-2/SKILL.md | 213 ++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 skills/swift-concurrency-6-2/SKILL.md diff --git a/skills/swift-concurrency-6-2/SKILL.md b/skills/swift-concurrency-6-2/SKILL.md new file mode 100644 index 00000000..7def68b2 --- /dev/null +++ b/skills/swift-concurrency-6-2/SKILL.md @@ -0,0 +1,213 @@ +--- +name: swift-concurrency-6-2 +description: Swift 6.2 Approachable Concurrency — single-threaded by default, @concurrent for explicit background offloading, isolated conformances for main actor types. +--- + +# Swift 6.2 Approachable Concurrency + +Patterns for adopting Swift 6.2's concurrency model where code runs single-threaded by default and concurrency is introduced explicitly. Eliminates common data-race errors without sacrificing performance. + +## When to Activate + +- Migrating Swift 5.x or 6.0/6.1 projects to Swift 6.2 +- Resolving data-race safety compiler errors +- Designing MainActor-based app architecture +- Offloading CPU-intensive work to background threads +- Implementing protocol conformances on MainActor-isolated types +- Enabling Approachable Concurrency build settings in Xcode 26 + +## Core Problem: Implicit Background Offloading + +In Swift 6.1 and earlier, async functions could be implicitly offloaded to background threads, causing data-race errors even in seemingly safe code: + +```swift +// Swift 6.1: ERROR +@MainActor +final class StickerModel { + let photoProcessor = PhotoProcessor() + + func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? { + guard let data = try await item.loadTransferable(type: Data.self) else { return nil } + + // Error: Sending 'self.photoProcessor' risks causing data races + return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier) + } +} +``` + +Swift 6.2 fixes this: async functions stay on the calling actor by default. + +```swift +// Swift 6.2: OK — async stays on MainActor, no data race +@MainActor +final class StickerModel { + let photoProcessor = PhotoProcessor() + + func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? { + guard let data = try await item.loadTransferable(type: Data.self) else { return nil } + return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier) + } +} +``` + +## Core Pattern — Isolated Conformances + +MainActor types can now conform to non-isolated protocols safely: + +```swift +protocol Exportable { + func export() +} + +// Swift 6.1: ERROR — crosses into main actor-isolated code +// Swift 6.2: OK with isolated conformance +extension StickerModel: @MainActor Exportable { + func export() { + photoProcessor.exportAsPNG() + } +} +``` + +The compiler ensures the conformance is only used on the main actor: + +```swift +// OK — ImageExporter is also @MainActor +@MainActor +struct ImageExporter { + var items: [any Exportable] + + mutating func add(_ item: StickerModel) { + items.append(item) // Safe: same actor isolation + } +} + +// ERROR — nonisolated context can't use MainActor conformance +nonisolated struct ImageExporter { + var items: [any Exportable] + + mutating func add(_ item: StickerModel) { + items.append(item) // Error: Main actor-isolated conformance cannot be used here + } +} +``` + +## Core Pattern — Global and Static Variables + +Protect global/static state with MainActor: + +```swift +// Swift 6.1: ERROR — non-Sendable type may have shared mutable state +final class StickerLibrary { + static let shared: StickerLibrary = .init() // Error +} + +// Fix: Annotate with @MainActor +@MainActor +final class StickerLibrary { + static let shared: StickerLibrary = .init() // OK +} +``` + +### MainActor Default Inference Mode + +Swift 6.2 introduces a mode where MainActor is inferred by default — no manual annotations needed: + +```swift +// With MainActor default inference enabled: +final class StickerLibrary { + static let shared: StickerLibrary = .init() // Implicitly @MainActor +} + +final class StickerModel { + let photoProcessor: PhotoProcessor + var selection: [PhotosPickerItem] // Implicitly @MainActor +} + +extension StickerModel: Exportable { // Implicitly @MainActor conformance + func export() { + photoProcessor.exportAsPNG() + } +} +``` + +This mode is opt-in and recommended for apps, scripts, and other executable targets. + +## Core Pattern — @concurrent for Background Work + +When you need actual parallelism, explicitly offload with `@concurrent`: + +```swift +nonisolated struct PhotoProcessor { + var cachedStickers: [String: Sticker] + + func extractSticker(data: Data, with id: String) async -> Sticker { + if let sticker = cachedStickers[id] { + return sticker + } + + let sticker = await Self.extractSubject(from: data) + cachedStickers[id] = sticker + return sticker + } + + // Offload expensive work to concurrent thread pool + @concurrent + static func extractSubject(from data: Data) async -> Sticker { /* ... */ } +} + +// Callers must await +processedPhotos[item.id] = await PhotoProcessor().process(data: data) +``` + +To use `@concurrent`: +1. Mark the containing type as `nonisolated` +2. Add `@concurrent` to the function +3. Add `async` if not already asynchronous +4. Add `await` at call sites + +## Key Design Decisions + +| Decision | Rationale | +|----------|-----------| +| Single-threaded by default | Most natural code is data-race free; concurrency is opt-in | +| Async stays on calling actor | Eliminates implicit offloading that caused data-race errors | +| Isolated conformances | MainActor types can conform to protocols without unsafe workarounds | +| `@concurrent` explicit opt-in | Background execution is a deliberate performance choice, not accidental | +| MainActor default inference | Reduces boilerplate `@MainActor` annotations for app targets | +| Opt-in adoption | Non-breaking migration path — enable features incrementally | + +## Migration Steps + +1. **Enable in Xcode**: Swift Compiler > Concurrency section in Build Settings +2. **Enable in SPM**: Use `SwiftSettings` API in package manifest +3. **Use migration tooling**: Automatic code changes via swift.org/migration +4. **Start with MainActor defaults**: Enable inference mode for app targets +5. **Add `@concurrent` where needed**: Profile first, then offload hot paths +6. **Test thoroughly**: Data-race issues become compile-time errors + +## Best Practices + +- **Start on MainActor** — write single-threaded code first, optimize later +- **Use `@concurrent` only for CPU-intensive work** — image processing, compression, complex computation +- **Enable MainActor inference mode** for app targets that are mostly single-threaded +- **Profile before offloading** — use Instruments to find actual bottlenecks +- **Protect globals with MainActor** — global/static mutable state needs actor isolation +- **Use isolated conformances** instead of `nonisolated` workarounds or `@Sendable` wrappers +- **Migrate incrementally** — enable features one at a time in build settings + +## Anti-Patterns to Avoid + +- Applying `@concurrent` to every async function (most don't need background execution) +- Using `nonisolated` to suppress compiler errors without understanding isolation +- Keeping legacy `DispatchQueue` patterns when actors provide the same safety +- Skipping `model.availability` checks in concurrency-related Foundation Models code +- Fighting the compiler — if it reports a data race, the code has a real concurrency issue +- Assuming all async code runs in the background (Swift 6.2 default: stays on calling actor) + +## When to Use + +- All new Swift 6.2+ projects (Approachable Concurrency is the recommended default) +- Migrating existing apps from Swift 5.x or 6.0/6.1 concurrency +- Resolving data-race safety compiler errors during Xcode 26 adoption +- Building MainActor-centric app architectures (most UI apps) +- Performance optimization — offloading specific heavy computations to background From 3b8c1579525b27ca26f6531ab020a22edfd39df9 Mon Sep 17 00:00:00 2001 From: Okmin Date: Thu, 19 Feb 2026 12:01:33 +0900 Subject: [PATCH 4/8] chore: update skill count from 43 to 46, add 3 iOS 26 skills to directory listing --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 063ca7dd..61e4924f 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ For manual install instructions see the README in the `rules/` folder. /plugin list everything-claude-code@everything-claude-code ``` -✨ **That's it!** You now have access to 13 agents, 44 skills, and 32 commands. +✨ **That's it!** You now have access to 13 agents, 47 skills, and 32 commands. --- @@ -252,6 +252,9 @@ everything-claude-code/ | |-- swift-actor-persistence/ # Thread-safe Swift data persistence with actors (NEW) | |-- swift-protocol-di-testing/ # Protocol-based DI for testable Swift code (NEW) | |-- search-first/ # Research-before-coding workflow (NEW) +| |-- liquid-glass-design/ # iOS 26 Liquid Glass design system (NEW) +| |-- foundation-models-on-device/ # Apple on-device LLM with FoundationModels (NEW) +| |-- swift-concurrency-6-2/ # Swift 6.2 Approachable Concurrency (NEW) | |-- commands/ # Slash commands for quick execution | |-- tdd.md # /tdd - Test-driven development @@ -811,7 +814,7 @@ The configuration is automatically detected from `.opencode/opencode.json`. |---------|-------------|----------|--------| | Agents | ✅ 13 agents | ✅ 12 agents | **Claude Code leads** | | Commands | ✅ 32 commands | ✅ 24 commands | **Claude Code leads** | -| Skills | ✅ 44 skills | ✅ 16 skills | **Claude Code leads** | +| Skills | ✅ 47 skills | ✅ 16 skills | **Claude Code leads** | | Hooks | ✅ 3 phases | ✅ 20+ events | **OpenCode has more!** | | Rules | ✅ 8 rules | ✅ 8 rules | **Full parity** | | MCP Servers | ✅ Full | ✅ Full | **Full parity** | From 0a770caf84580adfd7aa541e49e5027983366a21 Mon Sep 17 00:00:00 2001 From: Okmin Date: Thu, 19 Feb 2026 12:15:41 +0900 Subject: [PATCH 5/8] fix(skills): address code review feedback on iOS 26 skill examples - Add required name/description properties and @Generable to RecipeSearchTool - Fix missing argument label in session.respond(to:) call - Remove non-existent .scrollExtensionMode API, replace with correct guidance - Change PhotoProcessor from struct to class for cache mutation support - Fix method name mismatch in @concurrent example caller --- skills/foundation-models-on-device/SKILL.md | 8 ++++++-- skills/liquid-glass-design/SKILL.md | 8 ++------ skills/swift-concurrency-6-2/SKILL.md | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/skills/foundation-models-on-device/SKILL.md b/skills/foundation-models-on-device/SKILL.md index 365bd747..074598f0 100644 --- a/skills/foundation-models-on-device/SKILL.md +++ b/skills/foundation-models-on-device/SKILL.md @@ -113,7 +113,11 @@ Let the model invoke custom code for domain-specific tasks: ```swift struct RecipeSearchTool: Tool { - struct Arguments: Codable { + let name = "recipe_search" + let description = "Search for recipes matching a given term and return a list of results." + + @Generable + struct Arguments { var searchTerm: String var numberOfResults: Int } @@ -139,7 +143,7 @@ let response = try await session.respond(to: "Find me some pasta recipes") ```swift do { - let answer = try await session.respond("Find a recipe for tomato soup.") + let answer = try await session.respond(to: "Find a recipe for tomato soup.") } catch let error as LanguageModelSession.ToolCallError { print(error.tool.name) if case .databaseIsEmpty = error.underlyingError as? RecipeSearchToolError { diff --git a/skills/liquid-glass-design/SKILL.md b/skills/liquid-glass-design/SKILL.md index bf068910..03a49b40 100644 --- a/skills/liquid-glass-design/SKILL.md +++ b/skills/liquid-glass-design/SKILL.md @@ -124,13 +124,9 @@ Button("Toggle") { .buttonStyle(.glass) ``` -### Scroll and Sidebar Extensions +### Extending Horizontal Scrolling Under Sidebar -```swift -// Extend horizontal scroll under sidebar -ScrollView(.horizontal) { /* content */ } - .scrollExtensionMode(.underSidebar) -``` +To allow horizontal scroll content to extend under a sidebar or inspector, ensure the `ScrollView` content reaches the leading/trailing edges of the container. The system automatically handles the under-sidebar scrolling behavior when the layout extends to the edges — no additional modifier is needed. ## Core Pattern — UIKit diff --git a/skills/swift-concurrency-6-2/SKILL.md b/skills/swift-concurrency-6-2/SKILL.md index 7def68b2..7e79839b 100644 --- a/skills/swift-concurrency-6-2/SKILL.md +++ b/skills/swift-concurrency-6-2/SKILL.md @@ -137,8 +137,8 @@ This mode is opt-in and recommended for apps, scripts, and other executable targ When you need actual parallelism, explicitly offload with `@concurrent`: ```swift -nonisolated struct PhotoProcessor { - var cachedStickers: [String: Sticker] +nonisolated final class PhotoProcessor { + private var cachedStickers: [String: Sticker] = [:] func extractSticker(data: Data, with id: String) async -> Sticker { if let sticker = cachedStickers[id] { @@ -156,7 +156,8 @@ nonisolated struct PhotoProcessor { } // Callers must await -processedPhotos[item.id] = await PhotoProcessor().process(data: data) +let processor = PhotoProcessor() +processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id) ``` To use `@concurrent`: From c91636185d0c406263ec0d91c363760c5cc4c7c7 Mon Sep 17 00:00:00 2001 From: Okmin Date: Thu, 19 Feb 2026 13:22:40 +0900 Subject: [PATCH 6/8] fix(skills): add Approachable Concurrency build settings note to PhotoProcessor example --- skills/swift-concurrency-6-2/SKILL.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/skills/swift-concurrency-6-2/SKILL.md b/skills/swift-concurrency-6-2/SKILL.md index 7e79839b..9fff71da 100644 --- a/skills/swift-concurrency-6-2/SKILL.md +++ b/skills/swift-concurrency-6-2/SKILL.md @@ -137,6 +137,9 @@ This mode is opt-in and recommended for apps, scripts, and other executable targ When you need actual parallelism, explicitly offload with `@concurrent`: ```swift +// Assumes Approachable Concurrency build settings are enabled: +// SE-0466 (MainActor default isolation) and SE-0461 (NonisolatedNonsendingByDefault). +// Safe mutation of cachedStickers via await depends on these compiler options. nonisolated final class PhotoProcessor { private var cachedStickers: [String: Sticker] = [:] From 1e79991407db011378fe9ab73551ccc88cbabf82 Mon Sep 17 00:00:00 2001 From: Okmin Date: Tue, 24 Feb 2026 11:49:54 +0900 Subject: [PATCH 7/8] fix(readme): correct skill count to 48 and add missing skill-stocktake to directory listing --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 61e4924f..1ffa4aec 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ For manual install instructions see the README in the `rules/` folder. /plugin list everything-claude-code@everything-claude-code ``` -✨ **That's it!** You now have access to 13 agents, 47 skills, and 32 commands. +✨ **That's it!** You now have access to 13 agents, 48 skills, and 32 commands. --- @@ -252,6 +252,7 @@ everything-claude-code/ | |-- swift-actor-persistence/ # Thread-safe Swift data persistence with actors (NEW) | |-- swift-protocol-di-testing/ # Protocol-based DI for testable Swift code (NEW) | |-- search-first/ # Research-before-coding workflow (NEW) +| |-- skill-stocktake/ # Audit skills and commands for quality (NEW) | |-- liquid-glass-design/ # iOS 26 Liquid Glass design system (NEW) | |-- foundation-models-on-device/ # Apple on-device LLM with FoundationModels (NEW) | |-- swift-concurrency-6-2/ # Swift 6.2 Approachable Concurrency (NEW) @@ -814,7 +815,7 @@ The configuration is automatically detected from `.opencode/opencode.json`. |---------|-------------|----------|--------| | Agents | ✅ 13 agents | ✅ 12 agents | **Claude Code leads** | | Commands | ✅ 32 commands | ✅ 24 commands | **Claude Code leads** | -| Skills | ✅ 47 skills | ✅ 16 skills | **Claude Code leads** | +| Skills | ✅ 48 skills | ✅ 16 skills | **Claude Code leads** | | Hooks | ✅ 3 phases | ✅ 20+ events | **OpenCode has more!** | | Rules | ✅ 8 rules | ✅ 8 rules | **Full parity** | | MCP Servers | ✅ Full | ✅ Full | **Full parity** | From 300b6715f960f26302df250fc53058292211d1a8 Mon Sep 17 00:00:00 2001 From: Okmin Date: Tue, 24 Feb 2026 14:39:25 +0900 Subject: [PATCH 8/8] fix(skills): improve code examples in iOS 26 skills - Add do-catch error handling to SwiftUI streaming example in foundation-models-on-device - Add Auto Layout constraints to UIKit glass effect example in liquid-glass-design - Promote build settings prerequisite from code comment to visible blockquote warning in swift-concurrency-6-2 --- skills/foundation-models-on-device/SKILL.md | 14 +++++++++++--- skills/liquid-glass-design/SKILL.md | 14 ++++++++++++++ skills/swift-concurrency-6-2/SKILL.md | 5 ++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/skills/foundation-models-on-device/SKILL.md b/skills/foundation-models-on-device/SKILL.md index 074598f0..2304ca0e 100644 --- a/skills/foundation-models-on-device/SKILL.md +++ b/skills/foundation-models-on-device/SKILL.md @@ -178,6 +178,7 @@ for try await partial in stream { ```swift @State private var partialResult: TripIdeas.PartiallyGenerated? +@State private var errorMessage: String? var body: some View { List { @@ -185,10 +186,17 @@ var body: some View { Text(idea) } } + .overlay { + if let errorMessage { Text(errorMessage).foregroundStyle(.red) } + } .task { - let stream = session.streamResponse(to: prompt, generating: TripIdeas.self) - for try await partial in stream { - partialResult = partial + do { + let stream = session.streamResponse(to: prompt, generating: TripIdeas.self) + for try await partial in stream { + partialResult = partial + } + } catch { + errorMessage = error.localizedDescription } } } diff --git a/skills/liquid-glass-design/SKILL.md b/skills/liquid-glass-design/SKILL.md index 03a49b40..60551c2a 100644 --- a/skills/liquid-glass-design/SKILL.md +++ b/skills/liquid-glass-design/SKILL.md @@ -138,13 +138,27 @@ glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3) glassEffect.isInteractive = true let visualEffectView = UIVisualEffectView(effect: glassEffect) +visualEffectView.translatesAutoresizingMaskIntoConstraints = false visualEffectView.layer.cornerRadius = 20 visualEffectView.clipsToBounds = true +view.addSubview(visualEffectView) +NSLayoutConstraint.activate([ + visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor), + visualEffectView.widthAnchor.constraint(equalToConstant: 200), + visualEffectView.heightAnchor.constraint(equalToConstant: 120) +]) + // Add content to contentView let label = UILabel() label.text = "Liquid Glass" +label.translatesAutoresizingMaskIntoConstraints = false visualEffectView.contentView.addSubview(label) +NSLayoutConstraint.activate([ + label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor), + label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor) +]) ``` ### UIGlassContainerEffect for Multiple Elements diff --git a/skills/swift-concurrency-6-2/SKILL.md b/skills/swift-concurrency-6-2/SKILL.md index 9fff71da..d9864cc4 100644 --- a/skills/swift-concurrency-6-2/SKILL.md +++ b/skills/swift-concurrency-6-2/SKILL.md @@ -136,10 +136,9 @@ This mode is opt-in and recommended for apps, scripts, and other executable targ When you need actual parallelism, explicitly offload with `@concurrent`: +> **Important:** This example requires Approachable Concurrency build settings — SE-0466 (MainActor default isolation) and SE-0461 (NonisolatedNonsendingByDefault). With these enabled, `extractSticker` stays on the caller's actor, making mutable state access safe. **Without these settings, this code has a data race** — the compiler will flag it. + ```swift -// Assumes Approachable Concurrency build settings are enabled: -// SE-0466 (MainActor default isolation) and SE-0461 (NonisolatedNonsendingByDefault). -// Safe mutation of cachedStickers via await depends on these compiler options. nonisolated final class PhotoProcessor { private var cachedStickers: [String: Sticker] = [:]