codexkit 1.0.0
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.
- package/.codex/.env.example +27 -0
- package/.codex/.template-manifest.json +631 -0
- package/.codex/.version +1 -0
- package/.codex/agents/builder.toml +104 -0
- package/.codex/agents/debugger.toml +67 -0
- package/.codex/agents/general.toml +41 -0
- package/.codex/agents/painter.toml +40 -0
- package/.codex/agents/planner.toml +60 -0
- package/.codex/agents/refactorer.toml +76 -0
- package/.codex/agents/reviewer.toml +60 -0
- package/.codex/agents/runner.toml +40 -0
- package/.codex/agents/scout.toml +133 -0
- package/.codex/agents/shipper.toml +69 -0
- package/.codex/agents/vision.toml +69 -0
- package/.codex/config.toml +146 -0
- package/.codex/context/architecture.md +66 -0
- package/.codex/context/conventions.md +98 -0
- package/.codex/context/current-priorities.md +33 -0
- package/.codex/context/decision-log.md +93 -0
- package/.codex/context/gotchas.md +42 -0
- package/.codex/context/index.md +21 -0
- package/.codex/context/session-context.md +11 -0
- package/.codex/context/worklog.md +9 -0
- package/.codex/hooks/README.md +17 -0
- package/.codex/hooks/after_agent.sh +11 -0
- package/.codex/hooks/after_tool_use.sh +10 -0
- package/.codex/hooks/post_commit.sh +10 -0
- package/.codex/hooks/pre_commit.sh +6 -0
- package/.codex/hooks/session_start.sh +18 -0
- package/.codex/hooks/stop.sh +10 -0
- package/.codex/mcp/README.md +143 -0
- package/.codex/mcp/basic-memory.toml.example +10 -0
- package/.codex/mcp/context7.toml.example +13 -0
- package/.codex/mcp/exa.toml.example +12 -0
- package/.codex/mcp/memory-bridge.toml.example +15 -0
- package/.codex/mcp/memory.toml.example +6 -0
- package/.codex/mcp/ref.toml.example +13 -0
- package/.codex/mcp/tilth.toml.example +10 -0
- package/.codex/memory/README.md +29 -0
- package/.codex/memory/_templates/README.md +26 -0
- package/.codex/memory/_templates/design.md +15 -0
- package/.codex/memory/_templates/gotcha.md +9 -0
- package/.codex/memory/_templates/handoff.md +9 -0
- package/.codex/memory/_templates/prd.md +13 -0
- package/.codex/memory/_templates/project.md +9 -0
- package/.codex/memory/_templates/proposal.md +13 -0
- package/.codex/memory/_templates/research.md +9 -0
- package/.codex/memory/_templates/roadmap.md +11 -0
- package/.codex/memory/_templates/session-context.md +7 -0
- package/.codex/memory/_templates/state.md +11 -0
- package/.codex/memory/_templates/tasks.md +9 -0
- package/.codex/memory/_templates/tech-stack.md +9 -0
- package/.codex/memory/_templates/user.md +7 -0
- package/.codex/memory/project/gotchas.md +5 -0
- package/.codex/memory/project/project.md +12 -0
- package/.codex/memory/project/roadmap.md +15 -0
- package/.codex/memory/project/state.md +22 -0
- package/.codex/memory/project/tech-stack.md +19 -0
- package/.codex/memory/project/user.md +10 -0
- package/.codex/memory/research/.gitkeep +1 -0
- package/.codex/memory/session-context.md +18 -0
- package/.codex/plans/README.md +7 -0
- package/.codex/prompts/compound.md +154 -0
- package/.codex/prompts/create.md +238 -0
- package/.codex/prompts/design.md +90 -0
- package/.codex/prompts/handoff.md +184 -0
- package/.codex/prompts/init-context.md +185 -0
- package/.codex/prompts/init-user.md +93 -0
- package/.codex/prompts/init.md +103 -0
- package/.codex/prompts/lfg.md +140 -0
- package/.codex/prompts/plan.md +140 -0
- package/.codex/prompts/pr.md +150 -0
- package/.codex/prompts/research.md +137 -0
- package/.codex/prompts/resume.md +105 -0
- package/.codex/prompts/review-codebase.md +147 -0
- package/.codex/prompts/ship.md +334 -0
- package/.codex/prompts/start.md +141 -0
- package/.codex/prompts/status.md +102 -0
- package/.codex/prompts/ui-inspire.md +151 -0
- package/.codex/prompts/ui-review.md +86 -0
- package/.codex/prompts/verify.md +181 -0
- package/.codex/scripts/append_worklog.sh +20 -0
- package/.codex/scripts/apply_worklog_archive.sh +48 -0
- package/.codex/scripts/audit_memory_hygiene.sh +102 -0
- package/.codex/scripts/build_memory_index.sh +167 -0
- package/.codex/scripts/build_prior_related_work.sh +127 -0
- package/.codex/scripts/build_startup_brief.sh +52 -0
- package/.codex/scripts/close_bead.sh +103 -0
- package/.codex/scripts/detect_changed_files.sh +38 -0
- package/.codex/scripts/ensure_beads.sh +14 -0
- package/.codex/scripts/memory_search.sh +292 -0
- package/.codex/scripts/prepare_worklog_archive.sh +115 -0
- package/.codex/scripts/search_bead_context.sh +214 -0
- package/.codex/scripts/start_bead.sh +129 -0
- package/.codex/scripts/sync_bead_context.sh +288 -0
- package/.codex/scripts/validate_memory_docs.sh +44 -0
- package/.codex/scripts/verify_bead.sh +154 -0
- package/.codex/skills/accessibility-audit/SKILL.md +191 -0
- package/.codex/skills/agent-browser/SKILL.md +413 -0
- package/.codex/skills/agent-teams/SKILL.md +268 -0
- package/.codex/skills/augment-context-engine/SKILL.md +115 -0
- package/.codex/skills/augment-context-engine/mcp.json +6 -0
- package/.codex/skills/beads/SKILL.md +181 -0
- package/.codex/skills/beads/references/BEST_PRACTICES.md +27 -0
- package/.codex/skills/beads/references/BOUNDARIES.md +219 -0
- package/.codex/skills/beads/references/DEPENDENCIES.md +124 -0
- package/.codex/skills/beads/references/EXAMPLES.md +45 -0
- package/.codex/skills/beads/references/FILE_CLAIMING.md +101 -0
- package/.codex/skills/beads/references/GIT_SYNC.md +25 -0
- package/.codex/skills/beads/references/HIERARCHY.md +71 -0
- package/.codex/skills/beads/references/MULTI_AGENT.md +40 -0
- package/.codex/skills/beads/references/RESUMABILITY.md +177 -0
- package/.codex/skills/beads/references/SESSION_PROTOCOL.md +61 -0
- package/.codex/skills/beads/references/TASK_CREATION.md +38 -0
- package/.codex/skills/beads/references/TROUBLESHOOTING.md +38 -0
- package/.codex/skills/beads/references/WORKFLOWS.md +226 -0
- package/.codex/skills/beads-bridge/SKILL.md +321 -0
- package/.codex/skills/brainstorming/SKILL.md +114 -0
- package/.codex/skills/bug-triage/SKILL.md +191 -0
- package/.codex/skills/chrome-devtools/SKILL.md +76 -0
- package/.codex/skills/chrome-devtools/mcp.json +19 -0
- package/.codex/skills/cloudflare/SKILL.md +253 -0
- package/.codex/skills/cloudflare/references/agents-sdk/README.md +35 -0
- package/.codex/skills/cloudflare/references/agents-sdk/api.md +100 -0
- package/.codex/skills/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/.codex/skills/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/.codex/skills/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/.codex/skills/cloudflare/references/ai-gateway/README.md +695 -0
- package/.codex/skills/cloudflare/references/ai-search/README.md +14 -0
- package/.codex/skills/cloudflare/references/ai-search/api.md +38 -0
- package/.codex/skills/cloudflare/references/ai-search/configuration.md +52 -0
- package/.codex/skills/cloudflare/references/ai-search/gotchas.md +41 -0
- package/.codex/skills/cloudflare/references/ai-search/patterns.md +45 -0
- package/.codex/skills/cloudflare/references/analytics-engine/README.md +14 -0
- package/.codex/skills/cloudflare/references/analytics-engine/api.md +27 -0
- package/.codex/skills/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/.codex/skills/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/.codex/skills/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/.codex/skills/cloudflare/references/api/README.md +21 -0
- package/.codex/skills/cloudflare/references/api/api.md +31 -0
- package/.codex/skills/cloudflare/references/api/configuration.md +20 -0
- package/.codex/skills/cloudflare/references/api/gotchas.md +28 -0
- package/.codex/skills/cloudflare/references/api/patterns.md +47 -0
- package/.codex/skills/cloudflare/references/api-shield/README.md +20 -0
- package/.codex/skills/cloudflare/references/api-shield/api.md +78 -0
- package/.codex/skills/cloudflare/references/api-shield/configuration.md +128 -0
- package/.codex/skills/cloudflare/references/api-shield/gotchas.md +51 -0
- package/.codex/skills/cloudflare/references/api-shield/patterns.md +145 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/.codex/skills/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/.codex/skills/cloudflare/references/bindings/README.md +14 -0
- package/.codex/skills/cloudflare/references/bindings/api.md +3 -0
- package/.codex/skills/cloudflare/references/bindings/configuration.md +58 -0
- package/.codex/skills/cloudflare/references/bindings/gotchas.md +35 -0
- package/.codex/skills/cloudflare/references/bindings/patterns.md +37 -0
- package/.codex/skills/cloudflare/references/bot-management/README.md +71 -0
- package/.codex/skills/cloudflare/references/bot-management/api.md +168 -0
- package/.codex/skills/cloudflare/references/bot-management/configuration.md +114 -0
- package/.codex/skills/cloudflare/references/bot-management/gotchas.md +99 -0
- package/.codex/skills/cloudflare/references/bot-management/patterns.md +125 -0
- package/.codex/skills/cloudflare/references/browser-rendering/README.md +16 -0
- package/.codex/skills/cloudflare/references/browser-rendering/api.md +54 -0
- package/.codex/skills/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/.codex/skills/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/.codex/skills/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/.codex/skills/cloudflare/references/c3/README.md +264 -0
- package/.codex/skills/cloudflare/references/cache-reserve/README.md +93 -0
- package/.codex/skills/cloudflare/references/cache-reserve/api.md +176 -0
- package/.codex/skills/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/.codex/skills/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/.codex/skills/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/.codex/skills/cloudflare/references/containers/README.md +16 -0
- package/.codex/skills/cloudflare/references/containers/api.md +43 -0
- package/.codex/skills/cloudflare/references/containers/configuration.md +56 -0
- package/.codex/skills/cloudflare/references/containers/gotchas.md +21 -0
- package/.codex/skills/cloudflare/references/containers/patterns.md +40 -0
- package/.codex/skills/cloudflare/references/cron-triggers/README.md +85 -0
- package/.codex/skills/cloudflare/references/cron-triggers/api.md +198 -0
- package/.codex/skills/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/.codex/skills/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/.codex/skills/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/.codex/skills/cloudflare/references/d1/README.md +92 -0
- package/.codex/skills/cloudflare/references/d1/api.md +141 -0
- package/.codex/skills/cloudflare/references/d1/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/d1/gotchas.md +70 -0
- package/.codex/skills/cloudflare/references/d1/patterns.md +144 -0
- package/.codex/skills/cloudflare/references/ddos/README.md +34 -0
- package/.codex/skills/cloudflare/references/ddos/api.md +136 -0
- package/.codex/skills/cloudflare/references/ddos/configuration.md +67 -0
- package/.codex/skills/cloudflare/references/ddos/gotchas.md +114 -0
- package/.codex/skills/cloudflare/references/ddos/patterns.md +158 -0
- package/.codex/skills/cloudflare/references/do-storage/README.md +62 -0
- package/.codex/skills/cloudflare/references/do-storage/api.md +89 -0
- package/.codex/skills/cloudflare/references/do-storage/configuration.md +116 -0
- package/.codex/skills/cloudflare/references/do-storage/gotchas.md +93 -0
- package/.codex/skills/cloudflare/references/do-storage/patterns.md +112 -0
- package/.codex/skills/cloudflare/references/durable-objects/README.md +125 -0
- package/.codex/skills/cloudflare/references/durable-objects/api.md +152 -0
- package/.codex/skills/cloudflare/references/durable-objects/configuration.md +148 -0
- package/.codex/skills/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/.codex/skills/cloudflare/references/durable-objects/patterns.md +255 -0
- package/.codex/skills/cloudflare/references/email-routing/README.md +18 -0
- package/.codex/skills/cloudflare/references/email-routing/api.md +46 -0
- package/.codex/skills/cloudflare/references/email-routing/configuration.md +63 -0
- package/.codex/skills/cloudflare/references/email-routing/gotchas.md +16 -0
- package/.codex/skills/cloudflare/references/email-routing/patterns.md +46 -0
- package/.codex/skills/cloudflare/references/email-workers/README.md +598 -0
- package/.codex/skills/cloudflare/references/hyperdrive/README.md +62 -0
- package/.codex/skills/cloudflare/references/hyperdrive/api.md +137 -0
- package/.codex/skills/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/.codex/skills/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/.codex/skills/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/.codex/skills/cloudflare/references/images/README.md +14 -0
- package/.codex/skills/cloudflare/references/images/api.md +3 -0
- package/.codex/skills/cloudflare/references/images/configuration.md +45 -0
- package/.codex/skills/cloudflare/references/images/gotchas.md +23 -0
- package/.codex/skills/cloudflare/references/images/patterns.md +31 -0
- package/.codex/skills/cloudflare/references/kv/README.md +60 -0
- package/.codex/skills/cloudflare/references/kv/api.md +114 -0
- package/.codex/skills/cloudflare/references/kv/configuration.md +92 -0
- package/.codex/skills/cloudflare/references/kv/gotchas.md +117 -0
- package/.codex/skills/cloudflare/references/kv/patterns.md +139 -0
- package/.codex/skills/cloudflare/references/miniflare/README.md +64 -0
- package/.codex/skills/cloudflare/references/miniflare/api.md +144 -0
- package/.codex/skills/cloudflare/references/miniflare/configuration.md +203 -0
- package/.codex/skills/cloudflare/references/miniflare/gotchas.md +187 -0
- package/.codex/skills/cloudflare/references/miniflare/patterns.md +211 -0
- package/.codex/skills/cloudflare/references/network-interconnect/README.md +60 -0
- package/.codex/skills/cloudflare/references/network-interconnect/api.md +240 -0
- package/.codex/skills/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/.codex/skills/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/.codex/skills/cloudflare/references/observability/README.md +18 -0
- package/.codex/skills/cloudflare/references/observability/api.md +51 -0
- package/.codex/skills/cloudflare/references/observability/configuration.md +60 -0
- package/.codex/skills/cloudflare/references/observability/gotchas.md +36 -0
- package/.codex/skills/cloudflare/references/observability/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/pages/README.md +76 -0
- package/.codex/skills/cloudflare/references/pages/api.md +200 -0
- package/.codex/skills/cloudflare/references/pages/configuration.md +228 -0
- package/.codex/skills/cloudflare/references/pages/gotchas.md +161 -0
- package/.codex/skills/cloudflare/references/pages/patterns.md +145 -0
- package/.codex/skills/cloudflare/references/pages-functions/README.md +57 -0
- package/.codex/skills/cloudflare/references/pages-functions/api.md +201 -0
- package/.codex/skills/cloudflare/references/pages-functions/configuration.md +159 -0
- package/.codex/skills/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/.codex/skills/cloudflare/references/pages-functions/patterns.md +190 -0
- package/.codex/skills/cloudflare/references/pipelines/README.md +664 -0
- package/.codex/skills/cloudflare/references/pulumi/README.md +107 -0
- package/.codex/skills/cloudflare/references/pulumi/api.md +194 -0
- package/.codex/skills/cloudflare/references/pulumi/configuration.md +216 -0
- package/.codex/skills/cloudflare/references/pulumi/gotchas.md +223 -0
- package/.codex/skills/cloudflare/references/pulumi/patterns.md +139 -0
- package/.codex/skills/cloudflare/references/queues/README.md +69 -0
- package/.codex/skills/cloudflare/references/queues/api.md +138 -0
- package/.codex/skills/cloudflare/references/queues/configuration.md +125 -0
- package/.codex/skills/cloudflare/references/queues/gotchas.md +112 -0
- package/.codex/skills/cloudflare/references/queues/patterns.md +155 -0
- package/.codex/skills/cloudflare/references/r2/README.md +61 -0
- package/.codex/skills/cloudflare/references/r2/api.md +127 -0
- package/.codex/skills/cloudflare/references/r2/configuration.md +76 -0
- package/.codex/skills/cloudflare/references/r2/gotchas.md +94 -0
- package/.codex/skills/cloudflare/references/r2/patterns.md +127 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/.codex/skills/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/.codex/skills/cloudflare/references/r2-sql/README.md +512 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/README.md +21 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/api.md +135 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/.codex/skills/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/.codex/skills/cloudflare/references/realtimekit/README.md +81 -0
- package/.codex/skills/cloudflare/references/realtimekit/api.md +164 -0
- package/.codex/skills/cloudflare/references/realtimekit/configuration.md +147 -0
- package/.codex/skills/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/.codex/skills/cloudflare/references/realtimekit/patterns.md +155 -0
- package/.codex/skills/cloudflare/references/sandbox/README.md +90 -0
- package/.codex/skills/cloudflare/references/sandbox/api.md +178 -0
- package/.codex/skills/cloudflare/references/sandbox/configuration.md +131 -0
- package/.codex/skills/cloudflare/references/sandbox/gotchas.md +156 -0
- package/.codex/skills/cloudflare/references/sandbox/patterns.md +203 -0
- package/.codex/skills/cloudflare/references/secrets-store/README.md +58 -0
- package/.codex/skills/cloudflare/references/secrets-store/api.md +182 -0
- package/.codex/skills/cloudflare/references/secrets-store/configuration.md +140 -0
- package/.codex/skills/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/.codex/skills/cloudflare/references/secrets-store/patterns.md +218 -0
- package/.codex/skills/cloudflare/references/smart-placement/README.md +91 -0
- package/.codex/skills/cloudflare/references/smart-placement/api.md +139 -0
- package/.codex/skills/cloudflare/references/smart-placement/configuration.md +129 -0
- package/.codex/skills/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/.codex/skills/cloudflare/references/smart-placement/patterns.md +135 -0
- package/.codex/skills/cloudflare/references/snippets/README.md +15 -0
- package/.codex/skills/cloudflare/references/snippets/api.md +47 -0
- package/.codex/skills/cloudflare/references/snippets/configuration.md +33 -0
- package/.codex/skills/cloudflare/references/snippets/gotchas.md +21 -0
- package/.codex/skills/cloudflare/references/snippets/patterns.md +34 -0
- package/.codex/skills/cloudflare/references/spectrum/README.md +16 -0
- package/.codex/skills/cloudflare/references/spectrum/api.md +24 -0
- package/.codex/skills/cloudflare/references/spectrum/configuration.md +43 -0
- package/.codex/skills/cloudflare/references/spectrum/gotchas.md +42 -0
- package/.codex/skills/cloudflare/references/spectrum/patterns.md +40 -0
- package/.codex/skills/cloudflare/references/static-assets/README.md +14 -0
- package/.codex/skills/cloudflare/references/static-assets/api.md +3 -0
- package/.codex/skills/cloudflare/references/static-assets/configuration.md +47 -0
- package/.codex/skills/cloudflare/references/static-assets/gotchas.md +44 -0
- package/.codex/skills/cloudflare/references/static-assets/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/stream/README.md +103 -0
- package/.codex/skills/cloudflare/references/stream/api.md +204 -0
- package/.codex/skills/cloudflare/references/stream/configuration.md +127 -0
- package/.codex/skills/cloudflare/references/stream/gotchas.md +131 -0
- package/.codex/skills/cloudflare/references/stream/patterns.md +152 -0
- package/.codex/skills/cloudflare/references/tail-workers/README.md +640 -0
- package/.codex/skills/cloudflare/references/terraform/README.md +76 -0
- package/.codex/skills/cloudflare/references/terraform/api.md +159 -0
- package/.codex/skills/cloudflare/references/terraform/configuration.md +156 -0
- package/.codex/skills/cloudflare/references/terraform/gotchas.md +207 -0
- package/.codex/skills/cloudflare/references/terraform/patterns.md +135 -0
- package/.codex/skills/cloudflare/references/tunnel/README.md +82 -0
- package/.codex/skills/cloudflare/references/tunnel/api.md +105 -0
- package/.codex/skills/cloudflare/references/tunnel/configuration.md +113 -0
- package/.codex/skills/cloudflare/references/tunnel/gotchas.md +115 -0
- package/.codex/skills/cloudflare/references/tunnel/patterns.md +157 -0
- package/.codex/skills/cloudflare/references/turn/README.md +699 -0
- package/.codex/skills/cloudflare/references/turnstile/README.md +14 -0
- package/.codex/skills/cloudflare/references/turnstile/api.md +3 -0
- package/.codex/skills/cloudflare/references/turnstile/configuration.md +19 -0
- package/.codex/skills/cloudflare/references/turnstile/gotchas.md +27 -0
- package/.codex/skills/cloudflare/references/turnstile/patterns.md +41 -0
- package/.codex/skills/cloudflare/references/vectorize/README.md +682 -0
- package/.codex/skills/cloudflare/references/waf/README.md +14 -0
- package/.codex/skills/cloudflare/references/waf/api.md +3 -0
- package/.codex/skills/cloudflare/references/waf/configuration.md +44 -0
- package/.codex/skills/cloudflare/references/waf/gotchas.md +24 -0
- package/.codex/skills/cloudflare/references/waf/patterns.md +29 -0
- package/.codex/skills/cloudflare/references/web-analytics/README.md +19 -0
- package/.codex/skills/cloudflare/references/web-analytics/api.md +52 -0
- package/.codex/skills/cloudflare/references/web-analytics/configuration.md +31 -0
- package/.codex/skills/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/.codex/skills/cloudflare/references/web-analytics/patterns.md +52 -0
- package/.codex/skills/cloudflare/references/workerd/README.md +47 -0
- package/.codex/skills/cloudflare/references/workerd/api.md +199 -0
- package/.codex/skills/cloudflare/references/workerd/configuration.md +185 -0
- package/.codex/skills/cloudflare/references/workerd/gotchas.md +203 -0
- package/.codex/skills/cloudflare/references/workerd/patterns.md +216 -0
- package/.codex/skills/cloudflare/references/workers/README.md +96 -0
- package/.codex/skills/cloudflare/references/workers/api.md +137 -0
- package/.codex/skills/cloudflare/references/workers/configuration.md +147 -0
- package/.codex/skills/cloudflare/references/workers/gotchas.md +99 -0
- package/.codex/skills/cloudflare/references/workers/patterns.md +149 -0
- package/.codex/skills/cloudflare/references/workers-ai/README.md +116 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/.codex/skills/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/.codex/skills/cloudflare/references/workers-playground/README.md +16 -0
- package/.codex/skills/cloudflare/references/workers-playground/api.md +20 -0
- package/.codex/skills/cloudflare/references/workers-playground/configuration.md +3 -0
- package/.codex/skills/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/.codex/skills/cloudflare/references/workers-playground/patterns.md +42 -0
- package/.codex/skills/cloudflare/references/workers-vpc/README.md +579 -0
- package/.codex/skills/cloudflare/references/workflows/README.md +62 -0
- package/.codex/skills/cloudflare/references/workflows/api.md +125 -0
- package/.codex/skills/cloudflare/references/workflows/configuration.md +177 -0
- package/.codex/skills/cloudflare/references/workflows/gotchas.md +136 -0
- package/.codex/skills/cloudflare/references/workflows/patterns.md +132 -0
- package/.codex/skills/cloudflare/references/wrangler/README.md +90 -0
- package/.codex/skills/cloudflare/references/wrangler/api.md +140 -0
- package/.codex/skills/cloudflare/references/wrangler/configuration.md +128 -0
- package/.codex/skills/cloudflare/references/wrangler/gotchas.md +93 -0
- package/.codex/skills/cloudflare/references/wrangler/patterns.md +150 -0
- package/.codex/skills/cloudflare/references/zaraz/README.md +360 -0
- package/.codex/skills/code-navigation/SKILL.md +130 -0
- package/.codex/skills/code-review/SKILL.md +208 -0
- package/.codex/skills/compaction/SKILL.md +317 -0
- package/.codex/skills/condition-based-waiting/SKILL.md +123 -0
- package/.codex/skills/condition-based-waiting/example.ts +158 -0
- package/.codex/skills/context-engineering/SKILL.md +176 -0
- package/.codex/skills/context-initialization/SKILL.md +70 -0
- package/.codex/skills/context-management/SKILL.md +163 -0
- package/.codex/skills/core-data-expert/SKILL.md +93 -0
- package/.codex/skills/core-data-expert/references/batch-operations.md +543 -0
- package/.codex/skills/core-data-expert/references/cloudkit-integration.md +259 -0
- package/.codex/skills/core-data-expert/references/concurrency.md +522 -0
- package/.codex/skills/core-data-expert/references/fetch-requests.md +643 -0
- package/.codex/skills/core-data-expert/references/glossary.md +233 -0
- package/.codex/skills/core-data-expert/references/migration.md +393 -0
- package/.codex/skills/core-data-expert/references/model-configuration.md +597 -0
- package/.codex/skills/core-data-expert/references/performance.md +300 -0
- package/.codex/skills/core-data-expert/references/persistent-history.md +553 -0
- package/.codex/skills/core-data-expert/references/project-audit.md +60 -0
- package/.codex/skills/core-data-expert/references/saving.md +574 -0
- package/.codex/skills/core-data-expert/references/stack-setup.md +625 -0
- package/.codex/skills/core-data-expert/references/testing.md +300 -0
- package/.codex/skills/core-data-expert/references/threading.md +589 -0
- package/.codex/skills/debugging/SKILL.md +203 -0
- package/.codex/skills/deep-research/SKILL.md +384 -0
- package/.codex/skills/defense-in-depth/SKILL.md +166 -0
- package/.codex/skills/dependency-upgrades/SKILL.md +198 -0
- package/.codex/skills/design-system-audit/SKILL.md +153 -0
- package/.codex/skills/development-lifecycle/SKILL.md +356 -0
- package/.codex/skills/dispatching-parallel-agents/SKILL.md +191 -0
- package/.codex/skills/docs-handoff/SKILL.md +175 -0
- package/.codex/skills/executing-plans/SKILL.md +247 -0
- package/.codex/skills/figma/SKILL.md +224 -0
- package/.codex/skills/figma/mcp.json +6 -0
- package/.codex/skills/finishing-a-development-branch/SKILL.md +357 -0
- package/.codex/skills/frontend-design/SKILL.md +176 -0
- package/.codex/skills/gemini-large-context/SKILL.md +216 -0
- package/.codex/skills/git-pr-prep/SKILL.md +179 -0
- package/.codex/skills/index-knowledge/SKILL.md +413 -0
- package/.codex/skills/jira/SKILL.md +283 -0
- package/.codex/skills/jira/mcp.json +6 -0
- package/.codex/skills/memory-system/SKILL.md +93 -0
- package/.codex/skills/mockup-to-code/SKILL.md +184 -0
- package/.codex/skills/mqdh/SKILL.md +171 -0
- package/.codex/skills/obsidian/SKILL.md +187 -0
- package/.codex/skills/obsidian/mcp.json +22 -0
- package/.codex/skills/opensrc/SKILL.md +127 -0
- package/.codex/skills/opensrc/references/architecture.md +176 -0
- package/.codex/skills/opensrc/references/cli-usage.md +176 -0
- package/.codex/skills/opensrc/references/registry-support.md +137 -0
- package/.codex/skills/pdf-extract/SKILL.md +438 -0
- package/.codex/skills/playwright/SKILL.md +320 -0
- package/.codex/skills/playwright/mcp.json +16 -0
- package/.codex/skills/playwriter/SKILL.md +158 -0
- package/.codex/skills/polar/SKILL.md +102 -0
- package/.codex/skills/prd/SKILL.md +146 -0
- package/.codex/skills/prd-task/SKILL.md +182 -0
- package/.codex/skills/prd-task/references/prd-schema.json +124 -0
- package/.codex/skills/prompt-leverage/SKILL.md +69 -0
- package/.codex/skills/prompt-leverage/agents/openai.yaml +4 -0
- package/.codex/skills/prompt-leverage/references/framework.md +91 -0
- package/.codex/skills/prompt-leverage/scripts/augment_prompt.py +114 -0
- package/.codex/skills/ralph/SKILL.md +296 -0
- package/.codex/skills/react-best-practices/AGENTS.md +2410 -0
- package/.codex/skills/react-best-practices/README.md +123 -0
- package/.codex/skills/react-best-practices/SKILL.md +133 -0
- package/.codex/skills/react-best-practices/metadata.json +15 -0
- package/.codex/skills/react-best-practices/rules/_sections.md +46 -0
- package/.codex/skills/react-best-practices/rules/_template.md +28 -0
- package/.codex/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.codex/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/.codex/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/.codex/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/.codex/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/.codex/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/.codex/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.codex/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.codex/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/.codex/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.codex/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.codex/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/.codex/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/.codex/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.codex/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.codex/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.codex/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/.codex/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.codex/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.codex/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/.codex/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.codex/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/.codex/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.codex/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/.codex/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/.codex/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.codex/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.codex/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.codex/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/.codex/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.codex/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.codex/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.codex/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.codex/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.codex/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.codex/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.codex/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.codex/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.codex/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.codex/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.codex/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/.codex/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/.codex/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.codex/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/.codex/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/.codex/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.codex/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/.codex/skills/receiving-code-review/SKILL.md +252 -0
- package/.codex/skills/refactoring/SKILL.md +217 -0
- package/.codex/skills/repo-orientation/SKILL.md +156 -0
- package/.codex/skills/requesting-code-review/SKILL.md +397 -0
- package/.codex/skills/resend/SKILL.md +177 -0
- package/.codex/skills/resend/references/react-email.md +287 -0
- package/.codex/skills/resend/references/receive-email.md +248 -0
- package/.codex/skills/resend/references/send-email.md +318 -0
- package/.codex/skills/root-cause-tracing/SKILL.md +192 -0
- package/.codex/skills/root-cause-tracing/find-polluter.sh +63 -0
- package/.codex/skills/safe-implementation/SKILL.md +205 -0
- package/.codex/skills/session-management/SKILL.md +10 -0
- package/.codex/skills/sharing-skills/SKILL.md +214 -0
- package/.codex/skills/skill-creator/SKILL.md +156 -0
- package/.codex/skills/source-code-research/SKILL.md +293 -0
- package/.codex/skills/source-code-research/references/analysis-tips.md +43 -0
- package/.codex/skills/source-code-research/references/anti-patterns.md +36 -0
- package/.codex/skills/source-code-research/references/common-patterns.md +57 -0
- package/.codex/skills/source-code-research/references/example-workflow.md +60 -0
- package/.codex/skills/source-code-research/references/further-reading.md +5 -0
- package/.codex/skills/source-code-research/references/source-structure.md +45 -0
- package/.codex/skills/stitch/SKILL.md +147 -0
- package/.codex/skills/stitch/mcp.json +9 -0
- package/.codex/skills/structured-edit/SKILL.md +181 -0
- package/.codex/skills/subagent-driven-development/SKILL.md +237 -0
- package/.codex/skills/supabase/SKILL.md +130 -0
- package/.codex/skills/supabase/mcp.json +27 -0
- package/.codex/skills/supabase-postgres-best-practices/AGENTS.md +1490 -0
- package/.codex/skills/supabase-postgres-best-practices/SKILL.md +65 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/advanced-full-text-search.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +49 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-idle-timeout.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-limits.md +44 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-pooling.md +41 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/conn-prepared-statements.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-batch-inserts.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-n-plus-one.md +53 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-pagination.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/data-upsert.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-advisory.md +56 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +68 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-short-transactions.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/lock-skip-locked.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-composite-indexes.md +44 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-covering-indexes.md +40 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-index-types.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-missing-indexes.md +43 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/query-partial-indexes.md +45 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-data-types.md +46 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +59 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-partitioning.md +55 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/schema-primary-keys.md +61 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-privileges.md +54 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-rls-basics.md +50 -0
- package/.codex/skills/supabase-postgres-best-practices/rules/security-rls-performance.md +57 -0
- package/.codex/skills/swarm-coordination/SKILL.md +179 -0
- package/.codex/skills/swarm-coordination/references/architecture.md +39 -0
- package/.codex/skills/swarm-coordination/references/delegation-worker-protocol.md +145 -0
- package/.codex/skills/swarm-coordination/references/dependency-graph.md +50 -0
- package/.codex/skills/swarm-coordination/references/drift-check.md +90 -0
- package/.codex/skills/swarm-coordination/references/integration-beads.md +20 -0
- package/.codex/skills/swarm-coordination/references/launch-flow.md +186 -0
- package/.codex/skills/swarm-coordination/references/reconciler.md +172 -0
- package/.codex/skills/swarm-coordination/references/tier-enforcement.md +78 -0
- package/.codex/skills/swarm-coordination/references/tmux-integration.md +134 -0
- package/.codex/skills/swift-concurrency/SKILL.md +266 -0
- package/.codex/skills/swift-concurrency/references/actors.md +640 -0
- package/.codex/skills/swift-concurrency/references/async-algorithms.md +822 -0
- package/.codex/skills/swift-concurrency/references/async-await-basics.md +249 -0
- package/.codex/skills/swift-concurrency/references/async-sequences.md +670 -0
- package/.codex/skills/swift-concurrency/references/core-data.md +533 -0
- package/.codex/skills/swift-concurrency/references/glossary.md +128 -0
- package/.codex/skills/swift-concurrency/references/linting.md +142 -0
- package/.codex/skills/swift-concurrency/references/memory-management.md +542 -0
- package/.codex/skills/swift-concurrency/references/migration.md +1076 -0
- package/.codex/skills/swift-concurrency/references/performance.md +574 -0
- package/.codex/skills/swift-concurrency/references/sendable.md +578 -0
- package/.codex/skills/swift-concurrency/references/tasks.md +604 -0
- package/.codex/skills/swift-concurrency/references/testing.md +565 -0
- package/.codex/skills/swift-concurrency/references/threading.md +452 -0
- package/.codex/skills/swiftui-expert-skill/SKILL.md +329 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-advanced.md +351 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/.codex/skills/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/.codex/skills/swiftui-expert-skill/references/image-optimization.md +286 -0
- package/.codex/skills/swiftui-expert-skill/references/layout-best-practices.md +312 -0
- package/.codex/skills/swiftui-expert-skill/references/liquid-glass.md +377 -0
- package/.codex/skills/swiftui-expert-skill/references/list-patterns.md +153 -0
- package/.codex/skills/swiftui-expert-skill/references/modern-apis.md +400 -0
- package/.codex/skills/swiftui-expert-skill/references/performance-patterns.md +377 -0
- package/.codex/skills/swiftui-expert-skill/references/scroll-patterns.md +305 -0
- package/.codex/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +292 -0
- package/.codex/skills/swiftui-expert-skill/references/state-management.md +447 -0
- package/.codex/skills/swiftui-expert-skill/references/text-formatting.md +285 -0
- package/.codex/skills/swiftui-expert-skill/references/view-structure.md +276 -0
- package/.codex/skills/systematic-debugging/SKILL.md +402 -0
- package/.codex/skills/task-planning/SKILL.md +205 -0
- package/.codex/skills/test-driven-development/SKILL.md +388 -0
- package/.codex/skills/test-strategy/SKILL.md +186 -0
- package/.codex/skills/testing-anti-patterns/SKILL.md +320 -0
- package/.codex/skills/testing-skills-with-subagents/SKILL.md +405 -0
- package/.codex/skills/tilth-cli/SKILL.md +180 -0
- package/.codex/skills/tool-priority/SKILL.md +299 -0
- package/.codex/skills/ui-inspiration-scout/SKILL.md +203 -0
- package/.codex/skills/ui-ux-research/SKILL.md +35 -0
- package/.codex/skills/using-git-worktrees/SKILL.md +259 -0
- package/.codex/skills/using-skills/SKILL.md +117 -0
- package/.codex/skills/v0/SKILL.md +158 -0
- package/.codex/skills/v0/mcp.json +6 -0
- package/.codex/skills/v1-run/SKILL.md +175 -0
- package/.codex/skills/v1-run/mcp.json +6 -0
- package/.codex/skills/vercel-deploy-claimable/SKILL.md +124 -0
- package/.codex/skills/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/.codex/skills/verification/SKILL.md +191 -0
- package/.codex/skills/verification-before-completion/SKILL.md +236 -0
- package/.codex/skills/visual-analysis/SKILL.md +154 -0
- package/.codex/skills/web-design-guidelines/SKILL.md +46 -0
- package/.codex/skills/writing-plans/SKILL.md +320 -0
- package/.codex/skills/writing-skills/SKILL.md +287 -0
- package/.codex/skills/writing-skills/anthropic-best-practices.md +1173 -0
- package/.codex/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/.codex/skills/writing-skills/persuasion-principles.md +220 -0
- package/.codex/skills/writing-skills/references/anti-patterns.md +25 -0
- package/.codex/skills/writing-skills/references/claude-search-optimization.md +140 -0
- package/.codex/skills/writing-skills/references/discovery-workflow.md +11 -0
- package/.codex/skills/writing-skills/references/file-organization.md +32 -0
- package/.codex/skills/writing-skills/references/flowcharts-and-examples.md +57 -0
- package/.codex/skills/writing-skills/references/rationalization-hardening.md +75 -0
- package/.codex/skills/writing-skills/references/testing-skill-types.md +52 -0
- package/.template-manifest.json +631 -0
- package/AGENTS.md +719 -0
- package/AGENTS.override.md.example +7 -0
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +641 -0
- package/bin/codexkit +148 -0
- package/install/bead-close.sh +20 -0
- package/install/bead-search.sh +18 -0
- package/install/bead-start.sh +20 -0
- package/install/bead-sync.sh +19 -0
- package/install/bead-verify.sh +20 -0
- package/install/generate-manifest.sh +55 -0
- package/install/install-global.sh +150 -0
- package/install/install-project.sh +704 -0
- package/install/install-remote.sh +152 -0
- package/install/patch.sh +478 -0
- package/install/plugin.sh +565 -0
- package/install/run-codex.sh +68 -0
- package/install/template.sh +620 -0
- package/install/validate.sh +653 -0
- package/package.json +39 -0
- package/templates/global/.codex-config-template.toml +87 -0
- package/templates/global/AGENTS.override.md +18 -0
- package/templates/global/README.md +29 -0
- package/templates/project/.codex-config-template.toml +26 -0
- package/templates/project/AGENTS.md.template +27 -0
- package/templates/project/README.md +24 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Linting & Concurrency
|
|
2
|
+
|
|
3
|
+
Guidance for handling lint rules and compiler warnings related to Swift Concurrency.
|
|
4
|
+
|
|
5
|
+
## SwiftLint Concurrency Rules Overview
|
|
6
|
+
|
|
7
|
+
SwiftLint provides several rules targeting async/await and concurrency patterns. Understanding when to fix vs. suppress is critical.
|
|
8
|
+
|
|
9
|
+
| Rule | Default | Purpose |
|
|
10
|
+
|------|---------|---------|
|
|
11
|
+
| `async_without_await` | warning | Flags `async` functions that never await |
|
|
12
|
+
| `unowned_variable_capture` | warning | Warns about `unowned` in closures (risky in async) |
|
|
13
|
+
| `class_delegate_protocol` | warning | Ensures delegates are class-bound (AnyObject) |
|
|
14
|
+
| `weak_delegate` | warning | Delegates should be weak to avoid retain cycles |
|
|
15
|
+
|
|
16
|
+
## SwiftLint: `async_without_await`
|
|
17
|
+
|
|
18
|
+
- **Intent**: A declaration should not be `async` if it never awaits.
|
|
19
|
+
- **Never "fix"** by inserting fake suspension (e.g. `await Task.yield()`, `await Task { ... }.value`). Those mask the real issue and add meaningless suspension points.
|
|
20
|
+
- **Legit use of `Task.yield()`**: OK in tests or scheduling control when you truly need a yield; not as a lint workaround.
|
|
21
|
+
|
|
22
|
+
### Diagnose why the declaration is `async`
|
|
23
|
+
1) **Protocol requirement** — the protocol method/property is `async`.
|
|
24
|
+
2) **Override requirement** — base class API is `async`.
|
|
25
|
+
3) **`@concurrent` requirement** — stays `async` even without `await`.
|
|
26
|
+
4) **Accidental/legacy `async`** — no caller needs async semantics.
|
|
27
|
+
|
|
28
|
+
### Preferred fixes (order)
|
|
29
|
+
1) **Remove `async`** (and adjust call sites) when no async semantics are needed.
|
|
30
|
+
2) If `async` is required (protocol/override/@concurrent):
|
|
31
|
+
- Re-evaluate the upstream API if you own it (can it be non-async?).
|
|
32
|
+
- If you cannot change it, keep `async` and **narrowly suppress the rule** where appropriate (common for mocks/stubs/overrides).
|
|
33
|
+
|
|
34
|
+
### Suppression examples (keep scope tight)
|
|
35
|
+
```swift
|
|
36
|
+
// swiftlint:disable:next async_without_await
|
|
37
|
+
func fetch() async { perform() }
|
|
38
|
+
|
|
39
|
+
// For a block:
|
|
40
|
+
// swiftlint:disable async_without_await
|
|
41
|
+
func makeMock() async { perform() }
|
|
42
|
+
// swiftlint:enable async_without_await
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Quick checklist
|
|
46
|
+
- [ ] Confirm if `async` is truly required (protocol/override/@concurrent).
|
|
47
|
+
- [ ] If not required, remove `async` and update callers.
|
|
48
|
+
- [ ] If required, prefer localized suppression over dummy awaits.
|
|
49
|
+
- [ ] Avoid adding new suspension points without intent.
|
|
50
|
+
|
|
51
|
+
## Compiler Warnings: Sendable & Isolation
|
|
52
|
+
|
|
53
|
+
The Swift compiler generates concurrency-related warnings based on strict concurrency checking level.
|
|
54
|
+
|
|
55
|
+
### Common Warning Patterns
|
|
56
|
+
|
|
57
|
+
**"Capture of non-sendable type"**
|
|
58
|
+
```swift
|
|
59
|
+
// Warning: Capture of 'self' with non-sendable type 'MyClass' in a `@Sendable` closure
|
|
60
|
+
Task {
|
|
61
|
+
self.doWork() // 'self' is non-Sendable
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Fixes (in order of preference):**
|
|
66
|
+
1. Make the type `Sendable` if it's truly thread-safe
|
|
67
|
+
2. Use `@MainActor` isolation if it's UI-related
|
|
68
|
+
3. Capture only Sendable values instead of `self`
|
|
69
|
+
4. Use `@unchecked Sendable` with documented safety invariant (last resort)
|
|
70
|
+
|
|
71
|
+
**"Non-sendable result returned"**
|
|
72
|
+
```swift
|
|
73
|
+
// Warning: Non-sendable type 'MyResult' returned by implicitly async call
|
|
74
|
+
let result = await actor.getData() // Returns non-Sendable type
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Fixes:**
|
|
78
|
+
1. Make the return type Sendable
|
|
79
|
+
2. Return Sendable projections (IDs, copies of data)
|
|
80
|
+
3. Keep processing within the actor's isolation
|
|
81
|
+
|
|
82
|
+
### Actor Isolation Warnings
|
|
83
|
+
|
|
84
|
+
**"Main actor-isolated property accessed from non-isolated context"**
|
|
85
|
+
```swift
|
|
86
|
+
// Warning: Main actor-isolated property 'title' cannot be referenced from a non-isolated context
|
|
87
|
+
func updateTitle() {
|
|
88
|
+
viewModel.title = "New" // viewModel is @MainActor
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Fixes:**
|
|
93
|
+
1. Mark the calling function `@MainActor`
|
|
94
|
+
2. Use `await MainActor.run { }` for one-off access
|
|
95
|
+
3. Reconsider if the property truly needs @MainActor isolation
|
|
96
|
+
|
|
97
|
+
## Suppression Strategies
|
|
98
|
+
|
|
99
|
+
### When to Suppress vs. Fix
|
|
100
|
+
|
|
101
|
+
**Fix when:**
|
|
102
|
+
- The warning identifies a real data race risk
|
|
103
|
+
- The fix is straightforward (add Sendable, adjust isolation)
|
|
104
|
+
- The code is new or actively maintained
|
|
105
|
+
|
|
106
|
+
**Suppress when:**
|
|
107
|
+
- Protocol/inheritance requires the signature
|
|
108
|
+
- Third-party code forces the pattern
|
|
109
|
+
- Migration is in progress (with tracked ticket)
|
|
110
|
+
|
|
111
|
+
### Suppression Annotations
|
|
112
|
+
|
|
113
|
+
```swift
|
|
114
|
+
// Suppress Sendable warnings for legacy imports
|
|
115
|
+
@preconcurrency import LegacyFramework
|
|
116
|
+
|
|
117
|
+
// Suppress for a single declaration
|
|
118
|
+
nonisolated(unsafe) var legacyCallback: (() -> Void)?
|
|
119
|
+
|
|
120
|
+
// Type-level suppression (use sparingly)
|
|
121
|
+
struct LegacyWrapper: @unchecked Sendable {
|
|
122
|
+
// Document why this is safe
|
|
123
|
+
private let lock = NSLock()
|
|
124
|
+
private var value: Int
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Documentation Requirements
|
|
129
|
+
|
|
130
|
+
When using suppression annotations, document:
|
|
131
|
+
1. **Why** the suppression is needed
|
|
132
|
+
2. **What** invariant makes it safe
|
|
133
|
+
3. **When** it can be removed (link to migration ticket)
|
|
134
|
+
|
|
135
|
+
```swift
|
|
136
|
+
/// Thread-safe: Internal lock protects all mutations.
|
|
137
|
+
/// TODO: Remove @unchecked when migrated to actor (JIRA-1234)
|
|
138
|
+
final class ThreadSafeCache: @unchecked Sendable {
|
|
139
|
+
private let lock = NSLock()
|
|
140
|
+
private var storage: [String: Data] = [:]
|
|
141
|
+
}
|
|
142
|
+
```
|
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
# Memory Management
|
|
2
|
+
|
|
3
|
+
Preventing retain cycles and managing object lifetimes in Swift Concurrency.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
### Tasks capture like closures
|
|
8
|
+
|
|
9
|
+
Tasks capture variables and references just like regular closures. Swift doesn't automatically prevent retain cycles in concurrent code.
|
|
10
|
+
|
|
11
|
+
```swift
|
|
12
|
+
Task {
|
|
13
|
+
self.doWork() // ⚠️ Strong capture of self
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Why concurrency hides memory issues
|
|
18
|
+
|
|
19
|
+
- Tasks may live longer than expected
|
|
20
|
+
- Async operations delay execution
|
|
21
|
+
- Harder to track when memory should be released
|
|
22
|
+
- Long-running tasks can hold references indefinitely
|
|
23
|
+
|
|
24
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 8.1: Overview of memory management in Swift Concurrency](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
25
|
+
|
|
26
|
+
## Retain Cycles
|
|
27
|
+
|
|
28
|
+
### What is a retain cycle?
|
|
29
|
+
|
|
30
|
+
Two or more objects hold strong references to each other, preventing deallocation.
|
|
31
|
+
|
|
32
|
+
```swift
|
|
33
|
+
class A {
|
|
34
|
+
var b: B?
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class B {
|
|
38
|
+
var a: A?
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let a = A()
|
|
42
|
+
let b = B()
|
|
43
|
+
a.b = b
|
|
44
|
+
b.a = a // Retain cycle - neither can be deallocated
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Retain cycles with Tasks
|
|
48
|
+
|
|
49
|
+
When task captures `self` strongly and `self` owns the task:
|
|
50
|
+
|
|
51
|
+
```swift
|
|
52
|
+
@MainActor
|
|
53
|
+
final class ImageLoader {
|
|
54
|
+
var task: Task<Void, Never>?
|
|
55
|
+
|
|
56
|
+
func startPolling() {
|
|
57
|
+
task = Task {
|
|
58
|
+
while true {
|
|
59
|
+
self.pollImages() // ⚠️ Strong capture
|
|
60
|
+
try? await Task.sleep(for: .seconds(1))
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var loader: ImageLoader? = .init()
|
|
67
|
+
loader?.startPolling()
|
|
68
|
+
loader = nil // ⚠️ Loader never deallocated - retain cycle!
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Problem**: Task holds `self`, `self` holds task → neither released.
|
|
72
|
+
|
|
73
|
+
## Breaking Retain Cycles
|
|
74
|
+
|
|
75
|
+
### Use weak self
|
|
76
|
+
|
|
77
|
+
```swift
|
|
78
|
+
func startPolling() {
|
|
79
|
+
task = Task { [weak self] in
|
|
80
|
+
while let self = self {
|
|
81
|
+
self.pollImages()
|
|
82
|
+
try? await Task.sleep(for: .seconds(1))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var loader: ImageLoader? = .init()
|
|
88
|
+
loader?.startPolling()
|
|
89
|
+
loader = nil // ✅ Loader deallocated, task stops
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Pattern for long-running tasks
|
|
93
|
+
|
|
94
|
+
```swift
|
|
95
|
+
task = Task { [weak self] in
|
|
96
|
+
while let self = self {
|
|
97
|
+
await self.doWork()
|
|
98
|
+
try? await Task.sleep(for: interval)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 8.2: Preventing retain cycles when using Tasks](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
104
|
+
|
|
105
|
+
Loop exits when `self` becomes `nil`.
|
|
106
|
+
|
|
107
|
+
## One-Way Retention
|
|
108
|
+
|
|
109
|
+
Task retains `self`, but `self` doesn't retain task. Object stays alive until task completes.
|
|
110
|
+
|
|
111
|
+
```swift
|
|
112
|
+
@MainActor
|
|
113
|
+
final class ViewModel {
|
|
114
|
+
func fetchData() {
|
|
115
|
+
Task {
|
|
116
|
+
await performRequest()
|
|
117
|
+
updateUI() // ⚠️ Strong capture
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var viewModel: ViewModel? = .init()
|
|
123
|
+
viewModel?.fetchData()
|
|
124
|
+
viewModel = nil // ViewModel stays alive until task completes
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Execution order**:
|
|
128
|
+
1. Task starts
|
|
129
|
+
2. `viewModel = nil` (but object not deallocated)
|
|
130
|
+
3. Task completes
|
|
131
|
+
4. ViewModel finally deallocated
|
|
132
|
+
|
|
133
|
+
### When one-way retention is acceptable
|
|
134
|
+
|
|
135
|
+
Short-lived tasks that complete quickly:
|
|
136
|
+
|
|
137
|
+
```swift
|
|
138
|
+
func saveData() {
|
|
139
|
+
Task {
|
|
140
|
+
await database.save(self.data) // OK - completes quickly
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### When to use weak self
|
|
146
|
+
|
|
147
|
+
Long-running or indefinite tasks:
|
|
148
|
+
|
|
149
|
+
```swift
|
|
150
|
+
func startMonitoring() {
|
|
151
|
+
Task { [weak self] in
|
|
152
|
+
for await event in eventStream {
|
|
153
|
+
self?.handle(event)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Async Sequences and Retention
|
|
160
|
+
|
|
161
|
+
### Problem: Infinite sequences
|
|
162
|
+
|
|
163
|
+
```swift
|
|
164
|
+
@MainActor
|
|
165
|
+
final class AppLifecycleViewModel {
|
|
166
|
+
private(set) var isActive = false
|
|
167
|
+
private var task: Task<Void, Never>?
|
|
168
|
+
|
|
169
|
+
func startObserving() {
|
|
170
|
+
task = Task {
|
|
171
|
+
for await _ in NotificationCenter.default.notifications(
|
|
172
|
+
named: .didBecomeActive
|
|
173
|
+
) {
|
|
174
|
+
isActive = true // ⚠️ Strong capture, never ends
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
var viewModel: AppLifecycleViewModel? = .init()
|
|
181
|
+
viewModel?.startObserving()
|
|
182
|
+
viewModel = nil // ⚠️ Never deallocated - sequence continues
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Problem**: Async sequence never finishes, task holds `self` indefinitely.
|
|
186
|
+
|
|
187
|
+
### Solution 1: Manual cancellation
|
|
188
|
+
|
|
189
|
+
```swift
|
|
190
|
+
func startObserving() {
|
|
191
|
+
task = Task {
|
|
192
|
+
for await _ in NotificationCenter.default.notifications(
|
|
193
|
+
named: .didBecomeActive
|
|
194
|
+
) {
|
|
195
|
+
isActive = true
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
func stopObserving() {
|
|
201
|
+
task?.cancel()
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Usage
|
|
205
|
+
viewModel?.startObserving()
|
|
206
|
+
viewModel?.stopObserving() // Must call before release
|
|
207
|
+
viewModel = nil
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Solution 2: Weak self with guard
|
|
211
|
+
|
|
212
|
+
```swift
|
|
213
|
+
func startObserving() {
|
|
214
|
+
task = Task { [weak self] in
|
|
215
|
+
for await _ in NotificationCenter.default.notifications(
|
|
216
|
+
named: .didBecomeActive
|
|
217
|
+
) {
|
|
218
|
+
guard let self = self else { return }
|
|
219
|
+
self.isActive = true
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Task exits when `self` deallocates.
|
|
226
|
+
|
|
227
|
+
## Isolated deinit (Swift 6.2+)
|
|
228
|
+
|
|
229
|
+
Clean up actor-isolated state in deinit:
|
|
230
|
+
|
|
231
|
+
```swift
|
|
232
|
+
@MainActor
|
|
233
|
+
final class ViewModel {
|
|
234
|
+
private var task: Task<Void, Never>?
|
|
235
|
+
|
|
236
|
+
isolated deinit {
|
|
237
|
+
task?.cancel()
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Limitation**: Won't break retain cycles (deinit never called if cycle exists).
|
|
243
|
+
|
|
244
|
+
**Use for**: Cleanup when object is being deallocated normally.
|
|
245
|
+
|
|
246
|
+
## Common Patterns
|
|
247
|
+
|
|
248
|
+
### Short-lived task (strong capture OK)
|
|
249
|
+
|
|
250
|
+
```swift
|
|
251
|
+
func saveData() {
|
|
252
|
+
Task {
|
|
253
|
+
await database.save(self.data)
|
|
254
|
+
self.updateUI()
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**When safe**: Task completes quickly, acceptable for object to live until done.
|
|
260
|
+
|
|
261
|
+
### Long-running task (weak self required)
|
|
262
|
+
|
|
263
|
+
```swift
|
|
264
|
+
func startPolling() {
|
|
265
|
+
task = Task { [weak self] in
|
|
266
|
+
while let self = self {
|
|
267
|
+
await self.fetchUpdates()
|
|
268
|
+
try? await Task.sleep(for: .seconds(5))
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Async sequence monitoring (weak self + guard)
|
|
275
|
+
|
|
276
|
+
```swift
|
|
277
|
+
func startMonitoring() {
|
|
278
|
+
task = Task { [weak self] in
|
|
279
|
+
for await event in eventStream {
|
|
280
|
+
guard let self = self else { return }
|
|
281
|
+
self.handle(event)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Cancellable work with cleanup
|
|
288
|
+
|
|
289
|
+
```swift
|
|
290
|
+
func startWork() {
|
|
291
|
+
task = Task { [weak self] in
|
|
292
|
+
defer { self?.cleanup() }
|
|
293
|
+
|
|
294
|
+
while let self = self {
|
|
295
|
+
await self.doWork()
|
|
296
|
+
try? await Task.sleep(for: .seconds(1))
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Detection Strategies
|
|
303
|
+
|
|
304
|
+
### Add deinit logging
|
|
305
|
+
|
|
306
|
+
```swift
|
|
307
|
+
deinit {
|
|
308
|
+
print("✅ \(type(of: self)) deallocated")
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
If deinit never prints → likely retain cycle.
|
|
313
|
+
|
|
314
|
+
### Memory graph debugger
|
|
315
|
+
|
|
316
|
+
1. Run app in Xcode
|
|
317
|
+
2. Debug → Debug Memory Graph
|
|
318
|
+
3. Look for cycles in object graph
|
|
319
|
+
|
|
320
|
+
### Instruments
|
|
321
|
+
|
|
322
|
+
Use Leaks instrument to detect retain cycles at runtime.
|
|
323
|
+
|
|
324
|
+
## Decision Tree
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
Task captures self?
|
|
328
|
+
├─ Task completes quickly?
|
|
329
|
+
│ └─ Strong capture OK
|
|
330
|
+
│
|
|
331
|
+
├─ Long-running or infinite?
|
|
332
|
+
│ ├─ Can use weak self? → Use [weak self]
|
|
333
|
+
│ ├─ Need manual control? → Store task, cancel explicitly
|
|
334
|
+
│ └─ Async sequence? → [weak self] + guard
|
|
335
|
+
│
|
|
336
|
+
└─ Self owns task?
|
|
337
|
+
├─ Yes → High risk of retain cycle
|
|
338
|
+
└─ No → Lower risk, but check lifetime
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Best Practices
|
|
342
|
+
|
|
343
|
+
1. **Default to weak self** for long-running tasks
|
|
344
|
+
2. **Use guard let self** in async sequences
|
|
345
|
+
3. **Cancel tasks explicitly** when possible
|
|
346
|
+
4. **Add deinit logging** during development
|
|
347
|
+
5. **Test object deallocation** in unit tests
|
|
348
|
+
6. **Use Memory Graph** to verify no cycles
|
|
349
|
+
7. **Document lifetime expectations** in comments
|
|
350
|
+
8. **Prefer cancellation** over weak self when possible
|
|
351
|
+
9. **Avoid nested strong captures** in task closures
|
|
352
|
+
10. **Use isolated deinit** for cleanup (Swift 6.2+)
|
|
353
|
+
|
|
354
|
+
## Testing for Leaks
|
|
355
|
+
|
|
356
|
+
### Unit test pattern
|
|
357
|
+
|
|
358
|
+
```swift
|
|
359
|
+
func testViewModelDeallocates() async {
|
|
360
|
+
var viewModel: ViewModel? = ViewModel()
|
|
361
|
+
weak var weakViewModel = viewModel
|
|
362
|
+
|
|
363
|
+
viewModel?.startWork()
|
|
364
|
+
viewModel = nil
|
|
365
|
+
|
|
366
|
+
// Give tasks time to complete
|
|
367
|
+
try? await Task.sleep(for: .milliseconds(100))
|
|
368
|
+
|
|
369
|
+
XCTAssertNil(weakViewModel, "ViewModel should be deallocated")
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### SwiftUI view test
|
|
374
|
+
|
|
375
|
+
```swift
|
|
376
|
+
func testViewDeallocates() {
|
|
377
|
+
var view: MyView? = MyView()
|
|
378
|
+
weak var weakView = view
|
|
379
|
+
|
|
380
|
+
view = nil
|
|
381
|
+
|
|
382
|
+
XCTAssertNil(weakView)
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## Common Mistakes
|
|
387
|
+
|
|
388
|
+
### ❌ Forgetting weak self in loops
|
|
389
|
+
|
|
390
|
+
```swift
|
|
391
|
+
Task {
|
|
392
|
+
while true {
|
|
393
|
+
self.poll() // Retain cycle
|
|
394
|
+
try? await Task.sleep(for: .seconds(1))
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### ❌ Strong capture in async sequences
|
|
400
|
+
|
|
401
|
+
```swift
|
|
402
|
+
Task {
|
|
403
|
+
for await item in stream {
|
|
404
|
+
self.process(item) // May never release
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### ❌ Not canceling stored tasks
|
|
410
|
+
|
|
411
|
+
```swift
|
|
412
|
+
class Manager {
|
|
413
|
+
var task: Task<Void, Never>?
|
|
414
|
+
|
|
415
|
+
func start() {
|
|
416
|
+
task = Task {
|
|
417
|
+
await self.work() // Retain cycle
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Missing: deinit { task?.cancel() }
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### ❌ Assuming deinit breaks cycles
|
|
426
|
+
|
|
427
|
+
```swift
|
|
428
|
+
deinit {
|
|
429
|
+
task?.cancel() // Never called if retain cycle exists
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Examples by Use Case
|
|
434
|
+
|
|
435
|
+
### Polling service
|
|
436
|
+
|
|
437
|
+
```swift
|
|
438
|
+
final class PollingService {
|
|
439
|
+
private var task: Task<Void, Never>?
|
|
440
|
+
|
|
441
|
+
func start() {
|
|
442
|
+
task = Task { [weak self] in
|
|
443
|
+
while let self = self {
|
|
444
|
+
await self.poll()
|
|
445
|
+
try? await Task.sleep(for: .seconds(5))
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
func stop() {
|
|
451
|
+
task?.cancel()
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Notification observer
|
|
457
|
+
|
|
458
|
+
```swift
|
|
459
|
+
@MainActor
|
|
460
|
+
final class NotificationObserver {
|
|
461
|
+
private var task: Task<Void, Never>?
|
|
462
|
+
|
|
463
|
+
func startObserving() {
|
|
464
|
+
task = Task { [weak self] in
|
|
465
|
+
for await notification in NotificationCenter.default.notifications(
|
|
466
|
+
named: .someNotification
|
|
467
|
+
) {
|
|
468
|
+
guard let self = self else { return }
|
|
469
|
+
self.handle(notification)
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
isolated deinit {
|
|
475
|
+
task?.cancel()
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### Download manager
|
|
481
|
+
|
|
482
|
+
```swift
|
|
483
|
+
final class DownloadManager {
|
|
484
|
+
private var tasks: [URL: Task<Data, Error>] = [:]
|
|
485
|
+
|
|
486
|
+
func download(_ url: URL) async throws -> Data {
|
|
487
|
+
let task = Task { [weak self] in
|
|
488
|
+
defer { self?.tasks.removeValue(forKey: url) }
|
|
489
|
+
return try await URLSession.shared.data(from: url).0
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
tasks[url] = task
|
|
493
|
+
return try await task.value
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
func cancelAll() {
|
|
497
|
+
tasks.values.forEach { $0.cancel() }
|
|
498
|
+
tasks.removeAll()
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Timer
|
|
504
|
+
|
|
505
|
+
```swift
|
|
506
|
+
actor Timer {
|
|
507
|
+
private var task: Task<Void, Never>?
|
|
508
|
+
|
|
509
|
+
func start(interval: Duration, action: @Sendable () async -> Void) {
|
|
510
|
+
task = Task {
|
|
511
|
+
while !Task.isCancelled {
|
|
512
|
+
await action()
|
|
513
|
+
try? await Task.sleep(for: interval)
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
func stop() {
|
|
519
|
+
task?.cancel()
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
## Debugging Checklist
|
|
525
|
+
|
|
526
|
+
When object won't deallocate:
|
|
527
|
+
|
|
528
|
+
- [ ] Check for strong self captures in tasks
|
|
529
|
+
- [ ] Verify tasks are canceled or complete
|
|
530
|
+
- [ ] Look for infinite loops or sequences
|
|
531
|
+
- [ ] Check if self owns the task
|
|
532
|
+
- [ ] Use Memory Graph to find cycles
|
|
533
|
+
- [ ] Add deinit logging to verify
|
|
534
|
+
- [ ] Test with weak references
|
|
535
|
+
- [ ] Review async sequence usage
|
|
536
|
+
- [ ] Check nested task captures
|
|
537
|
+
- [ ] Verify cleanup in deinit
|
|
538
|
+
|
|
539
|
+
## Further Learning
|
|
540
|
+
|
|
541
|
+
For migration strategies, real-world examples, and advanced memory patterns, see [Swift Concurrency Course](https://www.swiftconcurrencycourse.com).
|
|
542
|
+
|