opencode-skills-antigravity 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/bundled-skills/app-store-changelog/SKILL.md +75 -0
  2. package/bundled-skills/app-store-changelog/agents/openai.yaml +4 -0
  3. package/bundled-skills/app-store-changelog/references/release-notes-guidelines.md +34 -0
  4. package/bundled-skills/app-store-changelog/scripts/collect_release_changes.sh +33 -0
  5. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  6. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  7. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  8. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  9. package/bundled-skills/docs/sources/sources.md +10 -0
  10. package/bundled-skills/docs/users/bundles.md +9 -1
  11. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  12. package/bundled-skills/docs/users/faq.md +36 -0
  13. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  14. package/bundled-skills/docs/users/getting-started.md +1 -1
  15. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  16. package/bundled-skills/docs/users/usage.md +14 -4
  17. package/bundled-skills/docs/users/visual-guide.md +4 -4
  18. package/bundled-skills/github/SKILL.md +76 -0
  19. package/bundled-skills/github/agents/openai.yaml +4 -0
  20. package/bundled-skills/ios-debugger-agent/SKILL.md +59 -0
  21. package/bundled-skills/ios-debugger-agent/agents/openai.yaml +4 -0
  22. package/bundled-skills/macos-menubar-tuist-app/SKILL.md +109 -0
  23. package/bundled-skills/macos-menubar-tuist-app/agents/openai.yaml +4 -0
  24. package/bundled-skills/macos-spm-app-packaging/SKILL.md +105 -0
  25. package/bundled-skills/macos-spm-app-packaging/agents/openai.yaml +4 -0
  26. package/bundled-skills/macos-spm-app-packaging/assets/templates/bootstrap/Package.swift +17 -0
  27. package/bundled-skills/macos-spm-app-packaging/assets/templates/bootstrap/Sources/MyApp/Resources/.keep +0 -0
  28. package/bundled-skills/macos-spm-app-packaging/assets/templates/bootstrap/Sources/MyApp/main.swift +11 -0
  29. package/bundled-skills/macos-spm-app-packaging/assets/templates/bootstrap/version.env +2 -0
  30. package/bundled-skills/macos-spm-app-packaging/assets/templates/build_icon.sh +49 -0
  31. package/bundled-skills/macos-spm-app-packaging/assets/templates/compile_and_run.sh +63 -0
  32. package/bundled-skills/macos-spm-app-packaging/assets/templates/launch.sh +28 -0
  33. package/bundled-skills/macos-spm-app-packaging/assets/templates/make_appcast.sh +82 -0
  34. package/bundled-skills/macos-spm-app-packaging/assets/templates/package_app.sh +206 -0
  35. package/bundled-skills/macos-spm-app-packaging/assets/templates/setup_dev_signing.sh +52 -0
  36. package/bundled-skills/macos-spm-app-packaging/assets/templates/sign-and-notarize.sh +52 -0
  37. package/bundled-skills/macos-spm-app-packaging/assets/templates/version.env +2 -0
  38. package/bundled-skills/macos-spm-app-packaging/references/packaging.md +17 -0
  39. package/bundled-skills/macos-spm-app-packaging/references/release.md +32 -0
  40. package/bundled-skills/macos-spm-app-packaging/references/scaffold.md +79 -0
  41. package/bundled-skills/orchestrate-batch-refactor/SKILL.md +97 -0
  42. package/bundled-skills/orchestrate-batch-refactor/agents/openai.yaml +4 -0
  43. package/bundled-skills/orchestrate-batch-refactor/references/agent-prompt-templates.md +53 -0
  44. package/bundled-skills/orchestrate-batch-refactor/references/work-packet-template.md +31 -0
  45. package/bundled-skills/project-skill-audit/SKILL.md +190 -0
  46. package/bundled-skills/project-skill-audit/agents/openai.yaml +4 -0
  47. package/bundled-skills/react-component-performance/SKILL.md +135 -0
  48. package/bundled-skills/react-component-performance/agents/openai.yaml +4 -0
  49. package/bundled-skills/react-component-performance/references/examples.md +88 -0
  50. package/bundled-skills/simplify-code/SKILL.md +179 -0
  51. package/bundled-skills/snowflake-development/SKILL.md +233 -0
  52. package/bundled-skills/swift-concurrency-expert/SKILL.md +113 -0
  53. package/bundled-skills/swift-concurrency-expert/agents/openai.yaml +4 -0
  54. package/bundled-skills/swift-concurrency-expert/references/approachable-concurrency.md +63 -0
  55. package/bundled-skills/swift-concurrency-expert/references/swift-6-2-concurrency.md +272 -0
  56. package/bundled-skills/swift-concurrency-expert/references/swiftui-concurrency-tour-wwdc.md +33 -0
  57. package/bundled-skills/swiftui-liquid-glass/SKILL.md +98 -0
  58. package/bundled-skills/swiftui-liquid-glass/agents/openai.yaml +4 -0
  59. package/bundled-skills/swiftui-liquid-glass/references/liquid-glass.md +280 -0
  60. package/bundled-skills/swiftui-performance-audit/SKILL.md +114 -0
  61. package/bundled-skills/swiftui-performance-audit/agents/openai.yaml +4 -0
  62. package/bundled-skills/swiftui-performance-audit/references/code-smells.md +150 -0
  63. package/bundled-skills/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
  64. package/bundled-skills/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
  65. package/bundled-skills/swiftui-performance-audit/references/profiling-intake.md +44 -0
  66. package/bundled-skills/swiftui-performance-audit/references/report-template.md +47 -0
  67. package/bundled-skills/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
  68. package/bundled-skills/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
  69. package/bundled-skills/swiftui-ui-patterns/SKILL.md +103 -0
  70. package/bundled-skills/swiftui-ui-patterns/agents/openai.yaml +4 -0
  71. package/bundled-skills/swiftui-ui-patterns/references/app-wiring.md +201 -0
  72. package/bundled-skills/swiftui-ui-patterns/references/async-state.md +96 -0
  73. package/bundled-skills/swiftui-ui-patterns/references/components-index.md +50 -0
  74. package/bundled-skills/swiftui-ui-patterns/references/controls.md +57 -0
  75. package/bundled-skills/swiftui-ui-patterns/references/deeplinks.md +66 -0
  76. package/bundled-skills/swiftui-ui-patterns/references/focus.md +90 -0
  77. package/bundled-skills/swiftui-ui-patterns/references/form.md +97 -0
  78. package/bundled-skills/swiftui-ui-patterns/references/grids.md +71 -0
  79. package/bundled-skills/swiftui-ui-patterns/references/haptics.md +71 -0
  80. package/bundled-skills/swiftui-ui-patterns/references/input-toolbar.md +51 -0
  81. package/bundled-skills/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
  82. package/bundled-skills/swiftui-ui-patterns/references/list.md +86 -0
  83. package/bundled-skills/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
  84. package/bundled-skills/swiftui-ui-patterns/references/macos-settings.md +71 -0
  85. package/bundled-skills/swiftui-ui-patterns/references/matched-transitions.md +59 -0
  86. package/bundled-skills/swiftui-ui-patterns/references/media.md +73 -0
  87. package/bundled-skills/swiftui-ui-patterns/references/menu-bar.md +101 -0
  88. package/bundled-skills/swiftui-ui-patterns/references/navigationstack.md +159 -0
  89. package/bundled-skills/swiftui-ui-patterns/references/overlay.md +45 -0
  90. package/bundled-skills/swiftui-ui-patterns/references/performance.md +62 -0
  91. package/bundled-skills/swiftui-ui-patterns/references/previews.md +48 -0
  92. package/bundled-skills/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
  93. package/bundled-skills/swiftui-ui-patterns/references/scrollview.md +87 -0
  94. package/bundled-skills/swiftui-ui-patterns/references/searchable.md +71 -0
  95. package/bundled-skills/swiftui-ui-patterns/references/sheets.md +155 -0
  96. package/bundled-skills/swiftui-ui-patterns/references/split-views.md +72 -0
  97. package/bundled-skills/swiftui-ui-patterns/references/tabview.md +114 -0
  98. package/bundled-skills/swiftui-ui-patterns/references/theming.md +71 -0
  99. package/bundled-skills/swiftui-ui-patterns/references/title-menus.md +93 -0
  100. package/bundled-skills/swiftui-ui-patterns/references/top-bar.md +49 -0
  101. package/bundled-skills/swiftui-view-refactor/SKILL.md +210 -0
  102. package/bundled-skills/swiftui-view-refactor/agents/openai.yaml +4 -0
  103. package/bundled-skills/swiftui-view-refactor/references/mv-patterns.md +161 -0
  104. package/bundled-skills/wordpress/SKILL.md +281 -4
  105. package/bundled-skills/wordpress-penetration-testing/SKILL.md +106 -1
  106. package/bundled-skills/wordpress-plugin-development/SKILL.md +296 -3
  107. package/bundled-skills/wordpress-theme-development/SKILL.md +316 -3
  108. package/bundled-skills/wordpress-woocommerce-development/SKILL.md +442 -2
  109. package/package.json +1 -1
@@ -0,0 +1,233 @@
1
+ ---
2
+ name: snowflake-development
3
+ description: "Comprehensive Snowflake development assistant covering SQL best practices, data pipeline design (Dynamic Tables, Streams, Tasks, Snowpipe), Cortex AI functions, Cortex Agents, Snowpark Python, dbt integration, performance tuning, and security hardening."
4
+ category: data-engineering
5
+ risk: safe
6
+ source: community
7
+ date_added: "2026-03-24"
8
+ ---
9
+
10
+ # Snowflake Development
11
+
12
+ You are a Snowflake development expert. Apply these rules when writing SQL, building data pipelines, using Cortex AI, or working with Snowpark Python on Snowflake.
13
+
14
+ ## When to Use
15
+
16
+ - When the user asks for help with Snowflake SQL, data pipelines, Cortex AI, or Snowpark Python.
17
+ - When you need Snowflake-specific guidance for dbt, performance tuning, or security hardening.
18
+
19
+ ## SQL Best Practices
20
+
21
+ ### Naming and Style
22
+
23
+ - Use `snake_case` for all identifiers. Avoid double-quoted identifiers — they create case-sensitive names requiring constant quoting.
24
+ - Use CTEs (`WITH` clauses) over nested subqueries.
25
+ - Use `CREATE OR REPLACE` for idempotent DDL.
26
+ - Use explicit column lists — never `SELECT *` in production (Snowflake's columnar storage scans only referenced columns).
27
+
28
+ ### Stored Procedures — Colon Prefix Rule
29
+
30
+ In SQL stored procedures (BEGIN...END blocks), variables and parameters **must** use the colon `:` prefix inside SQL statements. Without it, Snowflake raises "invalid identifier" errors.
31
+
32
+ BAD:
33
+ ```sql
34
+ CREATE PROCEDURE my_proc(p_id INT) RETURNS STRING LANGUAGE SQL AS
35
+ BEGIN
36
+ LET result STRING;
37
+ SELECT name INTO result FROM users WHERE id = p_id;
38
+ RETURN result;
39
+ END;
40
+ ```
41
+
42
+ GOOD:
43
+ ```sql
44
+ CREATE PROCEDURE my_proc(p_id INT) RETURNS STRING LANGUAGE SQL AS
45
+ BEGIN
46
+ LET result STRING;
47
+ SELECT name INTO :result FROM users WHERE id = :p_id;
48
+ RETURN result;
49
+ END;
50
+ ```
51
+
52
+ ### Semi-Structured Data
53
+
54
+ - VARIANT, OBJECT, ARRAY for JSON/Avro/Parquet/ORC.
55
+ - Access nested fields: `src:customer.name::STRING`. Always cast: `src:price::NUMBER(10,2)`.
56
+ - VARIANT null vs SQL NULL: JSON `null` is stored as `"null"`. Use `STRIP_NULL_VALUE = TRUE` on load.
57
+ - Flatten arrays: `SELECT f.value:name::STRING FROM my_table, LATERAL FLATTEN(input => src:items) f;`
58
+
59
+ ### MERGE for Upserts
60
+
61
+ ```sql
62
+ MERGE INTO target t USING source s ON t.id = s.id
63
+ WHEN MATCHED THEN UPDATE SET t.name = s.name, t.updated_at = CURRENT_TIMESTAMP()
64
+ WHEN NOT MATCHED THEN INSERT (id, name, updated_at) VALUES (s.id, s.name, CURRENT_TIMESTAMP());
65
+ ```
66
+
67
+ ## Data Pipelines
68
+
69
+ ### Choosing Your Approach
70
+
71
+ | Approach | When to Use |
72
+ |----------|-------------|
73
+ | Dynamic Tables | Declarative transformations. **Default choice.** Define the query, Snowflake handles refresh. |
74
+ | Streams + Tasks | Imperative CDC. Use for procedural logic, stored procedure calls. |
75
+ | Snowpipe | Continuous file loading from S3/GCS/Azure. |
76
+
77
+ ### Dynamic Tables
78
+
79
+ ```sql
80
+ CREATE OR REPLACE DYNAMIC TABLE cleaned_events
81
+ TARGET_LAG = '5 minutes'
82
+ WAREHOUSE = transform_wh
83
+ AS
84
+ SELECT event_id, event_type, user_id, event_timestamp
85
+ FROM raw_events
86
+ WHERE event_type IS NOT NULL;
87
+ ```
88
+
89
+ Key rules:
90
+ - Set `TARGET_LAG` progressively: tighter at top, looser at bottom.
91
+ - Incremental DTs **cannot** depend on Full refresh DTs.
92
+ - `SELECT *` breaks on schema changes — use explicit column lists.
93
+ - Change tracking must stay enabled on base tables.
94
+ - Views cannot sit between two Dynamic Tables.
95
+
96
+ ### Streams and Tasks
97
+
98
+ ```sql
99
+ CREATE OR REPLACE STREAM raw_stream ON TABLE raw_events;
100
+
101
+ CREATE OR REPLACE TASK process_events
102
+ WAREHOUSE = transform_wh
103
+ SCHEDULE = 'USING CRON 0 */1 * * * America/Los_Angeles'
104
+ WHEN SYSTEM$STREAM_HAS_DATA('raw_stream')
105
+ AS INSERT INTO cleaned_events SELECT ... FROM raw_stream;
106
+
107
+ -- Tasks start SUSPENDED — you MUST resume them
108
+ ALTER TASK process_events RESUME;
109
+ ```
110
+
111
+ ## Cortex AI
112
+
113
+ ### Function Reference
114
+
115
+ | Function | Purpose |
116
+ |----------|---------|
117
+ | `AI_COMPLETE` | LLM completion (text, images, documents) |
118
+ | `AI_CLASSIFY` | Classify into categories (up to 500 labels) |
119
+ | `AI_FILTER` | Boolean filter on text/images |
120
+ | `AI_EXTRACT` | Structured extraction from text/images/documents |
121
+ | `AI_SENTIMENT` | Sentiment score (-1 to 1) |
122
+ | `AI_PARSE_DOCUMENT` | OCR or layout extraction |
123
+ | `AI_REDACT` | PII removal |
124
+
125
+ **Deprecated (do NOT use):** `COMPLETE`, `CLASSIFY_TEXT`, `EXTRACT_ANSWER`, `PARSE_DOCUMENT`, `SUMMARIZE`, `TRANSLATE`, `SENTIMENT`, `EMBED_TEXT_768`.
126
+
127
+ ### TO_FILE — Common Error Source
128
+
129
+ Stage path and filename are **SEPARATE** arguments:
130
+
131
+ ```sql
132
+ -- BAD: TO_FILE('@stage/file.pdf')
133
+ -- GOOD:
134
+ TO_FILE('@db.schema.mystage', 'invoice.pdf')
135
+ ```
136
+
137
+ ### Use AI_CLASSIFY for Classification (Not AI_COMPLETE)
138
+
139
+ ```sql
140
+ SELECT AI_CLASSIFY(ticket_text,
141
+ ['billing', 'technical', 'account']):labels[0]::VARCHAR AS category
142
+ FROM tickets;
143
+ ```
144
+
145
+ ### Cortex Agents
146
+
147
+ ```sql
148
+ CREATE OR REPLACE AGENT my_db.my_schema.sales_agent
149
+ FROM SPECIFICATION $spec$
150
+ {
151
+ "models": {"orchestration": "auto"},
152
+ "instructions": {
153
+ "orchestration": "You are SalesBot...",
154
+ "response": "Be concise."
155
+ },
156
+ "tools": [{"tool_spec": {"type": "cortex_analyst_text_to_sql", "name": "Sales", "description": "Queries sales..."}}],
157
+ "tool_resources": {"Sales": {"semantic_model_file": "@stage/model.yaml"}}
158
+ }
159
+ $spec$;
160
+ ```
161
+
162
+ Agent rules:
163
+ - Use `$spec$` delimiter (not `$$`).
164
+ - `models` must be an object, not an array.
165
+ - `tool_resources` is a separate top-level object, not nested inside tools.
166
+ - Do NOT include empty/null values in edit specs — clears existing values.
167
+ - Tool descriptions are the #1 quality factor.
168
+ - Never modify production agents directly — clone first.
169
+
170
+ ## Snowpark Python
171
+
172
+ ```python
173
+ from snowflake.snowpark import Session
174
+ import os
175
+
176
+ session = Session.builder.configs({
177
+ "account": os.environ["SNOWFLAKE_ACCOUNT"],
178
+ "user": os.environ["SNOWFLAKE_USER"],
179
+ "password": os.environ["SNOWFLAKE_PASSWORD"],
180
+ "role": "my_role", "warehouse": "my_wh",
181
+ "database": "my_db", "schema": "my_schema"
182
+ }).create()
183
+ ```
184
+
185
+ - Never hardcode credentials.
186
+ - DataFrames are lazy — executed on `collect()`/`show()`.
187
+ - Do NOT use `collect()` on large DataFrames — process server-side.
188
+ - Use **vectorized UDFs** (10-100x faster) for batch/ML workloads instead of scalar UDFs.
189
+
190
+ ## dbt on Snowflake
191
+
192
+ Dynamic table materialization (streaming/near-real-time marts):
193
+ ```sql
194
+ {{ config(materialized='dynamic_table', snowflake_warehouse='transforming', target_lag='1 hour') }}
195
+ ```
196
+
197
+ Incremental materialization (large fact tables):
198
+ ```sql
199
+ {{ config(materialized='incremental', unique_key='event_id') }}
200
+ ```
201
+
202
+ Snowflake-specific configs (combine with any materialization):
203
+ ```sql
204
+ {{ config(transient=true, copy_grants=true, query_tag='team_daily') }}
205
+ ```
206
+
207
+ - Do NOT use `{{ this }}` without `{% if is_incremental() %}` guard.
208
+ - Use `dynamic_table` materialization for streaming/near-real-time marts.
209
+
210
+ ## Performance
211
+
212
+ - **Cluster keys**: Only multi-TB tables, on WHERE/JOIN/GROUP BY columns.
213
+ - **Search Optimization**: `ALTER TABLE t ADD SEARCH OPTIMIZATION ON EQUALITY(col);`
214
+ - **Warehouse sizing**: Start X-Small, scale up. `AUTO_SUSPEND = 60`, `AUTO_RESUME = TRUE`.
215
+ - **Separate warehouses** per workload.
216
+ - Estimate AI costs first: `SELECT SUM(AI_COUNT_TOKENS('claude-4-sonnet', text)) FROM table;`
217
+
218
+ ## Security
219
+
220
+ - Follow least-privilege RBAC. Use database roles for object-level grants.
221
+ - Audit ACCOUNTADMIN regularly: `SHOW GRANTS OF ROLE ACCOUNTADMIN;`
222
+ - Use network policies for IP allowlisting.
223
+ - Use masking policies for PII columns and row access policies for multi-tenant isolation.
224
+
225
+ ## Common Error Patterns
226
+
227
+ | Error | Cause | Fix |
228
+ |-------|-------|-----|
229
+ | "Object does not exist" | Wrong context or missing grants | Fully qualify names, check grants |
230
+ | "Invalid identifier" in proc | Missing colon prefix | Use `:variable_name` |
231
+ | "Numeric value not recognized" | VARIANT not cast | `src:field::NUMBER(10,2)` |
232
+ | Task not running | Forgot to resume | `ALTER TASK ... RESUME` |
233
+ | DT refresh failing | Schema change or tracking disabled | Use explicit columns, check change tracking |
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: swift-concurrency-expert
3
+ description: Review and fix Swift concurrency issues such as actor isolation and Sendable violations.
4
+ risk: safe
5
+ source: "Dimillian/Skills (MIT)"
6
+ date_added: "2026-03-25"
7
+ ---
8
+
9
+ # Swift Concurrency Expert
10
+
11
+ ## Overview
12
+
13
+ Review and fix Swift Concurrency issues in Swift 6.2+ codebases by applying actor isolation, Sendable safety, and modern concurrency patterns with minimal behavior changes.
14
+
15
+ ## When to Use
16
+
17
+ - When the user asks to review Swift concurrency usage or fix compiler diagnostics.
18
+ - When you need guidance on actor isolation, `Sendable`, `@MainActor`, or async migration.
19
+
20
+ ## Workflow
21
+
22
+ ### 1. Triage the issue
23
+
24
+ - Capture the exact compiler diagnostics and the offending symbol(s).
25
+ - Check project concurrency settings: Swift language version (6.2+), strict concurrency level, and whether approachable concurrency (default actor isolation / main-actor-by-default) is enabled.
26
+ - Identify the current actor context (`@MainActor`, `actor`, `nonisolated`) and whether a default actor isolation mode is enabled.
27
+ - Confirm whether the code is UI-bound or intended to run off the main actor.
28
+
29
+ ### 2. Apply the smallest safe fix
30
+
31
+ Prefer edits that preserve existing behavior while satisfying data-race safety.
32
+
33
+ Common fixes:
34
+ - **UI-bound types**: annotate the type or relevant members with `@MainActor`.
35
+ - **Protocol conformance on main actor types**: make the conformance isolated (e.g., `extension Foo: @MainActor SomeProtocol`).
36
+ - **Global/static state**: protect with `@MainActor` or move into an actor.
37
+ - **Background work**: move expensive work into a `@concurrent` async function on a `nonisolated` type or use an `actor` to guard mutable state.
38
+ - **Sendable errors**: prefer immutable/value types; add `Sendable` conformance only when correct; avoid `@unchecked Sendable` unless you can prove thread safety.
39
+
40
+ ### 3. Verify the fix
41
+
42
+ - Rebuild and confirm all concurrency diagnostics are resolved with no new warnings introduced.
43
+ - Run the test suite to check for regressions — concurrency changes can introduce subtle runtime issues even when the build is clean.
44
+ - If the fix surfaces new warnings, treat each one as a fresh triage (return to step 1) and resolve iteratively until the build is clean and tests pass.
45
+
46
+ ### Examples
47
+
48
+ **UI-bound type — adding `@MainActor`**
49
+
50
+ ```swift
51
+ // Before: data-race warning because ViewModel is accessed from the main thread
52
+ // but has no actor isolation
53
+ class ViewModel: ObservableObject {
54
+ @Published var title: String = ""
55
+ func load() { title = "Loaded" }
56
+ }
57
+
58
+ // After: annotate the whole type so all stored state and methods are
59
+ // automatically isolated to the main actor
60
+ @MainActor
61
+ class ViewModel: ObservableObject {
62
+ @Published var title: String = ""
63
+ func load() { title = "Loaded" }
64
+ }
65
+ ```
66
+
67
+ **Protocol conformance isolation**
68
+
69
+ ```swift
70
+ // Before: compiler error — SomeProtocol method is nonisolated but the
71
+ // conforming type is @MainActor
72
+ @MainActor
73
+ class Foo: SomeProtocol {
74
+ func protocolMethod() { /* accesses main-actor state */ }
75
+ }
76
+
77
+ // After: scope the conformance to @MainActor so the requirement is
78
+ // satisfied inside the correct isolation context
79
+ @MainActor
80
+ extension Foo: SomeProtocol {
81
+ func protocolMethod() { /* safely accesses main-actor state */ }
82
+ }
83
+ ```
84
+
85
+ **Background work with `@concurrent`**
86
+
87
+ ```swift
88
+ // Before: expensive computation blocks the main actor
89
+ @MainActor
90
+ func processData(_ input: [Int]) -> [Int] {
91
+ input.map { heavyTransform($0) } // runs on main thread
92
+ }
93
+
94
+ // After: hop off the main actor for the heavy work, then return the result
95
+ // The caller awaits the result and stays on its own actor
96
+ nonisolated func processData(_ input: [Int]) async -> [Int] {
97
+ await Task.detached(priority: .userInitiated) {
98
+ input.map { heavyTransform($0) }
99
+ }.value
100
+ }
101
+
102
+ // Or, using a @concurrent async function (Swift 6.2+):
103
+ @concurrent
104
+ func processData(_ input: [Int]) async -> [Int] {
105
+ input.map { heavyTransform($0) }
106
+ }
107
+ ```
108
+
109
+ ## Reference material
110
+
111
+ - See `references/swift-6-2-concurrency.md` for Swift 6.2 changes, patterns, and examples.
112
+ - See `references/approachable-concurrency.md` when the project is opted into approachable concurrency mode.
113
+ - See `references/swiftui-concurrency-tour-wwdc.md` for SwiftUI-specific concurrency guidance.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Swift Concurrency Expert"
3
+ short_description: "Review and fix Swift concurrency"
4
+ default_prompt: "Use $swift-concurrency-expert to review this Swift code for concurrency issues and fix the relevant diagnostics."
@@ -0,0 +1,63 @@
1
+ ## Approachable Concurrency (Swift 6.2) - project mode quick guide
2
+
3
+ Use this reference when the project has opted into the Swift 6.2 approachable
4
+ concurrency settings (default actor isolation / main-actor-by-default).
5
+
6
+ ## Detect the mode
7
+
8
+ Check Xcode build settings under "Swift Compiler - Concurrency":
9
+ - Swift language version (must be 6.2+).
10
+ - Default actor isolation / Main Actor by default.
11
+ - Strict concurrency checking level (Complete/Targeted/Minimal).
12
+
13
+ For SwiftPM, inspect Package.swift swiftSettings for the same flags.
14
+
15
+ ## Behavior changes to expect
16
+
17
+ - Async functions stay on the caller's actor by default; they don't hop to a
18
+ global concurrent executor unless the implementation chooses to.
19
+ - Main-actor-by-default reduces data race errors for UI-bound code and global
20
+ state, because mutable state is implicitly protected.
21
+ - Protocol conformances can be isolated (e.g., `extension Foo: @MainActor Bar`).
22
+
23
+ ## How to apply fixes in this mode
24
+
25
+ - Prefer minimal annotations; let main-actor-by-default do the work when the
26
+ code is UI-bound.
27
+ - Use isolated conformances instead of forcing `nonisolated` workarounds.
28
+ - Keep global or shared mutable state on the main actor unless there is a clear
29
+ performance need to offload it.
30
+
31
+ ## When to opt out or offload work
32
+
33
+ - Use `@concurrent` on async functions that must run on the concurrent pool.
34
+ - Make types or members `nonisolated` only when they are truly thread-safe and
35
+ used off the main actor.
36
+ - Continue to respect Sendable boundaries when values cross actors or tasks.
37
+
38
+ ## Common pitfalls
39
+
40
+ - `Task.detached` ignores inherited actor context; avoid it unless you truly
41
+ need to break isolation.
42
+ - Main-actor-by-default can hide performance issues if CPU-heavy work stays on
43
+ the main actor; move that work into `@concurrent` async functions.
44
+
45
+ ## Keywords (from source cheat sheet)
46
+
47
+ | Keyword | What it does |
48
+ | --- | --- |
49
+ | `async` | Function can pause |
50
+ | `await` | Pause here until done |
51
+ | `Task { }` | Start async work, inherits context |
52
+ | `Task.detached { }` | Start async work, no inherited context |
53
+ | `@MainActor` | Runs on main thread |
54
+ | `actor` | Type with isolated mutable state |
55
+ | `nonisolated` | Opts out of actor isolation |
56
+ | `Sendable` | Safe to pass between isolation domains |
57
+ | `@concurrent` | Always run on background (Swift 6.2+) |
58
+ | `async let` | Start parallel work |
59
+ | `TaskGroup` | Dynamic parallel work |
60
+
61
+ ## Source
62
+
63
+ https://fuckingapproachableswiftconcurrency.com/en/
@@ -0,0 +1,272 @@
1
+ ## Concurrent programming updates in Swift 6.2
2
+
3
+ Concurrent programming is hard because sharing memory between multiple tasks is prone to mistakes that lead to unpredictable behavior.
4
+
5
+ ## Data-race safety
6
+
7
+ Data-race safety in Swift 6 prevents these mistakes at compile time, so you can write concurrent code without fear of introducing hard-to-debug runtime bugs. But in many cases, the most natural code to write is prone to data races, leading to compiler errors that you have to address. A class with mutable state, like this `PhotoProcessor` class, is safe as long as you don’t access it concurrently.
8
+
9
+ ```swift
10
+ class PhotoProcessor {
11
+ func extractSticker(data: Data, with id: String?) async -> Sticker? { }
12
+ }
13
+
14
+ @MainActor
15
+ final class StickerModel {
16
+ let photoProcessor = PhotoProcessor()
17
+
18
+ func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
19
+ guard let data = try await item.loadTransferable(type: Data.self) else {
20
+ return nil
21
+ }
22
+
23
+ // Error: Sending 'self.photoProcessor' risks causing data races
24
+ // Sending main actor-isolated 'self.photoProcessor' to nonisolated instance method 'extractSticker(data:with:)'
25
+ // risks causing data races between nonisolated and main actor-isolated uses
26
+ return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
27
+ }
28
+ }
29
+ ```
30
+
31
+ It has an async method to extract a `Sticker` by computing the subject of the given image data. But if you try to call `extractSticker` from UI code on the main actor, you’ll get an error that the call risks causing data races. This is because there are several places in the language that offload work to the background implicitly, even if you never needed code to run in parallel.
32
+
33
+ Swift 6.2 changes this philosophy to stay single threaded by default until you choose to introduce concurrency.
34
+
35
+ ```swift
36
+ class PhotoProcessor {
37
+ func extractSticker(data: Data, with id: String?) async -> Sticker? { }
38
+ }
39
+
40
+ @MainActor
41
+ final class StickerModel {
42
+ let photoProcessor = PhotoProcessor()
43
+
44
+ func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
45
+ guard let data = try await item.loadTransferable(type: Data.self) else {
46
+ return nil
47
+ }
48
+
49
+ // No longer a data race error in Swift 6.2 because of Approachable Concurrency and default actor isolation
50
+ return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
51
+ }
52
+ }
53
+ ```
54
+
55
+ The language changes in Swift 6.2 make the most natural code to write data race free by default. This provides a more approachable path to introducing concurrency in a project.
56
+
57
+ When you choose to introduce concurrency because you want to run code in parallel, data-race safety will protect you.
58
+
59
+ First, we've made it easier to call async functions on types with mutable state. Instead of eagerly offloading async functions that aren't tied to a specific actor, the function will continue to run on the actor it was called from. This eliminates data races because the values passed into the async function are never sent outside the actor. Async functions can still offload work in their implementation, but clients don’t have to worry about their mutable state.
60
+
61
+ Next, we’ve made it easier to implement conformances on main actor types. Here I have a protocol called `Exportable`, and I’m trying to implement a conformance for my main actor `StickerModel` class. The export requirement doesn’t have actor isolation, so the language assumed that it could be called from off the main actor, and prevented `StickerModel` from using main actor state in its implementation.
62
+
63
+ ```swift
64
+ protocol Exportable {
65
+ func export()
66
+ }
67
+
68
+ extension StickerModel: Exportable { // error: Conformance of 'StickerModel' to protocol 'Exportable' crosses into main actor-isolated code and can cause data races
69
+ func export() {
70
+ photoProcessor.exportAsPNG()
71
+ }
72
+ }
73
+ ```
74
+
75
+ Swift 6.2 supports these conformances. A conformance that needs main actor state is called an *isolated* conformance. This is safe because the compiler ensures a main actor conformance is only used on the main actor.
76
+
77
+ ```swift
78
+ // Isolated conformances
79
+
80
+ protocol Exportable {
81
+ func export()
82
+ }
83
+
84
+ extension StickerModel: @MainActor Exportable {
85
+ func export() {
86
+ photoProcessor.exportAsPNG()
87
+ }
88
+ }
89
+ ```
90
+
91
+ I can create an `ImageExporter` type that adds a `StickerModel` to an array of any `Exportable` items as long as it stays on the main actor.
92
+
93
+ ```swift
94
+ // Isolated conformances
95
+
96
+ @MainActor
97
+ struct ImageExporter {
98
+ var items: [any Exportable]
99
+
100
+ mutating func add(_ item: StickerModel) {
101
+ items.append(item)
102
+ }
103
+
104
+ func exportAll() {
105
+ for item in items {
106
+ item.export()
107
+ }
108
+ }
109
+ }
110
+ ```
111
+
112
+ But if I allow `ImageExporter` to be used from anywhere, the compiler prevents adding `StickerModel` to the array because it isn’t safe to call export on `StickerModel` from outside the main actor.
113
+
114
+ ```swift
115
+ // Isolated conformances
116
+
117
+ nonisolated
118
+ struct ImageExporter {
119
+ var items: [any Exportable]
120
+
121
+ mutating func add(_ item: StickerModel) {
122
+ items.append(item) // error: Main actor-isolated conformance of 'StickerModel' to 'Exportable' cannot be used in nonisolated context
123
+ }
124
+
125
+ func exportAll() {
126
+ for item in items {
127
+ item.export()
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ With isolated conformances, you only have to solve data race safety issues when the code indicates that it uses the conformance concurrently.
134
+
135
+ ## Global State
136
+
137
+ Global and static variables are prone to data races because they allow mutable state to be accessed from anywhere.
138
+
139
+ ```swift
140
+ final class StickerLibrary {
141
+ static let shared: StickerLibrary = .init() // error: Static property 'shared' is not concurrency-safe because non-'Sendable' type 'StickerLibrary' may have shared mutable state
142
+ }
143
+ ```
144
+
145
+ The most common way to protect global state is with the main actor.
146
+
147
+ ```swift
148
+ final class StickerLibrary {
149
+ @MainActor
150
+ static let shared: StickerLibrary = .init()
151
+ }
152
+ ```
153
+
154
+ And it’s common to annotate an entire class with the main actor to protect all of its mutable state, especially in a project that doesn’t have a lot of concurrent tasks.
155
+
156
+ ```swift
157
+ @MainActor
158
+ final class StickerLibrary {
159
+ static let shared: StickerLibrary = .init()
160
+ }
161
+ ```
162
+
163
+ You can model a program that's entirely single-threaded by writing `@MainActor` on everything in your project.
164
+
165
+ ```swift
166
+ @MainActor
167
+ final class StickerLibrary {
168
+ static let shared: StickerLibrary = .init()
169
+ }
170
+
171
+ @MainActor
172
+ final class StickerModel {
173
+ let photoProcessor: PhotoProcessor
174
+
175
+ var selection: [PhotosPickerItem]
176
+ }
177
+
178
+ extension StickerModel: @MainActor Exportable {
179
+ func export() {
180
+ photoProcessor.exportAsPNG()
181
+ }
182
+ }
183
+ ```
184
+
185
+ To make it easier to model single-threaded code, we’ve introduced a mode to infer main actor by default.
186
+
187
+ ```swift
188
+ // Mode to infer main actor by default in Swift 6.2
189
+
190
+ final class StickerLibrary {
191
+ static let shared: StickerLibrary = .init()
192
+ }
193
+
194
+ final class StickerModel {
195
+ let photoProcessor: PhotoProcessor
196
+
197
+ var selection: [PhotosPickerItem]
198
+ }
199
+
200
+ extension StickerModel: Exportable {
201
+ func export() {
202
+ photoProcessor.exportAsPNG()
203
+ }
204
+ }
205
+ ```
206
+
207
+ This eliminates data-race safety errors about unsafe global and static variables, calls to other main actor functions like ones from the SDK, and more, because the main actor protects all mutable state by default. It also reduces concurrency annotations in code that’s mostly single-threaded. This mode is great for projects that do most of the work on the main actor, and concurrent code is encapsulated within specific types or files. It’s opt-in and it’s recommended for apps, scripts, and other executable targets.
208
+
209
+ ## Offloading work to the background
210
+
211
+ Offloading work to the background is still important for performance, such as keeping apps responsive when performing CPU-intensive tasks.
212
+
213
+ Let’s look at the implementation of the `extractSticker` method on `PhotoProcessor`.
214
+
215
+ ```swift
216
+ // Explicitly offloading async work
217
+
218
+ class PhotoProcessor {
219
+ var cachedStickers: [String: Sticker]
220
+
221
+ func extractSticker(data: Data, with id: String) async -> Sticker {
222
+ if let sticker = cachedStickers[id] {
223
+ return sticker
224
+ }
225
+
226
+ let sticker = await Self.extractSubject(from: data)
227
+ cachedStickers[id] = sticker
228
+ return sticker
229
+ }
230
+
231
+ // Offload expensive image processing using the @concurrent attribute.
232
+ @concurrent
233
+ static func extractSubject(from data: Data) async -> Sticker { }
234
+ }
235
+ ```
236
+
237
+ It first checks whether it already extracted a sticker for an image, so it can return the cached sticker immediately. If the sticker hasn’t been cached, it extracts the subject from the image data and creates a new sticker. The `extractSubject` method performs expensive image processing that I don’t want to block the main actor or any other actor.
238
+
239
+ I can offload this work using the `@concurrent` attribute. `@concurrent` ensures that a function always runs on the concurrent thread pool, freeing up the actor to run other tasks at the same time.
240
+
241
+ ### An example
242
+
243
+ Say you have a function called `process` that you would like to run on a background thread. To call that function on a background thread you need to:
244
+
245
+ - make sure the structure or class is `nonisolated`
246
+ - add the `@concurrent` attribute to the function you want to run in the background
247
+ - add the keyword `async` to the function if it is not already asynchronous
248
+ - and then add the keyword `await` to any callers
249
+
250
+ Like this:
251
+
252
+ ```swift
253
+ nonisolated struct PhotoProcessor {
254
+
255
+ @concurrent
256
+ func process(data: Data) async -> ProcessedPhoto? { ... }
257
+ }
258
+
259
+ // Callers with the added await
260
+ processedPhotos[item.id] = await PhotoProcessor().process(data: data)
261
+ ```
262
+
263
+
264
+ ## Summary
265
+
266
+ These language changes work together to make concurrency more approachable.
267
+
268
+ You start by writing code that runs on the main actor by default, where there’s no risk of data races. When you start to use async functions, those functions run wherever they’re called from. There’s still no risk of data races because all of your code still runs on the main actor. When you’re ready to embrace concurrency to improve performance, it’s easy to offload specific code to the background to run in parallel.
269
+
270
+ Some of these language changes are opt-in because they require changes in your project to adopt. You can find and enable all of the approachable concurrency language changes under the Swift Compiler - Concurrency section of Xcode build settings. You can also enable these features in a Swift package manifest file using the SwiftSettings API.
271
+
272
+ Swift 6.2 includes migration tooling to help you make the necessary code changes automatically. You can learn more about migration tooling at swift.org/migration.