opencode-starterkit 1.0.1
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/README.md +47 -0
- package/baseline/.env.example +196 -0
- package/baseline/.template-manifest.json +646 -0
- package/baseline/.version +1 -0
- package/baseline/AGENTS.md +410 -0
- package/baseline/AGENT_ALIGNMENT.md +564 -0
- package/baseline/README.md +79 -0
- package/baseline/agent/build.md +373 -0
- package/baseline/agent/explore.md +96 -0
- package/baseline/agent/general.md +186 -0
- package/baseline/agent/painter.md +74 -0
- package/baseline/agent/plan.md +435 -0
- package/baseline/agent/review.md +243 -0
- package/baseline/agent/runner.md +79 -0
- package/baseline/agent/scout.md +100 -0
- package/baseline/agent/vision.md +91 -0
- package/baseline/command/compound.md +143 -0
- package/baseline/command/create.md +213 -0
- package/baseline/command/design.md +112 -0
- package/baseline/command/handoff.md +147 -0
- package/baseline/command/init-context.md +273 -0
- package/baseline/command/init-user.md +105 -0
- package/baseline/command/init.md +117 -0
- package/baseline/command/lfg.md +170 -0
- package/baseline/command/plan.md +355 -0
- package/baseline/command/pr.md +161 -0
- package/baseline/command/research.md +125 -0
- package/baseline/command/resume.md +87 -0
- package/baseline/command/review-codebase.md +131 -0
- package/baseline/command/ship.md +342 -0
- package/baseline/command/start.md +158 -0
- package/baseline/command/status.md +117 -0
- package/baseline/command/ui-review.md +92 -0
- package/baseline/command/ui-slop-check.md +146 -0
- package/baseline/command/verify.md +160 -0
- package/baseline/context/README.md +29 -0
- package/baseline/dcp.jsonc +72 -0
- package/baseline/memory/README.md +89 -0
- package/baseline/memory/_templates/design.md +59 -0
- package/baseline/memory/_templates/prd.md +192 -0
- package/baseline/memory/_templates/project.md +58 -0
- package/baseline/memory/_templates/proposal.md +38 -0
- package/baseline/memory/_templates/roadmap.md +93 -0
- package/baseline/memory/_templates/state.md +89 -0
- package/baseline/memory/_templates/tasks.md +198 -0
- package/baseline/memory/_templates/tech-stack.md +85 -0
- package/baseline/memory/_templates/user.md +26 -0
- package/baseline/memory/project/gotchas.md +67 -0
- package/baseline/memory/project/project.md +92 -0
- package/baseline/memory/project/roadmap.md +142 -0
- package/baseline/memory/project/state.md +84 -0
- package/baseline/memory/project/tech-stack.md +53 -0
- package/baseline/memory/project/user.md +38 -0
- package/baseline/memory/research/benchmark-framework.md +162 -0
- package/baseline/memory/research/ccpm-analysis.md +334 -0
- package/baseline/memory/research/context-management-analysis.md +685 -0
- package/baseline/memory/research/effectiveness-audit.md +213 -0
- package/baseline/memory/research/opencode-mcp-bug-report.md +129 -0
- package/baseline/memory/research/openspec-analysis.md +226 -0
- package/baseline/memory/session-context.md +40 -0
- package/baseline/opencode.json +1431 -0
- package/baseline/opencode.json.tui-migration.bak +1380 -0
- package/baseline/package-lock.json +87 -0
- package/baseline/package.json +21 -0
- package/baseline/plans/1768385996691-silent-wizard.md +247 -0
- package/baseline/plans/1770006237537-mighty-otter.md +418 -0
- package/baseline/plans/1770006913647-glowing-forest.md +170 -0
- package/baseline/plans/1770013678126-witty-planet.md +278 -0
- package/baseline/plans/1770112267595-shiny-rocket.md +258 -0
- package/baseline/plans/swarm-protocol.md +123 -0
- package/baseline/plugin/README.md +70 -0
- package/baseline/plugin/copilot-auth.ts +607 -0
- package/baseline/plugin/lib/capture.ts +177 -0
- package/baseline/plugin/lib/context.ts +198 -0
- package/baseline/plugin/lib/curator.ts +234 -0
- package/baseline/plugin/lib/db/maintenance.ts +312 -0
- package/baseline/plugin/lib/db/observations.ts +299 -0
- package/baseline/plugin/lib/db/pipeline.ts +520 -0
- package/baseline/plugin/lib/db/schema.ts +356 -0
- package/baseline/plugin/lib/db/types.ts +211 -0
- package/baseline/plugin/lib/distill.ts +376 -0
- package/baseline/plugin/lib/inject.ts +126 -0
- package/baseline/plugin/lib/memory-admin-tools.ts +188 -0
- package/baseline/plugin/lib/memory-db.ts +58 -0
- package/baseline/plugin/lib/memory-helpers.ts +111 -0
- package/baseline/plugin/lib/memory-hooks.ts +195 -0
- package/baseline/plugin/lib/memory-tools.ts +341 -0
- package/baseline/plugin/lib/notify.ts +81 -0
- package/baseline/plugin/memory.ts +89 -0
- package/baseline/plugin/notification.ts.bak +64 -0
- package/baseline/plugin/package.json +7 -0
- package/baseline/plugin/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +178 -0
- package/baseline/plugin/sdk/copilot/chat/get-response-metadata.ts +15 -0
- package/baseline/plugin/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
- package/baseline/plugin/sdk/copilot/chat/openai-compatible-api-types.ts +72 -0
- package/baseline/plugin/sdk/copilot/chat/openai-compatible-chat-language-model.ts +833 -0
- package/baseline/plugin/sdk/copilot/chat/openai-compatible-chat-options.ts +30 -0
- package/baseline/plugin/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +48 -0
- package/baseline/plugin/sdk/copilot/chat/openai-compatible-prepare-tools.ts +92 -0
- package/baseline/plugin/sdk/copilot/copilot-provider.ts +94 -0
- package/baseline/plugin/sdk/copilot/index.ts +5 -0
- package/baseline/plugin/sdk/copilot/openai-compatible-error.ts +30 -0
- package/baseline/plugin/sessions.ts +428 -0
- package/baseline/plugin/skill-mcp.ts +618 -0
- package/baseline/plugin/tsconfig.json +16 -0
- package/baseline/skill/accessibility-audit/SKILL.md +191 -0
- package/baseline/skill/agent-browser/SKILL.md +413 -0
- package/baseline/skill/agent-teams/SKILL.md +268 -0
- package/baseline/skill/augment-context-engine/SKILL.md +122 -0
- package/baseline/skill/augment-context-engine/mcp.json +6 -0
- package/baseline/skill/beads/SKILL.md +181 -0
- package/baseline/skill/beads/references/BEST_PRACTICES.md +27 -0
- package/baseline/skill/beads/references/BOUNDARIES.md +219 -0
- package/baseline/skill/beads/references/DEPENDENCIES.md +124 -0
- package/baseline/skill/beads/references/EXAMPLES.md +45 -0
- package/baseline/skill/beads/references/FILE_CLAIMING.md +101 -0
- package/baseline/skill/beads/references/GIT_SYNC.md +25 -0
- package/baseline/skill/beads/references/HIERARCHY.md +71 -0
- package/baseline/skill/beads/references/MULTI_AGENT.md +40 -0
- package/baseline/skill/beads/references/RESUMABILITY.md +177 -0
- package/baseline/skill/beads/references/SESSION_PROTOCOL.md +61 -0
- package/baseline/skill/beads/references/TASK_CREATION.md +38 -0
- package/baseline/skill/beads/references/TROUBLESHOOTING.md +38 -0
- package/baseline/skill/beads/references/WORKFLOWS.md +226 -0
- package/baseline/skill/beads-bridge/SKILL.md +321 -0
- package/baseline/skill/brainstorming/SKILL.md +114 -0
- package/baseline/skill/chrome-devtools/SKILL.md +76 -0
- package/baseline/skill/chrome-devtools/mcp.json +19 -0
- package/baseline/skill/cloudflare/SKILL.md +253 -0
- package/baseline/skill/cloudflare/references/agents-sdk/README.md +35 -0
- package/baseline/skill/cloudflare/references/agents-sdk/api.md +100 -0
- package/baseline/skill/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/baseline/skill/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/baseline/skill/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/baseline/skill/cloudflare/references/ai-gateway/README.md +695 -0
- package/baseline/skill/cloudflare/references/ai-search/README.md +14 -0
- package/baseline/skill/cloudflare/references/ai-search/api.md +38 -0
- package/baseline/skill/cloudflare/references/ai-search/configuration.md +52 -0
- package/baseline/skill/cloudflare/references/ai-search/gotchas.md +41 -0
- package/baseline/skill/cloudflare/references/ai-search/patterns.md +45 -0
- package/baseline/skill/cloudflare/references/analytics-engine/README.md +14 -0
- package/baseline/skill/cloudflare/references/analytics-engine/api.md +27 -0
- package/baseline/skill/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/baseline/skill/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/baseline/skill/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/baseline/skill/cloudflare/references/api/README.md +21 -0
- package/baseline/skill/cloudflare/references/api/api.md +31 -0
- package/baseline/skill/cloudflare/references/api/configuration.md +20 -0
- package/baseline/skill/cloudflare/references/api/gotchas.md +28 -0
- package/baseline/skill/cloudflare/references/api/patterns.md +47 -0
- package/baseline/skill/cloudflare/references/api-shield/README.md +20 -0
- package/baseline/skill/cloudflare/references/api-shield/api.md +78 -0
- package/baseline/skill/cloudflare/references/api-shield/configuration.md +128 -0
- package/baseline/skill/cloudflare/references/api-shield/gotchas.md +51 -0
- package/baseline/skill/cloudflare/references/api-shield/patterns.md +145 -0
- package/baseline/skill/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/baseline/skill/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/baseline/skill/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/baseline/skill/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/baseline/skill/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/baseline/skill/cloudflare/references/bindings/README.md +14 -0
- package/baseline/skill/cloudflare/references/bindings/api.md +3 -0
- package/baseline/skill/cloudflare/references/bindings/configuration.md +58 -0
- package/baseline/skill/cloudflare/references/bindings/gotchas.md +35 -0
- package/baseline/skill/cloudflare/references/bindings/patterns.md +37 -0
- package/baseline/skill/cloudflare/references/bot-management/README.md +71 -0
- package/baseline/skill/cloudflare/references/bot-management/api.md +168 -0
- package/baseline/skill/cloudflare/references/bot-management/configuration.md +114 -0
- package/baseline/skill/cloudflare/references/bot-management/gotchas.md +99 -0
- package/baseline/skill/cloudflare/references/bot-management/patterns.md +125 -0
- package/baseline/skill/cloudflare/references/browser-rendering/README.md +16 -0
- package/baseline/skill/cloudflare/references/browser-rendering/api.md +54 -0
- package/baseline/skill/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/baseline/skill/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/baseline/skill/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/baseline/skill/cloudflare/references/c3/README.md +264 -0
- package/baseline/skill/cloudflare/references/cache-reserve/README.md +93 -0
- package/baseline/skill/cloudflare/references/cache-reserve/api.md +176 -0
- package/baseline/skill/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/baseline/skill/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/baseline/skill/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/baseline/skill/cloudflare/references/containers/README.md +16 -0
- package/baseline/skill/cloudflare/references/containers/api.md +43 -0
- package/baseline/skill/cloudflare/references/containers/configuration.md +56 -0
- package/baseline/skill/cloudflare/references/containers/gotchas.md +21 -0
- package/baseline/skill/cloudflare/references/containers/patterns.md +40 -0
- package/baseline/skill/cloudflare/references/cron-triggers/README.md +85 -0
- package/baseline/skill/cloudflare/references/cron-triggers/api.md +198 -0
- package/baseline/skill/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/baseline/skill/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/baseline/skill/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/baseline/skill/cloudflare/references/d1/README.md +92 -0
- package/baseline/skill/cloudflare/references/d1/api.md +141 -0
- package/baseline/skill/cloudflare/references/d1/configuration.md +127 -0
- package/baseline/skill/cloudflare/references/d1/gotchas.md +70 -0
- package/baseline/skill/cloudflare/references/d1/patterns.md +144 -0
- package/baseline/skill/cloudflare/references/ddos/README.md +34 -0
- package/baseline/skill/cloudflare/references/ddos/api.md +136 -0
- package/baseline/skill/cloudflare/references/ddos/configuration.md +67 -0
- package/baseline/skill/cloudflare/references/ddos/gotchas.md +114 -0
- package/baseline/skill/cloudflare/references/ddos/patterns.md +158 -0
- package/baseline/skill/cloudflare/references/do-storage/README.md +62 -0
- package/baseline/skill/cloudflare/references/do-storage/api.md +89 -0
- package/baseline/skill/cloudflare/references/do-storage/configuration.md +116 -0
- package/baseline/skill/cloudflare/references/do-storage/gotchas.md +93 -0
- package/baseline/skill/cloudflare/references/do-storage/patterns.md +112 -0
- package/baseline/skill/cloudflare/references/durable-objects/README.md +125 -0
- package/baseline/skill/cloudflare/references/durable-objects/api.md +152 -0
- package/baseline/skill/cloudflare/references/durable-objects/configuration.md +148 -0
- package/baseline/skill/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/baseline/skill/cloudflare/references/durable-objects/patterns.md +255 -0
- package/baseline/skill/cloudflare/references/email-routing/README.md +18 -0
- package/baseline/skill/cloudflare/references/email-routing/api.md +46 -0
- package/baseline/skill/cloudflare/references/email-routing/configuration.md +63 -0
- package/baseline/skill/cloudflare/references/email-routing/gotchas.md +16 -0
- package/baseline/skill/cloudflare/references/email-routing/patterns.md +46 -0
- package/baseline/skill/cloudflare/references/email-workers/README.md +598 -0
- package/baseline/skill/cloudflare/references/hyperdrive/README.md +62 -0
- package/baseline/skill/cloudflare/references/hyperdrive/api.md +137 -0
- package/baseline/skill/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/baseline/skill/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/baseline/skill/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/baseline/skill/cloudflare/references/images/README.md +14 -0
- package/baseline/skill/cloudflare/references/images/api.md +3 -0
- package/baseline/skill/cloudflare/references/images/configuration.md +45 -0
- package/baseline/skill/cloudflare/references/images/gotchas.md +23 -0
- package/baseline/skill/cloudflare/references/images/patterns.md +31 -0
- package/baseline/skill/cloudflare/references/kv/README.md +60 -0
- package/baseline/skill/cloudflare/references/kv/api.md +114 -0
- package/baseline/skill/cloudflare/references/kv/configuration.md +92 -0
- package/baseline/skill/cloudflare/references/kv/gotchas.md +117 -0
- package/baseline/skill/cloudflare/references/kv/patterns.md +139 -0
- package/baseline/skill/cloudflare/references/miniflare/README.md +64 -0
- package/baseline/skill/cloudflare/references/miniflare/api.md +144 -0
- package/baseline/skill/cloudflare/references/miniflare/configuration.md +203 -0
- package/baseline/skill/cloudflare/references/miniflare/gotchas.md +187 -0
- package/baseline/skill/cloudflare/references/miniflare/patterns.md +211 -0
- package/baseline/skill/cloudflare/references/network-interconnect/README.md +60 -0
- package/baseline/skill/cloudflare/references/network-interconnect/api.md +240 -0
- package/baseline/skill/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/baseline/skill/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/baseline/skill/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/baseline/skill/cloudflare/references/observability/README.md +18 -0
- package/baseline/skill/cloudflare/references/observability/api.md +51 -0
- package/baseline/skill/cloudflare/references/observability/configuration.md +60 -0
- package/baseline/skill/cloudflare/references/observability/gotchas.md +36 -0
- package/baseline/skill/cloudflare/references/observability/patterns.md +42 -0
- package/baseline/skill/cloudflare/references/pages/README.md +76 -0
- package/baseline/skill/cloudflare/references/pages/api.md +200 -0
- package/baseline/skill/cloudflare/references/pages/configuration.md +228 -0
- package/baseline/skill/cloudflare/references/pages/gotchas.md +161 -0
- package/baseline/skill/cloudflare/references/pages/patterns.md +145 -0
- package/baseline/skill/cloudflare/references/pages-functions/README.md +57 -0
- package/baseline/skill/cloudflare/references/pages-functions/api.md +201 -0
- package/baseline/skill/cloudflare/references/pages-functions/configuration.md +159 -0
- package/baseline/skill/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/baseline/skill/cloudflare/references/pages-functions/patterns.md +190 -0
- package/baseline/skill/cloudflare/references/pipelines/README.md +664 -0
- package/baseline/skill/cloudflare/references/pulumi/README.md +107 -0
- package/baseline/skill/cloudflare/references/pulumi/api.md +194 -0
- package/baseline/skill/cloudflare/references/pulumi/configuration.md +216 -0
- package/baseline/skill/cloudflare/references/pulumi/gotchas.md +223 -0
- package/baseline/skill/cloudflare/references/pulumi/patterns.md +139 -0
- package/baseline/skill/cloudflare/references/queues/README.md +69 -0
- package/baseline/skill/cloudflare/references/queues/api.md +138 -0
- package/baseline/skill/cloudflare/references/queues/configuration.md +125 -0
- package/baseline/skill/cloudflare/references/queues/gotchas.md +112 -0
- package/baseline/skill/cloudflare/references/queues/patterns.md +155 -0
- package/baseline/skill/cloudflare/references/r2/README.md +61 -0
- package/baseline/skill/cloudflare/references/r2/api.md +127 -0
- package/baseline/skill/cloudflare/references/r2/configuration.md +76 -0
- package/baseline/skill/cloudflare/references/r2/gotchas.md +94 -0
- package/baseline/skill/cloudflare/references/r2/patterns.md +127 -0
- package/baseline/skill/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/baseline/skill/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/baseline/skill/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/baseline/skill/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/baseline/skill/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/baseline/skill/cloudflare/references/r2-sql/README.md +512 -0
- package/baseline/skill/cloudflare/references/realtime-sfu/README.md +21 -0
- package/baseline/skill/cloudflare/references/realtime-sfu/api.md +135 -0
- package/baseline/skill/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/baseline/skill/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/baseline/skill/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/baseline/skill/cloudflare/references/realtimekit/README.md +81 -0
- package/baseline/skill/cloudflare/references/realtimekit/api.md +164 -0
- package/baseline/skill/cloudflare/references/realtimekit/configuration.md +147 -0
- package/baseline/skill/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/baseline/skill/cloudflare/references/realtimekit/patterns.md +155 -0
- package/baseline/skill/cloudflare/references/sandbox/README.md +90 -0
- package/baseline/skill/cloudflare/references/sandbox/api.md +178 -0
- package/baseline/skill/cloudflare/references/sandbox/configuration.md +131 -0
- package/baseline/skill/cloudflare/references/sandbox/gotchas.md +156 -0
- package/baseline/skill/cloudflare/references/sandbox/patterns.md +203 -0
- package/baseline/skill/cloudflare/references/secrets-store/README.md +58 -0
- package/baseline/skill/cloudflare/references/secrets-store/api.md +182 -0
- package/baseline/skill/cloudflare/references/secrets-store/configuration.md +140 -0
- package/baseline/skill/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/baseline/skill/cloudflare/references/secrets-store/patterns.md +218 -0
- package/baseline/skill/cloudflare/references/smart-placement/README.md +91 -0
- package/baseline/skill/cloudflare/references/smart-placement/api.md +139 -0
- package/baseline/skill/cloudflare/references/smart-placement/configuration.md +129 -0
- package/baseline/skill/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/baseline/skill/cloudflare/references/smart-placement/patterns.md +135 -0
- package/baseline/skill/cloudflare/references/snippets/README.md +15 -0
- package/baseline/skill/cloudflare/references/snippets/api.md +47 -0
- package/baseline/skill/cloudflare/references/snippets/configuration.md +33 -0
- package/baseline/skill/cloudflare/references/snippets/gotchas.md +21 -0
- package/baseline/skill/cloudflare/references/snippets/patterns.md +34 -0
- package/baseline/skill/cloudflare/references/spectrum/README.md +16 -0
- package/baseline/skill/cloudflare/references/spectrum/api.md +24 -0
- package/baseline/skill/cloudflare/references/spectrum/configuration.md +43 -0
- package/baseline/skill/cloudflare/references/spectrum/gotchas.md +42 -0
- package/baseline/skill/cloudflare/references/spectrum/patterns.md +40 -0
- package/baseline/skill/cloudflare/references/static-assets/README.md +14 -0
- package/baseline/skill/cloudflare/references/static-assets/api.md +3 -0
- package/baseline/skill/cloudflare/references/static-assets/configuration.md +47 -0
- package/baseline/skill/cloudflare/references/static-assets/gotchas.md +44 -0
- package/baseline/skill/cloudflare/references/static-assets/patterns.md +42 -0
- package/baseline/skill/cloudflare/references/stream/README.md +103 -0
- package/baseline/skill/cloudflare/references/stream/api.md +204 -0
- package/baseline/skill/cloudflare/references/stream/configuration.md +127 -0
- package/baseline/skill/cloudflare/references/stream/gotchas.md +131 -0
- package/baseline/skill/cloudflare/references/stream/patterns.md +152 -0
- package/baseline/skill/cloudflare/references/tail-workers/README.md +640 -0
- package/baseline/skill/cloudflare/references/terraform/README.md +76 -0
- package/baseline/skill/cloudflare/references/terraform/api.md +159 -0
- package/baseline/skill/cloudflare/references/terraform/configuration.md +156 -0
- package/baseline/skill/cloudflare/references/terraform/gotchas.md +207 -0
- package/baseline/skill/cloudflare/references/terraform/patterns.md +135 -0
- package/baseline/skill/cloudflare/references/tunnel/README.md +82 -0
- package/baseline/skill/cloudflare/references/tunnel/api.md +105 -0
- package/baseline/skill/cloudflare/references/tunnel/configuration.md +113 -0
- package/baseline/skill/cloudflare/references/tunnel/gotchas.md +115 -0
- package/baseline/skill/cloudflare/references/tunnel/patterns.md +157 -0
- package/baseline/skill/cloudflare/references/turn/README.md +699 -0
- package/baseline/skill/cloudflare/references/turnstile/README.md +14 -0
- package/baseline/skill/cloudflare/references/turnstile/api.md +3 -0
- package/baseline/skill/cloudflare/references/turnstile/configuration.md +19 -0
- package/baseline/skill/cloudflare/references/turnstile/gotchas.md +27 -0
- package/baseline/skill/cloudflare/references/turnstile/patterns.md +41 -0
- package/baseline/skill/cloudflare/references/vectorize/README.md +682 -0
- package/baseline/skill/cloudflare/references/waf/README.md +14 -0
- package/baseline/skill/cloudflare/references/waf/api.md +3 -0
- package/baseline/skill/cloudflare/references/waf/configuration.md +44 -0
- package/baseline/skill/cloudflare/references/waf/gotchas.md +24 -0
- package/baseline/skill/cloudflare/references/waf/patterns.md +29 -0
- package/baseline/skill/cloudflare/references/web-analytics/README.md +19 -0
- package/baseline/skill/cloudflare/references/web-analytics/api.md +52 -0
- package/baseline/skill/cloudflare/references/web-analytics/configuration.md +31 -0
- package/baseline/skill/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/baseline/skill/cloudflare/references/web-analytics/patterns.md +52 -0
- package/baseline/skill/cloudflare/references/workerd/README.md +47 -0
- package/baseline/skill/cloudflare/references/workerd/api.md +199 -0
- package/baseline/skill/cloudflare/references/workerd/configuration.md +185 -0
- package/baseline/skill/cloudflare/references/workerd/gotchas.md +203 -0
- package/baseline/skill/cloudflare/references/workerd/patterns.md +216 -0
- package/baseline/skill/cloudflare/references/workers/README.md +96 -0
- package/baseline/skill/cloudflare/references/workers/api.md +137 -0
- package/baseline/skill/cloudflare/references/workers/configuration.md +147 -0
- package/baseline/skill/cloudflare/references/workers/gotchas.md +99 -0
- package/baseline/skill/cloudflare/references/workers/patterns.md +149 -0
- package/baseline/skill/cloudflare/references/workers-ai/README.md +116 -0
- package/baseline/skill/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/baseline/skill/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/baseline/skill/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/baseline/skill/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/baseline/skill/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/baseline/skill/cloudflare/references/workers-playground/README.md +16 -0
- package/baseline/skill/cloudflare/references/workers-playground/api.md +20 -0
- package/baseline/skill/cloudflare/references/workers-playground/configuration.md +3 -0
- package/baseline/skill/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/baseline/skill/cloudflare/references/workers-playground/patterns.md +42 -0
- package/baseline/skill/cloudflare/references/workers-vpc/README.md +579 -0
- package/baseline/skill/cloudflare/references/workflows/README.md +62 -0
- package/baseline/skill/cloudflare/references/workflows/api.md +125 -0
- package/baseline/skill/cloudflare/references/workflows/configuration.md +177 -0
- package/baseline/skill/cloudflare/references/workflows/gotchas.md +136 -0
- package/baseline/skill/cloudflare/references/workflows/patterns.md +132 -0
- package/baseline/skill/cloudflare/references/wrangler/README.md +90 -0
- package/baseline/skill/cloudflare/references/wrangler/api.md +140 -0
- package/baseline/skill/cloudflare/references/wrangler/configuration.md +128 -0
- package/baseline/skill/cloudflare/references/wrangler/gotchas.md +93 -0
- package/baseline/skill/cloudflare/references/wrangler/patterns.md +150 -0
- package/baseline/skill/cloudflare/references/zaraz/README.md +360 -0
- package/baseline/skill/code-navigation/SKILL.md +130 -0
- package/baseline/skill/compaction/SKILL.md +317 -0
- package/baseline/skill/condition-based-waiting/SKILL.md +123 -0
- package/baseline/skill/condition-based-waiting/example.ts +158 -0
- package/baseline/skill/context-engineering/SKILL.md +176 -0
- package/baseline/skill/context-initialization/SKILL.md +70 -0
- package/baseline/skill/context-management/SKILL.md +163 -0
- package/baseline/skill/core-data-expert/SKILL.md +93 -0
- package/baseline/skill/core-data-expert/references/batch-operations.md +543 -0
- package/baseline/skill/core-data-expert/references/cloudkit-integration.md +259 -0
- package/baseline/skill/core-data-expert/references/concurrency.md +522 -0
- package/baseline/skill/core-data-expert/references/fetch-requests.md +643 -0
- package/baseline/skill/core-data-expert/references/glossary.md +233 -0
- package/baseline/skill/core-data-expert/references/migration.md +393 -0
- package/baseline/skill/core-data-expert/references/model-configuration.md +597 -0
- package/baseline/skill/core-data-expert/references/performance.md +300 -0
- package/baseline/skill/core-data-expert/references/persistent-history.md +553 -0
- package/baseline/skill/core-data-expert/references/project-audit.md +60 -0
- package/baseline/skill/core-data-expert/references/saving.md +574 -0
- package/baseline/skill/core-data-expert/references/stack-setup.md +625 -0
- package/baseline/skill/core-data-expert/references/testing.md +300 -0
- package/baseline/skill/core-data-expert/references/threading.md +589 -0
- package/baseline/skill/deep-research/SKILL.md +384 -0
- package/baseline/skill/defense-in-depth/SKILL.md +166 -0
- package/baseline/skill/design-system-audit/SKILL.md +153 -0
- package/baseline/skill/development-lifecycle/SKILL.md +356 -0
- package/baseline/skill/dispatching-parallel-agents/SKILL.md +191 -0
- package/baseline/skill/executing-plans/SKILL.md +247 -0
- package/baseline/skill/figma/SKILL.md +224 -0
- package/baseline/skill/finishing-a-development-branch/SKILL.md +357 -0
- package/baseline/skill/frontend-design/SKILL.md +235 -0
- package/baseline/skill/frontend-design/references/animation/motion-advanced.md +224 -0
- package/baseline/skill/frontend-design/references/animation/motion-core.md +181 -0
- package/baseline/skill/frontend-design/references/canvas/execution.md +90 -0
- package/baseline/skill/frontend-design/references/canvas/philosophy.md +94 -0
- package/baseline/skill/frontend-design/references/design/color-system.md +111 -0
- package/baseline/skill/frontend-design/references/design/interaction.md +149 -0
- package/baseline/skill/frontend-design/references/design/typography-rules.md +106 -0
- package/baseline/skill/frontend-design/references/design/ux-writing.md +99 -0
- package/baseline/skill/frontend-design/references/shadcn/accessibility.md +132 -0
- package/baseline/skill/frontend-design/references/shadcn/core-components.md +153 -0
- package/baseline/skill/frontend-design/references/shadcn/form-components.md +158 -0
- package/baseline/skill/frontend-design/references/shadcn/setup.md +69 -0
- package/baseline/skill/frontend-design/references/shadcn/theming.md +152 -0
- package/baseline/skill/frontend-design/references/tailwind/responsive.md +112 -0
- package/baseline/skill/frontend-design/references/tailwind/utilities-layout.md +134 -0
- package/baseline/skill/frontend-design/references/tailwind/utilities-styling.md +165 -0
- package/baseline/skill/frontend-design/references/tailwind/v4-config.md +147 -0
- package/baseline/skill/frontend-design/references/tailwind/v4-features.md +128 -0
- package/baseline/skill/gemini-large-context/SKILL.md +216 -0
- package/baseline/skill/index-knowledge/SKILL.md +413 -0
- package/baseline/skill/jira/SKILL.md +283 -0
- package/baseline/skill/jira/mcp.json +6 -0
- package/baseline/skill/memory-system/SKILL.md +84 -0
- package/baseline/skill/mockup-to-code/SKILL.md +184 -0
- package/baseline/skill/mqdh/SKILL.md +171 -0
- package/baseline/skill/obsidian/SKILL.md +192 -0
- package/baseline/skill/obsidian/mcp.json +22 -0
- package/baseline/skill/opensrc/SKILL.md +127 -0
- package/baseline/skill/opensrc/references/architecture.md +176 -0
- package/baseline/skill/opensrc/references/cli-usage.md +176 -0
- package/baseline/skill/opensrc/references/registry-support.md +137 -0
- package/baseline/skill/pdf-extract/SKILL.md +438 -0
- package/baseline/skill/playwright/SKILL.md +320 -0
- package/baseline/skill/playwright/mcp.json +16 -0
- package/baseline/skill/playwriter/SKILL.md +158 -0
- package/baseline/skill/polar/SKILL.md +102 -0
- package/baseline/skill/prd/SKILL.md +146 -0
- package/baseline/skill/prd-task/SKILL.md +182 -0
- package/baseline/skill/prd-task/references/prd-schema.json +124 -0
- package/baseline/skill/ralph/SKILL.md +296 -0
- package/baseline/skill/react-best-practices/AGENTS.md +2410 -0
- package/baseline/skill/react-best-practices/README.md +123 -0
- package/baseline/skill/react-best-practices/SKILL.md +133 -0
- package/baseline/skill/react-best-practices/metadata.json +15 -0
- package/baseline/skill/react-best-practices/rules/_sections.md +46 -0
- package/baseline/skill/react-best-practices/rules/_template.md +28 -0
- package/baseline/skill/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/baseline/skill/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/baseline/skill/react-best-practices/rules/async-api-routes.md +38 -0
- package/baseline/skill/react-best-practices/rules/async-defer-await.md +80 -0
- package/baseline/skill/react-best-practices/rules/async-dependencies.md +36 -0
- package/baseline/skill/react-best-practices/rules/async-parallel.md +28 -0
- package/baseline/skill/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/baseline/skill/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/baseline/skill/react-best-practices/rules/bundle-conditional.md +31 -0
- package/baseline/skill/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/baseline/skill/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/baseline/skill/react-best-practices/rules/bundle-preload.md +50 -0
- package/baseline/skill/react-best-practices/rules/client-event-listeners.md +74 -0
- package/baseline/skill/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/baseline/skill/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/baseline/skill/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/baseline/skill/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/baseline/skill/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/baseline/skill/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/baseline/skill/react-best-practices/rules/js-cache-storage.md +70 -0
- package/baseline/skill/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/baseline/skill/react-best-practices/rules/js-early-exit.md +50 -0
- package/baseline/skill/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/baseline/skill/react-best-practices/rules/js-index-maps.md +37 -0
- package/baseline/skill/react-best-practices/rules/js-length-check-first.md +49 -0
- package/baseline/skill/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/baseline/skill/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/baseline/skill/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/baseline/skill/react-best-practices/rules/rendering-activity.md +26 -0
- package/baseline/skill/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/baseline/skill/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/baseline/skill/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/baseline/skill/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/baseline/skill/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/baseline/skill/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/baseline/skill/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/baseline/skill/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/baseline/skill/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/baseline/skill/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/baseline/skill/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/baseline/skill/react-best-practices/rules/rerender-memo.md +44 -0
- package/baseline/skill/react-best-practices/rules/rerender-transitions.md +40 -0
- package/baseline/skill/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/baseline/skill/react-best-practices/rules/server-cache-lru.md +41 -0
- package/baseline/skill/react-best-practices/rules/server-cache-react.md +76 -0
- package/baseline/skill/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/baseline/skill/react-best-practices/rules/server-serialization.md +38 -0
- package/baseline/skill/receiving-code-review/SKILL.md +252 -0
- package/baseline/skill/requesting-code-review/SKILL.md +397 -0
- package/baseline/skill/requesting-code-review/review.md +160 -0
- package/baseline/skill/resend/SKILL.md +177 -0
- package/baseline/skill/resend/references/react-email.md +287 -0
- package/baseline/skill/resend/references/receive-email.md +248 -0
- package/baseline/skill/resend/references/send-email.md +318 -0
- package/baseline/skill/root-cause-tracing/SKILL.md +192 -0
- package/baseline/skill/root-cause-tracing/find-polluter.sh +63 -0
- package/baseline/skill/session-management/SKILL.md +9 -0
- package/baseline/skill/sharing-skills/SKILL.md +214 -0
- package/baseline/skill/skill-creator/SKILL.md +156 -0
- package/baseline/skill/source-code-research/SKILL.md +293 -0
- package/baseline/skill/source-code-research/references/analysis-tips.md +43 -0
- package/baseline/skill/source-code-research/references/anti-patterns.md +36 -0
- package/baseline/skill/source-code-research/references/common-patterns.md +57 -0
- package/baseline/skill/source-code-research/references/example-workflow.md +60 -0
- package/baseline/skill/source-code-research/references/further-reading.md +5 -0
- package/baseline/skill/source-code-research/references/source-structure.md +45 -0
- package/baseline/skill/stitch/SKILL.md +147 -0
- package/baseline/skill/stitch/mcp.json +9 -0
- package/baseline/skill/structured-edit/SKILL.md +181 -0
- package/baseline/skill/subagent-driven-development/SKILL.md +237 -0
- package/baseline/skill/supabase/SKILL.md +130 -0
- package/baseline/skill/supabase/mcp.json +27 -0
- package/baseline/skill/supabase-postgres-best-practices/AGENTS.md +1490 -0
- package/baseline/skill/supabase-postgres-best-practices/SKILL.md +65 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/advanced-full-text-search.md +55 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/advanced-jsonb-indexing.md +49 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/conn-idle-timeout.md +46 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/conn-limits.md +44 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/conn-pooling.md +41 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/conn-prepared-statements.md +46 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/data-batch-inserts.md +54 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/data-n-plus-one.md +53 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/data-pagination.md +50 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/data-upsert.md +50 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/lock-advisory.md +56 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/lock-deadlock-prevention.md +68 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/lock-short-transactions.md +50 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/lock-skip-locked.md +54 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/monitor-explain-analyze.md +45 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/monitor-pg-stat-statements.md +55 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/monitor-vacuum-analyze.md +55 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/query-composite-indexes.md +44 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/query-covering-indexes.md +40 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/query-index-types.md +45 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/query-missing-indexes.md +43 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/query-partial-indexes.md +45 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/schema-data-types.md +46 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/schema-foreign-key-indexes.md +59 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/schema-lowercase-identifiers.md +55 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/schema-partitioning.md +55 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/schema-primary-keys.md +61 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/security-privileges.md +54 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/security-rls-basics.md +50 -0
- package/baseline/skill/supabase-postgres-best-practices/rules/security-rls-performance.md +57 -0
- package/baseline/skill/swarm-coordination/SKILL.md +179 -0
- package/baseline/skill/swarm-coordination/references/architecture.md +39 -0
- package/baseline/skill/swarm-coordination/references/delegation-worker-protocol.md +145 -0
- package/baseline/skill/swarm-coordination/references/dependency-graph.md +50 -0
- package/baseline/skill/swarm-coordination/references/drift-check.md +90 -0
- package/baseline/skill/swarm-coordination/references/integration-beads.md +20 -0
- package/baseline/skill/swarm-coordination/references/launch-flow.md +186 -0
- package/baseline/skill/swarm-coordination/references/reconciler.md +172 -0
- package/baseline/skill/swarm-coordination/references/tier-enforcement.md +78 -0
- package/baseline/skill/swarm-coordination/references/tmux-integration.md +134 -0
- package/baseline/skill/swift-concurrency/SKILL.md +266 -0
- package/baseline/skill/swift-concurrency/references/actors.md +640 -0
- package/baseline/skill/swift-concurrency/references/async-algorithms.md +822 -0
- package/baseline/skill/swift-concurrency/references/async-await-basics.md +249 -0
- package/baseline/skill/swift-concurrency/references/async-sequences.md +670 -0
- package/baseline/skill/swift-concurrency/references/core-data.md +533 -0
- package/baseline/skill/swift-concurrency/references/glossary.md +128 -0
- package/baseline/skill/swift-concurrency/references/linting.md +142 -0
- package/baseline/skill/swift-concurrency/references/memory-management.md +542 -0
- package/baseline/skill/swift-concurrency/references/migration.md +1076 -0
- package/baseline/skill/swift-concurrency/references/performance.md +574 -0
- package/baseline/skill/swift-concurrency/references/sendable.md +578 -0
- package/baseline/skill/swift-concurrency/references/tasks.md +604 -0
- package/baseline/skill/swift-concurrency/references/testing.md +565 -0
- package/baseline/skill/swift-concurrency/references/threading.md +452 -0
- package/baseline/skill/swiftui-expert-skill/SKILL.md +329 -0
- package/baseline/skill/swiftui-expert-skill/references/animation-advanced.md +351 -0
- package/baseline/skill/swiftui-expert-skill/references/animation-basics.md +284 -0
- package/baseline/skill/swiftui-expert-skill/references/animation-transitions.md +326 -0
- package/baseline/skill/swiftui-expert-skill/references/image-optimization.md +286 -0
- package/baseline/skill/swiftui-expert-skill/references/layout-best-practices.md +312 -0
- package/baseline/skill/swiftui-expert-skill/references/liquid-glass.md +377 -0
- package/baseline/skill/swiftui-expert-skill/references/list-patterns.md +153 -0
- package/baseline/skill/swiftui-expert-skill/references/modern-apis.md +400 -0
- package/baseline/skill/swiftui-expert-skill/references/performance-patterns.md +377 -0
- package/baseline/skill/swiftui-expert-skill/references/scroll-patterns.md +305 -0
- package/baseline/skill/swiftui-expert-skill/references/sheet-navigation-patterns.md +292 -0
- package/baseline/skill/swiftui-expert-skill/references/state-management.md +447 -0
- package/baseline/skill/swiftui-expert-skill/references/text-formatting.md +285 -0
- package/baseline/skill/swiftui-expert-skill/references/view-structure.md +276 -0
- package/baseline/skill/systematic-debugging/SKILL.md +402 -0
- package/baseline/skill/test-driven-development/SKILL.md +388 -0
- package/baseline/skill/testing-anti-patterns/SKILL.md +333 -0
- package/baseline/skill/testing-skills-with-subagents/SKILL.md +405 -0
- package/baseline/skill/tilth-cli/SKILL.md +180 -0
- package/baseline/skill/tool-priority/SKILL.md +299 -0
- package/baseline/skill/ui-ux-research/SKILL.md +9 -0
- package/baseline/skill/using-git-worktrees/SKILL.md +259 -0
- package/baseline/skill/using-skills/SKILL.md +117 -0
- package/baseline/skill/v0/SKILL.md +158 -0
- package/baseline/skill/v1-run/SKILL.md +175 -0
- package/baseline/skill/v1-run/mcp.json +6 -0
- package/baseline/skill/vercel-deploy-claimable/SKILL.md +124 -0
- package/baseline/skill/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/baseline/skill/verification-before-completion/SKILL.md +236 -0
- package/baseline/skill/verification-before-completion/references/VERIFICATION_PROTOCOL.md +171 -0
- package/baseline/skill/visual-analysis/SKILL.md +154 -0
- package/baseline/skill/web-design-guidelines/SKILL.md +46 -0
- package/baseline/skill/writing-plans/SKILL.md +320 -0
- package/baseline/skill/writing-skills/SKILL.md +287 -0
- package/baseline/skill/writing-skills/anthropic-best-practices.md +1173 -0
- package/baseline/skill/writing-skills/graphviz-conventions.dot +172 -0
- package/baseline/skill/writing-skills/persuasion-principles.md +220 -0
- package/baseline/skill/writing-skills/references/anti-patterns.md +25 -0
- package/baseline/skill/writing-skills/references/claude-search-optimization.md +140 -0
- package/baseline/skill/writing-skills/references/discovery-workflow.md +11 -0
- package/baseline/skill/writing-skills/references/file-organization.md +32 -0
- package/baseline/skill/writing-skills/references/flowcharts-and-examples.md +57 -0
- package/baseline/skill/writing-skills/references/rationalization-hardening.md +75 -0
- package/baseline/skill/writing-skills/references/testing-skill-types.md +52 -0
- package/baseline/tool/context7.ts +191 -0
- package/baseline/tool/grepsearch.ts +143 -0
- package/baseline/tsconfig.json +21 -0
- package/baseline/tui.json +15 -0
- package/bin/mrc-opc.mjs +25 -0
- package/bin/ocp.mjs +25 -0
- package/bin/opc.mjs +25 -0
- package/bin/opencode-starterkit.mjs +25 -0
- package/docs/reports/2026-03-18-memory-db-architecture-note.md +47 -0
- package/docs/reports/2026-03-18-vat-opencode-classification-matrix.md +180 -0
- package/package.json +25 -0
- package/src/cli.mjs +41 -0
- package/src/config-merge.mjs +61 -0
- package/src/constants.mjs +58 -0
- package/src/fs-utils.mjs +46 -0
- package/src/install-global.mjs +102 -0
- package/src/install-project.mjs +81 -0
- package/src/memory-bootstrap.mjs +29 -0
- package/src/prompt.mjs +31 -0
- package/src/templates.mjs +31 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
# Actors
|
|
2
|
+
|
|
3
|
+
Data isolation patterns and thread-safe state management in Swift.
|
|
4
|
+
|
|
5
|
+
## What is an Actor?
|
|
6
|
+
|
|
7
|
+
Actors protect mutable state by ensuring only one task accesses it at a time. They're reference types with automatic synchronization.
|
|
8
|
+
|
|
9
|
+
```swift
|
|
10
|
+
actor Counter {
|
|
11
|
+
var value = 0
|
|
12
|
+
|
|
13
|
+
func increment() {
|
|
14
|
+
value += 1
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Key guarantee**: Only one task can access mutable state at a time (serialized access).
|
|
20
|
+
|
|
21
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.1: Understanding actors in Swift Concurrency](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
22
|
+
|
|
23
|
+
## Actor Isolation
|
|
24
|
+
|
|
25
|
+
### Enforced by compiler
|
|
26
|
+
|
|
27
|
+
```swift
|
|
28
|
+
actor BankAccount {
|
|
29
|
+
var balance: Int = 0
|
|
30
|
+
|
|
31
|
+
func deposit(_ amount: Int) {
|
|
32
|
+
balance += amount
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let account = BankAccount()
|
|
37
|
+
account.balance += 1 // ❌ Error: can't mutate from outside
|
|
38
|
+
await account.deposit(1) // ✅ Must use actor's methods
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Reading properties
|
|
42
|
+
|
|
43
|
+
```swift
|
|
44
|
+
let account = BankAccount()
|
|
45
|
+
await account.deposit(100)
|
|
46
|
+
print(await account.balance) // Must await reads too
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Always use `await` when accessing actor properties/methods—you don't know if another task is inside.
|
|
50
|
+
|
|
51
|
+
## Actors vs Classes
|
|
52
|
+
|
|
53
|
+
### Similarities
|
|
54
|
+
|
|
55
|
+
- Reference types (copies share same instance)
|
|
56
|
+
- Can have properties, methods, initializers
|
|
57
|
+
- Can conform to protocols
|
|
58
|
+
|
|
59
|
+
### Differences
|
|
60
|
+
|
|
61
|
+
- **No inheritance** (except `NSObject` for Objective-C interop)
|
|
62
|
+
- **Automatic isolation** (no manual locks needed)
|
|
63
|
+
- **Implicit Sendable** conformance
|
|
64
|
+
|
|
65
|
+
```swift
|
|
66
|
+
// ❌ Can't inherit from actors
|
|
67
|
+
actor Base {}
|
|
68
|
+
actor Child: Base {} // Error
|
|
69
|
+
|
|
70
|
+
// ✅ NSObject exception
|
|
71
|
+
actor Example: NSObject {} // OK for Objective-C
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Global Actors
|
|
75
|
+
|
|
76
|
+
Shared isolation domain across types, functions, and properties.
|
|
77
|
+
|
|
78
|
+
### @MainActor
|
|
79
|
+
|
|
80
|
+
Ensures execution on main thread:
|
|
81
|
+
|
|
82
|
+
```swift
|
|
83
|
+
@MainActor
|
|
84
|
+
final class ViewModel {
|
|
85
|
+
var items: [Item] = []
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@MainActor
|
|
89
|
+
func updateUI() {
|
|
90
|
+
// Always runs on main thread
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@MainActor
|
|
94
|
+
var title: String = ""
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Custom global actors
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
@globalActor
|
|
101
|
+
actor ImageProcessing {
|
|
102
|
+
static let shared = ImageProcessing()
|
|
103
|
+
private init() {} // Prevent duplicate instances
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@ImageProcessing
|
|
107
|
+
final class ImageCache {
|
|
108
|
+
var images: [URL: Data] = [:]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@ImageProcessing
|
|
112
|
+
func applyFilter(_ image: UIImage) -> UIImage {
|
|
113
|
+
// All image processing serialized
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Use private init** to prevent creating multiple executors.
|
|
118
|
+
|
|
119
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.2: An introduction to Global Actors](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
120
|
+
|
|
121
|
+
## @MainActor Best Practices
|
|
122
|
+
|
|
123
|
+
### When to use
|
|
124
|
+
|
|
125
|
+
UI-related code that must run on main thread:
|
|
126
|
+
|
|
127
|
+
```swift
|
|
128
|
+
@MainActor
|
|
129
|
+
final class ContentViewModel: ObservableObject {
|
|
130
|
+
@Published var items: [Item] = []
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Replacing DispatchQueue.main
|
|
135
|
+
|
|
136
|
+
```swift
|
|
137
|
+
// Old way
|
|
138
|
+
DispatchQueue.main.async {
|
|
139
|
+
// Update UI
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Modern way
|
|
143
|
+
await MainActor.run {
|
|
144
|
+
// Update UI
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Better: Use attribute
|
|
148
|
+
@MainActor
|
|
149
|
+
func updateUI() {
|
|
150
|
+
// Automatically on main thread
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### MainActor.assumeIsolated
|
|
155
|
+
|
|
156
|
+
**Use sparingly** - assumes you're on main thread, crashes if not:
|
|
157
|
+
|
|
158
|
+
```swift
|
|
159
|
+
func methodB() {
|
|
160
|
+
assert(Thread.isMainThread) // Validate assumption
|
|
161
|
+
|
|
162
|
+
MainActor.assumeIsolated {
|
|
163
|
+
someMainActorMethod()
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Prefer**: Explicit `@MainActor` or `await MainActor.run` over `assumeIsolated`.
|
|
169
|
+
|
|
170
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.3: When and how to use @MainActor](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
171
|
+
|
|
172
|
+
## Isolated vs Nonisolated
|
|
173
|
+
|
|
174
|
+
### Default: Isolated
|
|
175
|
+
|
|
176
|
+
Actor methods are isolated by default:
|
|
177
|
+
|
|
178
|
+
```swift
|
|
179
|
+
actor BankAccount {
|
|
180
|
+
var balance: Double
|
|
181
|
+
|
|
182
|
+
// Implicitly isolated
|
|
183
|
+
func deposit(_ amount: Double) {
|
|
184
|
+
balance += amount
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Isolated parameters
|
|
190
|
+
|
|
191
|
+
Reduce suspension points by inheriting caller's isolation:
|
|
192
|
+
|
|
193
|
+
```swift
|
|
194
|
+
struct Charger {
|
|
195
|
+
static func charge(
|
|
196
|
+
amount: Double,
|
|
197
|
+
from account: isolated BankAccount
|
|
198
|
+
) async throws -> Double {
|
|
199
|
+
// No await needed - we're isolated to account
|
|
200
|
+
try account.withdraw(amount: amount)
|
|
201
|
+
return account.balance
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Isolated closures
|
|
207
|
+
|
|
208
|
+
```swift
|
|
209
|
+
actor Database {
|
|
210
|
+
func transaction<T>(
|
|
211
|
+
_ operation: @Sendable (_ db: isolated Database) throws -> T
|
|
212
|
+
) throws -> T {
|
|
213
|
+
beginTransaction()
|
|
214
|
+
let result = try operation(self)
|
|
215
|
+
commitTransaction()
|
|
216
|
+
return result
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Usage: Multiple operations, one await
|
|
221
|
+
try await database.transaction { db in
|
|
222
|
+
db.insert(item1)
|
|
223
|
+
db.insert(item2)
|
|
224
|
+
db.insert(item3)
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Generic isolated extension
|
|
229
|
+
|
|
230
|
+
```swift
|
|
231
|
+
extension Actor {
|
|
232
|
+
func performInIsolation<T: Sendable>(
|
|
233
|
+
_ block: @Sendable (_ actor: isolated Self) throws -> T
|
|
234
|
+
) async rethrows -> T {
|
|
235
|
+
try block(self)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Usage
|
|
240
|
+
try await bankAccount.performInIsolation { account in
|
|
241
|
+
try account.withdraw(amount: 20)
|
|
242
|
+
print("Balance: \(account.balance)")
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Nonisolated
|
|
247
|
+
|
|
248
|
+
Opt out of isolation for immutable data:
|
|
249
|
+
|
|
250
|
+
```swift
|
|
251
|
+
actor BankAccount {
|
|
252
|
+
let accountHolder: String
|
|
253
|
+
|
|
254
|
+
nonisolated var details: String {
|
|
255
|
+
"Account: \(accountHolder)"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// No await needed
|
|
260
|
+
print(account.details)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Protocol conformance
|
|
264
|
+
|
|
265
|
+
```swift
|
|
266
|
+
extension BankAccount: CustomStringConvertible {
|
|
267
|
+
nonisolated var description: String {
|
|
268
|
+
"Account: \(accountHolder)"
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.4: Isolated vs. non-isolated access in actors](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
274
|
+
|
|
275
|
+
## Isolated Deinit (Swift 6.2+)
|
|
276
|
+
|
|
277
|
+
Clean up actor state on deallocation:
|
|
278
|
+
|
|
279
|
+
```swift
|
|
280
|
+
actor FileDownloader {
|
|
281
|
+
var downloadTask: Task<Void, Error>?
|
|
282
|
+
|
|
283
|
+
isolated deinit {
|
|
284
|
+
downloadTask?.cancel() // Can call isolated methods
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Requires**: iOS 18.4+, macOS 15.4+
|
|
290
|
+
|
|
291
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.5: Using Isolated synchronous deinit](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
292
|
+
|
|
293
|
+
## Global Actor Isolated Conformance (Swift 6.2+)
|
|
294
|
+
|
|
295
|
+
Protocol conformance respecting actor isolation:
|
|
296
|
+
|
|
297
|
+
```swift
|
|
298
|
+
@MainActor
|
|
299
|
+
final class PersonViewModel {
|
|
300
|
+
let id: UUID
|
|
301
|
+
var name: String
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
extension PersonViewModel: @MainActor Equatable {
|
|
305
|
+
static func == (lhs: PersonViewModel, rhs: PersonViewModel) -> Bool {
|
|
306
|
+
lhs.id == rhs.id && lhs.name == rhs.name
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Enable**: `InferIsolatedConformances` upcoming feature.
|
|
312
|
+
|
|
313
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.6: Adding isolated conformance to protocols](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
314
|
+
|
|
315
|
+
## Actor Reentrancy
|
|
316
|
+
|
|
317
|
+
**Critical**: State can change between suspension points.
|
|
318
|
+
|
|
319
|
+
```swift
|
|
320
|
+
actor BankAccount {
|
|
321
|
+
var balance: Double
|
|
322
|
+
|
|
323
|
+
func deposit(amount: Double) async {
|
|
324
|
+
balance += amount
|
|
325
|
+
|
|
326
|
+
// ⚠️ Actor unlocked during await
|
|
327
|
+
await logActivity("Deposited \(amount)")
|
|
328
|
+
|
|
329
|
+
// ⚠️ Balance may have changed!
|
|
330
|
+
print("Balance: \(balance)")
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Problem
|
|
336
|
+
|
|
337
|
+
```swift
|
|
338
|
+
async let _ = account.deposit(50)
|
|
339
|
+
async let _ = account.deposit(50)
|
|
340
|
+
async let _ = account.deposit(50)
|
|
341
|
+
|
|
342
|
+
// May print same balance three times:
|
|
343
|
+
// Balance: 150
|
|
344
|
+
// Balance: 150
|
|
345
|
+
// Balance: 150
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Solution
|
|
349
|
+
|
|
350
|
+
Complete actor work before suspending:
|
|
351
|
+
|
|
352
|
+
```swift
|
|
353
|
+
func deposit(amount: Double) async {
|
|
354
|
+
balance += amount
|
|
355
|
+
print("Balance: \(balance)") // Before suspension
|
|
356
|
+
|
|
357
|
+
await logActivity("Deposited \(amount)")
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Rule**: Don't assume state is unchanged after `await`.
|
|
362
|
+
|
|
363
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.7: Understanding actor reentrancy](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
364
|
+
|
|
365
|
+
## #isolation Macro
|
|
366
|
+
|
|
367
|
+
Inherit caller's isolation for generic code:
|
|
368
|
+
|
|
369
|
+
```swift
|
|
370
|
+
extension Collection where Element: Sendable {
|
|
371
|
+
func sequentialMap<Result: Sendable>(
|
|
372
|
+
isolation: isolated (any Actor)? = #isolation,
|
|
373
|
+
transform: (Element) async -> Result
|
|
374
|
+
) async -> [Result] {
|
|
375
|
+
var results: [Result] = []
|
|
376
|
+
for element in self {
|
|
377
|
+
results.append(await transform(element))
|
|
378
|
+
}
|
|
379
|
+
return results
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Usage from @MainActor context
|
|
384
|
+
Task { @MainActor in
|
|
385
|
+
let names = ["Alice", "Bob"]
|
|
386
|
+
let results = await names.sequentialMap { name in
|
|
387
|
+
await process(name) // Inherits @MainActor
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Benefits**: Avoids unnecessary suspensions, allows non-Sendable data.
|
|
393
|
+
|
|
394
|
+
### Task Closures and Isolation Inheritance
|
|
395
|
+
|
|
396
|
+
When spawning unstructured `Task` closures that need to work with `non-Sendable` types, you must capture the isolation parameter to inherit the caller's isolation context.
|
|
397
|
+
|
|
398
|
+
**Problem**: `Task` closures are `@Sendable`, which prevents capturing `non-Sendable` types:
|
|
399
|
+
|
|
400
|
+
```swift
|
|
401
|
+
func process(delegate: NonSendableDelegate) {
|
|
402
|
+
Task {
|
|
403
|
+
delegate.doWork() // ❌ Error: capturing non-Sendable type
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Solution**: Use `#isolation` parameter and capture it inside the `Task`:
|
|
409
|
+
|
|
410
|
+
```swift
|
|
411
|
+
func process(
|
|
412
|
+
delegate: NonSendableDelegate,
|
|
413
|
+
isolation: isolated (any Actor)? = #isolation
|
|
414
|
+
) {
|
|
415
|
+
Task {
|
|
416
|
+
_ = isolation // Forces capture, Task inherits caller's isolation
|
|
417
|
+
delegate.doWork() // ✅ Safe - running on caller's actor
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Why `_ = isolation` is required**: Per [SE-0420](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0420-inheritance-of-actor-isolation.md), `Task` closures only inherit isolation when "a non-optional binding of an isolated parameter is captured by the closure." The `_ = isolation` statement forces this capture. The capture list syntax `[isolation]` should work but currently does not.
|
|
423
|
+
|
|
424
|
+
**When to use this pattern**:
|
|
425
|
+
- Spawning `Task`s that work with `non-Sendable` delegate objects
|
|
426
|
+
- Fire-and-forget async work that needs access to caller's state
|
|
427
|
+
- Bridging callback-based APIs to async streams while keeping delegates alive
|
|
428
|
+
|
|
429
|
+
**Note**: This pattern keeps the `non-Sendable` value alive and accessible within the `Task`. The `Task` runs on the caller's isolation domain, so no cross-isolation "sending" occurs.
|
|
430
|
+
|
|
431
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.8: Inheritance of actor isolation using the #isolation macro](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
432
|
+
|
|
433
|
+
## Custom Actor Executors
|
|
434
|
+
|
|
435
|
+
**Advanced**: Control how actor schedules work.
|
|
436
|
+
|
|
437
|
+
### Serial executor
|
|
438
|
+
|
|
439
|
+
```swift
|
|
440
|
+
final class DispatchQueueExecutor: SerialExecutor {
|
|
441
|
+
private let queue: DispatchQueue
|
|
442
|
+
|
|
443
|
+
init(queue: DispatchQueue) {
|
|
444
|
+
self.queue = queue
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
func enqueue(_ job: consuming ExecutorJob) {
|
|
448
|
+
let unownedJob = UnownedJob(job)
|
|
449
|
+
let executor = asUnownedSerialExecutor()
|
|
450
|
+
|
|
451
|
+
queue.async {
|
|
452
|
+
unownedJob.runSynchronously(on: executor)
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
actor LoggingActor {
|
|
458
|
+
private let executor: DispatchQueueExecutor
|
|
459
|
+
|
|
460
|
+
nonisolated var unownedExecutor: UnownedSerialExecutor {
|
|
461
|
+
executor.asUnownedSerialExecutor()
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
init(queue: DispatchQueue) {
|
|
465
|
+
executor = DispatchQueueExecutor(queue: queue)
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### When to use
|
|
471
|
+
|
|
472
|
+
- Integration with legacy DispatchQueue-based code
|
|
473
|
+
- Specific thread requirements (e.g., C++ interop)
|
|
474
|
+
- Custom scheduling logic
|
|
475
|
+
|
|
476
|
+
**Default executor is usually sufficient.**
|
|
477
|
+
|
|
478
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.9: Using a custom actor executor](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
479
|
+
|
|
480
|
+
## Mutex: Alternative to Actors
|
|
481
|
+
|
|
482
|
+
Synchronous locking without async/await overhead (iOS 18+, macOS 15+).
|
|
483
|
+
|
|
484
|
+
### Basic usage
|
|
485
|
+
|
|
486
|
+
```swift
|
|
487
|
+
import Synchronization
|
|
488
|
+
|
|
489
|
+
final class Counter {
|
|
490
|
+
private let count = Mutex<Int>(0)
|
|
491
|
+
|
|
492
|
+
var currentCount: Int {
|
|
493
|
+
count.withLock { $0 }
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
func increment() {
|
|
497
|
+
count.withLock { $0 += 1 }
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Sendable access to non-Sendable types
|
|
503
|
+
|
|
504
|
+
```swift
|
|
505
|
+
final class TouchesCapturer: Sendable {
|
|
506
|
+
let path = Mutex<NSBezierPath>(NSBezierPath())
|
|
507
|
+
|
|
508
|
+
func storeTouch(_ point: NSPoint) {
|
|
509
|
+
path.withLock { path in
|
|
510
|
+
path.move(to: point)
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Error handling
|
|
517
|
+
|
|
518
|
+
```swift
|
|
519
|
+
func decrement() throws {
|
|
520
|
+
try count.withLock { count in
|
|
521
|
+
guard count > 0 else {
|
|
522
|
+
throw Error.reachedZero
|
|
523
|
+
}
|
|
524
|
+
count -= 1
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### Mutex vs Actor
|
|
530
|
+
|
|
531
|
+
| Feature | Mutex | Actor |
|
|
532
|
+
|---------|-------|-------|
|
|
533
|
+
| Synchronous | ✅ | ❌ (requires await) |
|
|
534
|
+
| Async support | ❌ | ✅ |
|
|
535
|
+
| Thread blocking | ✅ | ❌ (cooperative) |
|
|
536
|
+
| Fine-grained locking | ✅ | ❌ (whole actor) |
|
|
537
|
+
| Legacy code integration | ✅ | ❌ |
|
|
538
|
+
|
|
539
|
+
**Use Mutex when**:
|
|
540
|
+
- Need synchronous access
|
|
541
|
+
- Working with legacy non-async APIs
|
|
542
|
+
- Fine-grained locking required
|
|
543
|
+
- Low contention, short critical sections
|
|
544
|
+
|
|
545
|
+
**Use Actor when**:
|
|
546
|
+
- Can adopt async/await
|
|
547
|
+
- Need logical isolation
|
|
548
|
+
- Working in async context
|
|
549
|
+
|
|
550
|
+
> **Course Deep Dive**: This topic is covered in detail in [Lesson 5.10: Using a Mutex as an alternative to actors](https://www.swiftconcurrencycourse.com?utm_source=github&utm_medium=agent-skill&utm_campaign=lesson-reference)
|
|
551
|
+
|
|
552
|
+
## Common Patterns
|
|
553
|
+
|
|
554
|
+
### View model with @MainActor
|
|
555
|
+
|
|
556
|
+
```swift
|
|
557
|
+
@MainActor
|
|
558
|
+
final class ContentViewModel: ObservableObject {
|
|
559
|
+
@Published var items: [Item] = []
|
|
560
|
+
|
|
561
|
+
func loadItems() async {
|
|
562
|
+
items = try await api.fetchItems()
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Background processing with custom actor
|
|
568
|
+
|
|
569
|
+
```swift
|
|
570
|
+
@ImageProcessing
|
|
571
|
+
final class ImageProcessor {
|
|
572
|
+
func process(_ images: [UIImage]) async -> [UIImage] {
|
|
573
|
+
images.map { applyFilters($0) }
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Mixed isolation
|
|
579
|
+
|
|
580
|
+
```swift
|
|
581
|
+
actor DataStore {
|
|
582
|
+
private var items: [Item] = []
|
|
583
|
+
|
|
584
|
+
func add(_ item: Item) {
|
|
585
|
+
items.append(item)
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
nonisolated func itemCount() -> Int {
|
|
589
|
+
// ❌ Can't access items
|
|
590
|
+
return 0
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Transaction pattern
|
|
596
|
+
|
|
597
|
+
```swift
|
|
598
|
+
actor Database {
|
|
599
|
+
func transaction<T>(
|
|
600
|
+
_ operation: @Sendable (_ db: isolated Database) throws -> T
|
|
601
|
+
) throws -> T {
|
|
602
|
+
beginTransaction()
|
|
603
|
+
defer { commitTransaction() }
|
|
604
|
+
return try operation(self)
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
## Best Practices
|
|
610
|
+
|
|
611
|
+
1. **Prefer actors over manual locks** for async code
|
|
612
|
+
2. **Use @MainActor for UI** - all view models, UI updates
|
|
613
|
+
3. **Minimize work in actors** - keep critical sections short
|
|
614
|
+
4. **Watch for reentrancy** - don't assume state unchanged after await
|
|
615
|
+
5. **Use nonisolated sparingly** - only for truly immutable data
|
|
616
|
+
6. **Avoid assumeIsolated** - prefer explicit isolation
|
|
617
|
+
7. **Custom executors are rare** - default is usually best
|
|
618
|
+
8. **Consider Mutex for sync code** - when async overhead not needed
|
|
619
|
+
9. **Complete actor work before suspending** - prevent reentrancy bugs
|
|
620
|
+
10. **Use isolated parameters** - reduce suspension points
|
|
621
|
+
|
|
622
|
+
## Decision Tree
|
|
623
|
+
|
|
624
|
+
```
|
|
625
|
+
Need thread-safe mutable state?
|
|
626
|
+
├─ Async context?
|
|
627
|
+
│ ├─ Single instance? → Actor
|
|
628
|
+
│ ├─ Global/shared? → Global Actor (@MainActor, custom)
|
|
629
|
+
│ └─ UI-related? → @MainActor
|
|
630
|
+
│
|
|
631
|
+
└─ Synchronous context?
|
|
632
|
+
├─ Can refactor to async? → Actor
|
|
633
|
+
├─ Legacy code integration? → Mutex
|
|
634
|
+
└─ Fine-grained locking? → Mutex
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
## Further Learning
|
|
638
|
+
|
|
639
|
+
For migration strategies, advanced patterns, and real-world examples, see [Swift Concurrency Course](https://www.swiftconcurrencycourse.com).
|
|
640
|
+
|