@heyai-rules/pilo-masterkit 1.2.2 → 3.1.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/.agent/agents/architect.md +211 -211
- package/.agent/agents/build-error-resolver.md +114 -114
- package/.agent/agents/chief-of-staff.md +151 -151
- package/.agent/agents/code-reviewer.md +237 -237
- package/.agent/agents/cpp-build-resolver.md +90 -90
- package/.agent/agents/cpp-reviewer.md +72 -72
- package/.agent/agents/csharp-reviewer.md +101 -0
- package/.agent/agents/dart-build-resolver.md +201 -0
- package/.agent/agents/database-reviewer.md +91 -91
- package/.agent/agents/doc-updater.md +107 -107
- package/.agent/agents/docs-lookup.md +68 -68
- package/.agent/agents/e2e-runner.md +107 -107
- package/.agent/agents/flutter-reviewer.md +243 -243
- package/.agent/agents/gan-evaluator.md +209 -0
- package/.agent/agents/gan-generator.md +131 -0
- package/.agent/agents/gan-planner.md +99 -0
- package/.agent/agents/go-build-resolver.md +94 -94
- package/.agent/agents/go-reviewer.md +76 -76
- package/.agent/agents/harness-optimizer.md +35 -35
- package/.agent/agents/healthcare-reviewer.md +83 -0
- package/.agent/agents/java-build-resolver.md +153 -153
- package/.agent/agents/java-reviewer.md +92 -92
- package/.agent/agents/kotlin-build-resolver.md +118 -118
- package/.agent/agents/kotlin-reviewer.md +159 -159
- package/.agent/agents/loop-operator.md +36 -36
- package/.agent/agents/opensource-forker.md +198 -0
- package/.agent/agents/opensource-packager.md +249 -0
- package/.agent/agents/opensource-sanitizer.md +188 -0
- package/.agent/agents/performance-optimizer.md +392 -133
- package/.agent/agents/personas/athena-agent/agent.json +10 -0
- package/.agent/agents/personas/athena-agent/athena-backend-logic-architecture-profile.md +189 -0
- package/.agent/agents/personas/athena-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/athena-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/athena-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/athena-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/athena-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/athena-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/da-vinci-agent/agent.json +10 -0
- package/.agent/agents/personas/da-vinci-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/da-vinci-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/da-vinci-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/da-vinci-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/da-vinci-agent/da-vinci-frontend-ui-ux-design-profile.md +189 -0
- package/.agent/agents/personas/da-vinci-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/da-vinci-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/duong-tang-agent/agent.json +10 -0
- package/.agent/agents/personas/duong-tang-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/duong-tang-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/duong-tang-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/duong-tang-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/duong-tang-agent/tang-monk-quality-testing-documentation-profile.md +189 -0
- package/.agent/agents/personas/duong-tang-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/duong-tang-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/gia-cat-luong-agent/agent.json +10 -0
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/gia-cat-luong-agent/kongming-research-strategy-analysis-profile.md +189 -0
- package/.agent/agents/personas/gia-cat-luong-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/gia-cat-luong-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/mihata-agent/agent.json +10 -0
- package/.agent/agents/personas/mihata-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/mihata-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/mihata-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/mihata-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/mihata-agent/mihata-multi-agent-orchestration-profile.md +189 -0
- package/.agent/agents/personas/mihata-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/mihata-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/tesla-agent/agent.json +10 -0
- package/.agent/agents/personas/tesla-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/tesla-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/tesla-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/tesla-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/tesla-agent/tesla-fullstack-system-optimization-profile.md +189 -0
- package/.agent/agents/personas/tesla-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/tesla-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/tu-ma-y-agent/agent.json +10 -0
- package/.agent/agents/personas/tu-ma-y-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/tu-ma-y-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/tu-ma-y-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/tu-ma-y-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/tu-ma-y-agent/simayi-feasibility-risk-control-profile.md +189 -0
- package/.agent/agents/personas/tu-ma-y-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/tu-ma-y-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/venti-agent/agent.json +10 -0
- package/.agent/agents/personas/venti-agent/context-files/agents.md +55 -0
- package/.agent/agents/personas/venti-agent/context-files/identity.md +23 -0
- package/.agent/agents/personas/venti-agent/context-files/soul.md +51 -0
- package/.agent/agents/personas/venti-agent/context-files/user-predefined.md +15 -0
- package/.agent/agents/personas/venti-agent/user-context-files/system/bootstrap.md +37 -0
- package/.agent/agents/personas/venti-agent/user-context-files/system/user.md +45 -0
- package/.agent/agents/personas/venti-agent/venti-learning-communication-mentoring-profile.md +189 -0
- package/.agent/agents/planner.md +212 -212
- package/.agent/agents/python-reviewer.md +98 -98
- package/.agent/agents/pytorch-build-resolver.md +120 -120
- package/.agent/agents/refactor-cleaner.md +85 -85
- package/.agent/agents/rust-build-resolver.md +148 -148
- package/.agent/agents/rust-reviewer.md +94 -94
- package/.agent/agents/security-reviewer.md +108 -108
- package/.agent/agents/tdd-guide.md +91 -91
- package/.agent/agents/typescript-reviewer.md +112 -112
- package/.agent/contexts/dev.md +20 -0
- package/.agent/contexts/research.md +26 -0
- package/.agent/contexts/review.md +22 -0
- package/.agent/hooks/hooks.json +395 -0
- package/.agent/hooks/readme.md +222 -0
- package/.agent/mcp-configs/mcp-servers.json +181 -0
- package/.agent/rules/common/agents.md +50 -0
- package/.agent/rules/common/code-review.md +124 -0
- package/.agent/rules/common/coding-style.md +48 -0
- package/.agent/rules/common/development-workflow.md +44 -0
- package/.agent/rules/common/git-workflow.md +24 -0
- package/.agent/rules/common/hooks.md +30 -0
- package/.agent/rules/common/patterns.md +31 -0
- package/.agent/rules/common/performance.md +55 -0
- package/.agent/rules/common/security.md +29 -0
- package/.agent/rules/common/testing.md +29 -0
- package/.agent/rules/cpp/coding-style.md +44 -0
- package/.agent/rules/cpp/hooks.md +39 -0
- package/.agent/rules/cpp/patterns.md +51 -0
- package/.agent/rules/cpp/security.md +51 -0
- package/.agent/rules/cpp/testing.md +44 -0
- package/.agent/rules/csharp/coding-style.md +72 -0
- package/.agent/rules/csharp/hooks.md +25 -0
- package/.agent/rules/csharp/patterns.md +50 -0
- package/.agent/rules/csharp/security.md +58 -0
- package/.agent/rules/csharp/testing.md +46 -0
- package/.agent/rules/dart/coding-style.md +159 -0
- package/.agent/rules/dart/hooks.md +66 -0
- package/.agent/rules/dart/patterns.md +261 -0
- package/.agent/rules/dart/security.md +135 -0
- package/.agent/rules/dart/testing.md +215 -0
- package/.agent/rules/golang/coding-style.md +32 -0
- package/.agent/rules/golang/hooks.md +17 -0
- package/.agent/rules/golang/patterns.md +45 -0
- package/.agent/rules/golang/security.md +34 -0
- package/.agent/rules/golang/testing.md +31 -0
- package/.agent/rules/java/coding-style.md +114 -0
- package/.agent/rules/java/hooks.md +18 -0
- package/.agent/rules/java/patterns.md +146 -0
- package/.agent/rules/java/security.md +100 -0
- package/.agent/rules/java/testing.md +131 -0
- package/.agent/rules/kotlin/coding-style.md +86 -0
- package/.agent/rules/kotlin/hooks.md +17 -0
- package/.agent/rules/kotlin/patterns.md +146 -0
- package/.agent/rules/kotlin/security.md +82 -0
- package/.agent/rules/kotlin/testing.md +128 -0
- package/.agent/rules/perl/coding-style.md +46 -0
- package/.agent/rules/perl/hooks.md +22 -0
- package/.agent/rules/perl/patterns.md +76 -0
- package/.agent/rules/perl/security.md +69 -0
- package/.agent/rules/perl/testing.md +54 -0
- package/.agent/rules/php/coding-style.md +40 -0
- package/.agent/rules/php/hooks.md +24 -0
- package/.agent/rules/php/patterns.md +33 -0
- package/.agent/rules/php/security.md +37 -0
- package/.agent/rules/php/testing.md +39 -0
- package/.agent/rules/python/coding-style.md +42 -0
- package/.agent/rules/python/hooks.md +19 -0
- package/.agent/rules/python/patterns.md +39 -0
- package/.agent/rules/python/security.md +30 -0
- package/.agent/rules/python/testing.md +38 -0
- package/.agent/rules/readme.md +111 -0
- package/.agent/rules/rust/coding-style.md +151 -0
- package/.agent/rules/rust/hooks.md +16 -0
- package/.agent/rules/rust/patterns.md +168 -0
- package/.agent/rules/rust/security.md +141 -0
- package/.agent/rules/rust/testing.md +154 -0
- package/.agent/rules/swift/coding-style.md +47 -0
- package/.agent/rules/swift/hooks.md +20 -0
- package/.agent/rules/swift/patterns.md +66 -0
- package/.agent/rules/swift/security.md +33 -0
- package/.agent/rules/swift/testing.md +45 -0
- package/.agent/rules/typescript/coding-style.md +199 -0
- package/.agent/rules/typescript/hooks.md +22 -0
- package/.agent/rules/typescript/patterns.md +52 -0
- package/.agent/rules/typescript/security.md +28 -0
- package/.agent/rules/typescript/testing.md +18 -0
- package/.agent/rules/web/coding-style.md +96 -0
- package/.agent/rules/web/design-quality.md +63 -0
- package/.agent/rules/web/hooks.md +120 -0
- package/.agent/rules/web/patterns.md +79 -0
- package/.agent/rules/web/performance.md +64 -0
- package/.agent/rules/web/security.md +57 -0
- package/.agent/rules/web/testing.md +55 -0
- package/.agent/rules/zh/agents.md +50 -0
- package/.agent/rules/zh/code-review.md +124 -0
- package/.agent/rules/zh/coding-style.md +48 -0
- package/.agent/rules/zh/development-workflow.md +44 -0
- package/.agent/rules/zh/git-workflow.md +24 -0
- package/.agent/rules/zh/hooks.md +30 -0
- package/.agent/rules/zh/patterns.md +31 -0
- package/.agent/rules/zh/performance.md +55 -0
- package/.agent/rules/zh/readme.md +108 -0
- package/.agent/rules/zh/security.md +29 -0
- package/.agent/rules/zh/testing.md +29 -0
- package/.agent/skills/agent-eval/SKILL.md +145 -0
- package/.agent/skills/agent-harness-construction/SKILL.md +73 -0
- package/.agent/skills/agent-payment-x402/SKILL.md +178 -0
- package/.agent/skills/agentic-engineering/SKILL.md +63 -0
- package/.agent/skills/ai-first-engineering/SKILL.md +51 -0
- package/.agent/skills/ai-regression-testing/SKILL.md +385 -0
- package/.agent/skills/android-clean-architecture/SKILL.md +339 -0
- package/.agent/skills/api-design/SKILL.md +523 -0
- package/.agent/skills/architecture-decision-records/SKILL.md +179 -0
- package/.agent/skills/article-writing/SKILL.md +79 -0
- package/.agent/skills/autonomous-agent-harness/SKILL.md +267 -0
- package/.agent/skills/autonomous-loops/SKILL.md +610 -0
- package/.agent/skills/backend-patterns/SKILL.md +598 -0
- package/.agent/skills/benchmark/SKILL.md +93 -0
- package/.agent/skills/blueprint/SKILL.md +105 -0
- package/.agent/skills/brand-voice/SKILL.md +97 -0
- package/.agent/skills/brand-voice/references/voice-profile-schema.md +55 -0
- package/.agent/skills/browser-qa/SKILL.md +87 -0
- package/.agent/skills/bun-runtime/SKILL.md +84 -0
- package/.agent/skills/canary-watch/SKILL.md +99 -0
- package/.agent/skills/carrier-relationship-management/SKILL.md +212 -0
- package/.agent/skills/ck/SKILL.md +147 -0
- package/.agent/skills/ck/commands/forget.mjs +44 -0
- package/.agent/skills/ck/commands/info.mjs +24 -0
- package/.agent/skills/ck/commands/init.mjs +143 -0
- package/.agent/skills/ck/commands/list.mjs +40 -0
- package/.agent/skills/ck/commands/migrate.mjs +202 -0
- package/.agent/skills/ck/commands/resume.mjs +36 -0
- package/.agent/skills/ck/commands/save.mjs +210 -0
- package/.agent/skills/ck/commands/shared.mjs +387 -0
- package/.agent/skills/ck/hooks/session-start.mjs +224 -0
- package/.agent/skills/claude-api/SKILL.md +337 -0
- package/.agent/skills/claude-devfleet/SKILL.md +103 -0
- package/.agent/skills/click-path-audit/SKILL.md +244 -0
- package/.agent/skills/clickhouse-io/SKILL.md +439 -0
- package/.agent/skills/codebase-onboarding/SKILL.md +233 -0
- package/.agent/skills/coding-standards/SKILL.md +530 -0
- package/.agent/skills/compose-multiplatform-patterns/SKILL.md +299 -0
- package/.agent/skills/configure-ecc/SKILL.md +367 -0
- package/.agent/skills/connections-optimizer/SKILL.md +189 -0
- package/.agent/skills/content-engine/SKILL.md +131 -0
- package/.agent/skills/content-hash-cache-pattern/SKILL.md +161 -0
- package/.agent/skills/context-budget/SKILL.md +135 -0
- package/.agent/skills/continuous-agent-loop/SKILL.md +45 -0
- package/.agent/skills/continuous-learning/SKILL.md +119 -0
- package/.agent/skills/continuous-learning/config.json +18 -0
- package/.agent/skills/continuous-learning/evaluate-session.sh +69 -0
- package/.agent/skills/continuous-learning-v2/SKILL.md +365 -0
- package/.agent/skills/continuous-learning-v2/agents/observer-loop.sh +271 -0
- package/.agent/skills/continuous-learning-v2/agents/observer.md +198 -0
- package/.agent/skills/continuous-learning-v2/agents/session-guardian.sh +150 -0
- package/.agent/skills/continuous-learning-v2/agents/start-observer.sh +244 -0
- package/.agent/skills/continuous-learning-v2/config.json +8 -0
- package/.agent/skills/continuous-learning-v2/hooks/observe.sh +428 -0
- package/.agent/skills/continuous-learning-v2/scripts/detect-project.sh +228 -0
- package/.agent/skills/continuous-learning-v2/scripts/instinct-cli.py +1426 -0
- package/.agent/skills/continuous-learning-v2/scripts/test-parse-instinct.py +984 -0
- package/.agent/skills/cost-aware-llm-pipeline/SKILL.md +183 -0
- package/.agent/skills/cpp-coding-standards/SKILL.md +723 -0
- package/.agent/skills/cpp-testing/SKILL.md +324 -0
- package/.agent/skills/crosspost/SKILL.md +111 -0
- package/.agent/skills/csharp-testing/SKILL.md +321 -0
- package/.agent/skills/customer-billing-ops/SKILL.md +140 -0
- package/.agent/skills/customs-trade-compliance/SKILL.md +263 -0
- package/.agent/skills/dart-flutter-patterns/SKILL.md +563 -0
- package/.agent/skills/data-scraper-agent/SKILL.md +764 -0
- package/.agent/skills/database-migrations/SKILL.md +429 -0
- package/.agent/skills/deep-research/SKILL.md +155 -0
- package/.agent/skills/deployment-patterns/SKILL.md +427 -0
- package/.agent/skills/design-system/SKILL.md +82 -0
- package/.agent/skills/django-patterns/SKILL.md +734 -0
- package/.agent/skills/django-security/SKILL.md +593 -0
- package/.agent/skills/django-tdd/SKILL.md +729 -0
- package/.agent/skills/django-verification/SKILL.md +469 -0
- package/.agent/skills/dmux-workflows/SKILL.md +191 -0
- package/.agent/skills/docker-patterns/SKILL.md +364 -0
- package/.agent/skills/documentation-lookup/SKILL.md +90 -0
- package/.agent/skills/dotnet-patterns/SKILL.md +321 -0
- package/.agent/skills/e2e-testing/SKILL.md +326 -0
- package/.agent/skills/energy-procurement/SKILL.md +228 -0
- package/.agent/skills/enterprise-agent-ops/SKILL.md +50 -0
- package/.agent/skills/eval-harness/SKILL.md +270 -0
- package/.agent/skills/exa-search/SKILL.md +103 -0
- package/.agent/skills/fal-ai-media/SKILL.md +284 -0
- package/.agent/skills/flutter-dart-code-review/SKILL.md +435 -0
- package/.agent/skills/foundation-models-on-device/SKILL.md +243 -0
- package/.agent/skills/frontend-patterns/SKILL.md +642 -0
- package/.agent/skills/frontend-slides/SKILL.md +184 -0
- package/.agent/skills/frontend-slides/style-presets.md +330 -0
- package/.agent/skills/gan-style-harness/SKILL.md +278 -0
- package/.agent/skills/git-workflow/SKILL.md +715 -0
- package/.agent/skills/golang-patterns/SKILL.md +674 -0
- package/.agent/skills/golang-testing/SKILL.md +720 -0
- package/.agent/skills/google-workspace-ops/SKILL.md +95 -0
- package/.agent/skills/healthcare-cdss-patterns/SKILL.md +245 -0
- package/.agent/skills/healthcare-emr-patterns/SKILL.md +159 -0
- package/.agent/skills/healthcare-eval-harness/SKILL.md +207 -0
- package/.agent/skills/healthcare-phi-compliance/SKILL.md +145 -0
- package/.agent/skills/hexagonal-architecture/SKILL.md +276 -0
- package/.agent/skills/inventory-demand-planning/SKILL.md +247 -0
- package/.agent/skills/investor-materials/SKILL.md +96 -0
- package/.agent/skills/investor-outreach/SKILL.md +91 -0
- package/.agent/skills/iterative-retrieval/SKILL.md +211 -0
- package/.agent/skills/java-coding-standards/SKILL.md +147 -0
- package/.agent/skills/jira-integration/SKILL.md +293 -0
- package/.agent/skills/jpa-patterns/SKILL.md +151 -0
- package/.agent/skills/kotlin-coroutines-flows/SKILL.md +284 -0
- package/.agent/skills/kotlin-exposed-patterns/SKILL.md +719 -0
- package/.agent/skills/kotlin-ktor-patterns/SKILL.md +689 -0
- package/.agent/skills/kotlin-patterns/SKILL.md +711 -0
- package/.agent/skills/kotlin-testing/SKILL.md +824 -0
- package/.agent/skills/laravel-patterns/SKILL.md +415 -0
- package/.agent/skills/laravel-plugin-discovery/SKILL.md +229 -0
- package/.agent/skills/laravel-security/SKILL.md +285 -0
- package/.agent/skills/laravel-tdd/SKILL.md +283 -0
- package/.agent/skills/laravel-verification/SKILL.md +179 -0
- package/.agent/skills/lead-intelligence/SKILL.md +321 -0
- package/.agent/skills/lead-intelligence/agents/enrichment-agent.md +85 -0
- package/.agent/skills/lead-intelligence/agents/mutual-mapper.md +75 -0
- package/.agent/skills/lead-intelligence/agents/outreach-drafter.md +98 -0
- package/.agent/skills/lead-intelligence/agents/signal-scorer.md +60 -0
- package/.agent/skills/liquid-glass-design/SKILL.md +279 -0
- package/.agent/skills/logistics-exception-management/SKILL.md +222 -0
- package/.agent/skills/manim-video/SKILL.md +89 -0
- package/.agent/skills/manim-video/assets/network-graph-scene.py +52 -0
- package/.agent/skills/market-research/SKILL.md +75 -0
- package/.agent/skills/mcp-builder/SKILL.md +173 -113
- package/.agent/skills/mcp-builder/license.txt +202 -0
- package/.agent/skills/mcp-builder/reference/evaluation.md +602 -0
- package/.agent/skills/mcp-builder/reference/mcp-best-practices.md +249 -0
- package/.agent/skills/mcp-builder/reference/node-mcp-server.md +970 -0
- package/.agent/skills/mcp-builder/reference/python-mcp-server.md +719 -0
- package/.agent/skills/mcp-builder/scripts/connections.py +151 -0
- package/.agent/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/.agent/skills/mcp-builder/scripts/example-evaluation.xml +22 -0
- package/.agent/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/.agent/skills/mcp-server-patterns/SKILL.md +67 -0
- package/.agent/skills/nanoclaw-repl/SKILL.md +33 -0
- package/.agent/skills/nestjs-patterns/SKILL.md +230 -0
- package/.agent/skills/nextjs-turbopack/SKILL.md +44 -0
- package/.agent/skills/nutrient-document-processing/SKILL.md +167 -0
- package/.agent/skills/nuxt4-patterns/SKILL.md +100 -0
- package/.agent/skills/openclaw-persona-forge/SKILL.md +296 -0
- package/.agent/skills/openclaw-persona-forge/gacha.py +224 -0
- package/.agent/skills/openclaw-persona-forge/gacha.sh +5 -0
- package/.agent/skills/openclaw-persona-forge/references/avatar-style.md +124 -0
- package/.agent/skills/openclaw-persona-forge/references/boundary-rules.md +53 -0
- package/.agent/skills/openclaw-persona-forge/references/error-handling.md +53 -0
- package/.agent/skills/openclaw-persona-forge/references/identity-tension.md +48 -0
- package/.agent/skills/openclaw-persona-forge/references/naming-system.md +39 -0
- package/.agent/skills/openclaw-persona-forge/references/output-template.md +166 -0
- package/.agent/skills/opensource-pipeline/SKILL.md +255 -0
- package/.agent/skills/perl-patterns/SKILL.md +504 -0
- package/.agent/skills/perl-security/SKILL.md +503 -0
- package/.agent/skills/perl-testing/SKILL.md +475 -0
- package/.agent/skills/plankton-code-quality/SKILL.md +236 -0
- package/.agent/skills/postgres-patterns/SKILL.md +147 -0
- package/.agent/skills/product-lens/SKILL.md +85 -0
- package/.agent/skills/production-scheduling/SKILL.md +238 -0
- package/.agent/skills/project-flow-ops/SKILL.md +111 -0
- package/.agent/skills/project-guidelines-example/SKILL.md +349 -0
- package/.agent/skills/prompt-optimizer/SKILL.md +397 -0
- package/.agent/skills/python-patterns/SKILL.md +622 -313
- package/.agent/skills/python-testing/SKILL.md +816 -0
- package/.agent/skills/pytorch-patterns/SKILL.md +396 -0
- package/.agent/skills/quality-nonconformance/SKILL.md +260 -0
- package/.agent/skills/ralphinho-rfc-pipeline/SKILL.md +67 -0
- package/.agent/skills/regex-vs-llm-structured-text/SKILL.md +220 -0
- package/.agent/skills/remotion-video-creation/SKILL.md +43 -0
- package/.agent/skills/remotion-video-creation/rules/3d.md +86 -0
- package/.agent/skills/remotion-video-creation/rules/animations.md +29 -0
- package/.agent/skills/remotion-video-creation/rules/assets/charts-bar-chart.tsx +173 -0
- package/.agent/skills/remotion-video-creation/rules/assets/text-animations-typewriter.tsx +100 -0
- package/.agent/skills/remotion-video-creation/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/.agent/skills/remotion-video-creation/rules/assets.md +78 -0
- package/.agent/skills/remotion-video-creation/rules/audio.md +172 -0
- package/.agent/skills/remotion-video-creation/rules/calculate-metadata.md +104 -0
- package/.agent/skills/remotion-video-creation/rules/can-decode.md +75 -0
- package/.agent/skills/remotion-video-creation/rules/charts.md +58 -0
- package/.agent/skills/remotion-video-creation/rules/compositions.md +146 -0
- package/.agent/skills/remotion-video-creation/rules/display-captions.md +126 -0
- package/.agent/skills/remotion-video-creation/rules/extract-frames.md +229 -0
- package/.agent/skills/remotion-video-creation/rules/fonts.md +152 -0
- package/.agent/skills/remotion-video-creation/rules/get-audio-duration.md +58 -0
- package/.agent/skills/remotion-video-creation/rules/get-video-dimensions.md +68 -0
- package/.agent/skills/remotion-video-creation/rules/get-video-duration.md +58 -0
- package/.agent/skills/remotion-video-creation/rules/gifs.md +138 -0
- package/.agent/skills/remotion-video-creation/rules/images.md +130 -0
- package/.agent/skills/remotion-video-creation/rules/import-srt-captions.md +67 -0
- package/.agent/skills/remotion-video-creation/rules/lottie.md +67 -0
- package/.agent/skills/remotion-video-creation/rules/measuring-dom-nodes.md +34 -0
- package/.agent/skills/remotion-video-creation/rules/measuring-text.md +143 -0
- package/.agent/skills/remotion-video-creation/rules/sequencing.md +106 -0
- package/.agent/skills/remotion-video-creation/rules/tailwind.md +11 -0
- package/.agent/skills/remotion-video-creation/rules/text-animations.md +20 -0
- package/.agent/skills/remotion-video-creation/rules/timing.md +179 -0
- package/.agent/skills/remotion-video-creation/rules/transcribe-captions.md +19 -0
- package/.agent/skills/remotion-video-creation/rules/transitions.md +122 -0
- package/.agent/skills/remotion-video-creation/rules/trimming.md +52 -0
- package/.agent/skills/remotion-video-creation/rules/videos.md +171 -0
- package/.agent/skills/repo-scan/SKILL.md +78 -0
- package/.agent/skills/returns-reverse-logistics/SKILL.md +240 -0
- package/.agent/skills/rules-distill/SKILL.md +264 -0
- package/.agent/skills/rules-distill/scripts/scan-rules.sh +58 -0
- package/.agent/skills/rules-distill/scripts/scan-skills.sh +129 -0
- package/.agent/skills/rust-patterns/SKILL.md +499 -0
- package/.agent/skills/rust-testing/SKILL.md +500 -0
- package/.agent/skills/safety-guard/SKILL.md +75 -0
- package/.agent/skills/santa-method/SKILL.md +306 -0
- package/.agent/skills/search-first/SKILL.md +161 -0
- package/.agent/skills/security-review/SKILL.md +495 -0
- package/.agent/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/.agent/skills/security-scan/SKILL.md +165 -0
- package/.agent/skills/skill-comply/SKILL.md +58 -0
- package/.agent/skills/skill-comply/fixtures/compliant-trace.jsonl +5 -0
- package/.agent/skills/skill-comply/fixtures/noncompliant-trace.jsonl +3 -0
- package/.agent/skills/skill-comply/fixtures/tdd-spec.yaml +44 -0
- package/.agent/skills/skill-comply/prompts/classifier.md +24 -0
- package/.agent/skills/skill-comply/prompts/scenario-generator.md +62 -0
- package/.agent/skills/skill-comply/prompts/spec-generator.md +42 -0
- package/.agent/skills/skill-comply/pyproject.toml +15 -0
- package/.agent/skills/skill-comply/scripts/classifier.py +85 -0
- package/.agent/skills/skill-comply/scripts/grader.py +122 -0
- package/.agent/skills/skill-comply/scripts/init.py +0 -0
- package/.agent/skills/skill-comply/scripts/parser.py +107 -0
- package/.agent/skills/skill-comply/scripts/report.py +170 -0
- package/.agent/skills/skill-comply/scripts/run.py +127 -0
- package/.agent/skills/skill-comply/scripts/runner.py +161 -0
- package/.agent/skills/skill-comply/scripts/scenario-generator.py +70 -0
- package/.agent/skills/skill-comply/scripts/spec-generator.py +72 -0
- package/.agent/skills/skill-comply/scripts/utils.py +13 -0
- package/.agent/skills/skill-comply/tests/test-grader.py +137 -0
- package/.agent/skills/skill-comply/tests/test-parser.py +90 -0
- package/.agent/skills/skill-creator/SKILL.md +485 -0
- package/.agent/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agent/skills/skill-creator/agents/comparator.md +202 -0
- package/.agent/skills/skill-creator/agents/grader.md +223 -0
- package/.agent/skills/skill-creator/assets/eval-review.html +146 -0
- package/.agent/skills/skill-creator/eval-viewer/generate-review.py +471 -0
- package/.agent/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agent/skills/skill-creator/license.txt +202 -0
- package/.agent/skills/skill-creator/references/schemas.md +430 -0
- package/.agent/skills/skill-creator/scripts/aggregate-benchmark.py +401 -0
- package/.agent/skills/skill-creator/scripts/generate-report.py +326 -0
- package/.agent/skills/skill-creator/scripts/improve-description.py +247 -0
- package/.agent/skills/skill-creator/scripts/init.py +0 -0
- package/.agent/skills/skill-creator/scripts/package-skill.py +136 -0
- package/.agent/skills/skill-creator/scripts/quick-validate.py +103 -0
- package/.agent/skills/skill-creator/scripts/run-eval.py +310 -0
- package/.agent/skills/skill-creator/scripts/run-loop.py +328 -0
- package/.agent/skills/skill-creator/scripts/utils.py +47 -0
- package/.agent/skills/skill-stocktake/SKILL.md +193 -0
- package/.agent/skills/skill-stocktake/scripts/quick-diff.sh +87 -0
- package/.agent/skills/skill-stocktake/scripts/save-results.sh +56 -0
- package/.agent/skills/skill-stocktake/scripts/scan.sh +170 -0
- package/.agent/skills/social-graph-ranker/SKILL.md +154 -0
- package/.agent/skills/springboot-patterns/SKILL.md +314 -0
- package/.agent/skills/springboot-security/SKILL.md +272 -0
- package/.agent/skills/springboot-tdd/SKILL.md +158 -0
- package/.agent/skills/springboot-verification/SKILL.md +231 -0
- package/.agent/skills/strategic-compact/SKILL.md +131 -0
- package/.agent/skills/strategic-compact/suggest-compact.sh +54 -0
- package/.agent/skills/swift-actor-persistence/SKILL.md +143 -0
- package/.agent/skills/swift-concurrency-6-2/SKILL.md +216 -0
- package/.agent/skills/swift-protocol-di-testing/SKILL.md +190 -0
- package/.agent/skills/swiftui-patterns/SKILL.md +259 -0
- package/.agent/skills/tdd-workflow/SKILL.md +412 -98
- package/.agent/skills/team-builder/SKILL.md +168 -0
- package/.agent/skills/token-budget-advisor/SKILL.md +133 -0
- package/.agent/skills/ui-demo/SKILL.md +465 -0
- package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -26
- package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -97
- package/.agent/skills/ui-ux-pro-max/data/landing.csv +28 -28
- package/.agent/skills/ui-ux-pro-max/data/products.csv +96 -96
- package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/.agent/skills/ui-ux-pro-max/data/styles.csv +68 -68
- package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/.agent/skills/ui-ux-pro-max/scripts/search.py +114 -114
- package/.agent/skills/verification-loop/SKILL.md +126 -0
- package/.agent/skills/video-editing/SKILL.md +310 -0
- package/.agent/skills/videodb/SKILL.md +374 -0
- package/.agent/skills/videodb/reference/api-reference.md +550 -0
- package/.agent/skills/videodb/reference/capture-reference.md +407 -0
- package/.agent/skills/videodb/reference/capture.md +101 -0
- package/.agent/skills/videodb/reference/editor.md +443 -0
- package/.agent/skills/videodb/reference/generative.md +331 -0
- package/.agent/skills/videodb/reference/rtstream-reference.md +564 -0
- package/.agent/skills/videodb/reference/rtstream.md +65 -0
- package/.agent/skills/videodb/reference/search.md +230 -0
- package/.agent/skills/videodb/reference/streaming.md +406 -0
- package/.agent/skills/videodb/reference/use-cases.md +118 -0
- package/.agent/skills/videodb/scripts/ws-listener.py +282 -0
- package/.agent/skills/visa-doc-translate/SKILL.md +117 -0
- package/.agent/skills/visa-doc-translate/readme.md +86 -0
- package/.agent/skills/workspace-surface-audit/SKILL.md +125 -0
- package/.agent/skills/x-api/SKILL.md +230 -0
- package/.agent/tasks/two-track-merge-contract.md +29 -0
- package/.agent/workflows/aside.md +164 -164
- package/.agent/workflows/build-fix.md +62 -62
- package/.agent/workflows/checkpoint.md +74 -74
- package/.agent/workflows/claw.md +23 -51
- package/.agent/workflows/clean-memory.md +34 -0
- package/.agent/workflows/code-review.md +289 -40
- package/.agent/workflows/context-budget.md +23 -29
- package/.agent/workflows/cpp-build.md +173 -173
- package/.agent/workflows/cpp-review.md +132 -132
- package/.agent/workflows/cpp-test.md +251 -251
- package/.agent/workflows/devfleet.md +23 -92
- package/.agent/workflows/docs.md +23 -31
- package/.agent/workflows/e2e.md +268 -365
- package/.agent/workflows/eval.md +23 -120
- package/.agent/workflows/evolve.md +178 -178
- package/.agent/workflows/flutter-build.md +164 -0
- package/.agent/workflows/flutter-review.md +116 -0
- package/.agent/workflows/flutter-test.md +144 -0
- package/.agent/workflows/gan-build.md +99 -0
- package/.agent/workflows/gan-design.md +35 -0
- package/.agent/workflows/go-build.md +183 -183
- package/.agent/workflows/go-review.md +148 -148
- package/.agent/workflows/go-test.md +268 -268
- package/.agent/workflows/gradle-build.md +70 -70
- package/.agent/workflows/harness-audit.md +73 -71
- package/.agent/workflows/instinct-export.md +66 -66
- package/.agent/workflows/instinct-import.md +114 -114
- package/.agent/workflows/instinct-status.md +59 -59
- package/.agent/workflows/jira.md +106 -0
- package/.agent/workflows/kotlin-build.md +174 -174
- package/.agent/workflows/kotlin-review.md +140 -140
- package/.agent/workflows/kotlin-test.md +312 -312
- package/.agent/workflows/learn-eval.md +116 -116
- package/.agent/workflows/learn.md +70 -70
- package/.agent/workflows/loop-start.md +32 -32
- package/.agent/workflows/loop-status.md +24 -24
- package/.agent/workflows/model-route.md +26 -26
- package/.agent/workflows/multi-backend.md +158 -158
- package/.agent/workflows/multi-execute.md +315 -315
- package/.agent/workflows/multi-frontend.md +158 -158
- package/.agent/workflows/multi-plan.md +268 -268
- package/.agent/workflows/multi-workflow.md +191 -191
- package/.agent/workflows/orchestrate.md +135 -231
- package/.agent/workflows/plan.md +117 -115
- package/.agent/workflows/pm2.md +272 -272
- package/.agent/workflows/projects.md +39 -39
- package/.agent/workflows/promote.md +41 -41
- package/.agent/workflows/prompt-optimize.md +23 -38
- package/.agent/workflows/prp-commit.md +112 -0
- package/.agent/workflows/prp-implement.md +385 -0
- package/.agent/workflows/prp-plan.md +502 -0
- package/.agent/workflows/prp-pr.md +184 -0
- package/.agent/workflows/prp-prd.md +447 -0
- package/.agent/workflows/prune.md +31 -31
- package/.agent/workflows/python-review.md +297 -297
- package/.agent/workflows/quality-gate.md +29 -29
- package/.agent/workflows/refactor-clean.md +80 -80
- package/.agent/workflows/resume-session.md +156 -156
- package/.agent/workflows/rules-distill.md +20 -11
- package/.agent/workflows/rust-build.md +187 -187
- package/.agent/workflows/rust-review.md +142 -142
- package/.agent/workflows/rust-test.md +308 -308
- package/.agent/workflows/santa-loop.md +175 -0
- package/.agent/workflows/save-session.md +275 -275
- package/.agent/workflows/sessions.md +333 -333
- package/.agent/workflows/setup-pm.md +80 -80
- package/.agent/workflows/skill-create.md +174 -174
- package/.agent/workflows/skill-health.md +54 -54
- package/.agent/workflows/tdd.md +231 -328
- package/.agent/workflows/test-coverage.md +69 -69
- package/.agent/workflows/update-codemaps.md +72 -72
- package/.agent/workflows/update-docs.md +84 -84
- package/.agent/workflows/verify.md +23 -59
- package/LICENSE +176 -176
- package/README.md +28 -20
- package/RELEASE.md +32 -36
- package/package.json +87 -79
- package/scripts/release-check.js +55 -55
- package/src/bin/cli.js +399 -53
- package/src/lib/installer.js +360 -114
- package/src/lib/manifests/stacks.js +122 -0
- package/src/lib/slash-commands.js +28 -0
- package/src/templates/claude/CLAUDE.en.md +42 -0
- package/src/templates/claude/CLAUDE.md +42 -0
- package/src/templates/claude/CLAUDE.vi.md +42 -0
- package/src/templates/codex/AGENTS.en.md +40 -0
- package/src/templates/codex/AGENTS.md +40 -0
- package/src/templates/codex/AGENTS.vi.md +40 -0
- package/src/templates/cursor/pilo-masterkit.mdc +20 -0
- package/src/templates/gemini/GEMINI.en.md +56 -0
- package/src/templates/gemini/GEMINI.md +56 -0
- package/src/templates/gemini/GEMINI.vi.md +56 -0
- package/src/templates/github/copilot-instructions.md +16 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scan-skills.sh — enumerate skill files, extract frontmatter and UTC mtime
|
|
3
|
+
# Usage: scan-skills.sh [CWD_SKILLS_DIR]
|
|
4
|
+
# Output: JSON to stdout
|
|
5
|
+
#
|
|
6
|
+
# When CWD_SKILLS_DIR is omitted, defaults to $PWD/.claude/skills so the
|
|
7
|
+
# script always picks up project-level skills without relying on the caller.
|
|
8
|
+
#
|
|
9
|
+
# Environment:
|
|
10
|
+
# RULES_DISTILL_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
|
11
|
+
# do not set in production — intended for bats tests)
|
|
12
|
+
# RULES_DISTILL_PROJECT_DIR Override project dir detection (for testing only)
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
GLOBAL_DIR="${RULES_DISTILL_GLOBAL_DIR:-$HOME/.claude/skills}"
|
|
17
|
+
CWD_SKILLS_DIR="${RULES_DISTILL_PROJECT_DIR:-${1:-$PWD/.claude/skills}}"
|
|
18
|
+
# Validate CWD_SKILLS_DIR looks like a .claude/skills path (defense-in-depth).
|
|
19
|
+
# Only warn when the path exists — a nonexistent path poses no traversal risk.
|
|
20
|
+
if [[ -n "$CWD_SKILLS_DIR" && -d "$CWD_SKILLS_DIR" && "$CWD_SKILLS_DIR" != */.claude/skills* ]]; then
|
|
21
|
+
echo "Warning: CWD_SKILLS_DIR does not look like a .claude/skills path: $CWD_SKILLS_DIR" >&2
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Extract a frontmatter field (handles both quoted and unquoted single-line values).
|
|
25
|
+
# Does NOT support multi-line YAML blocks (| or >) or nested YAML keys.
|
|
26
|
+
extract_field() {
|
|
27
|
+
local file="$1" field="$2"
|
|
28
|
+
awk -v f="$field" '
|
|
29
|
+
BEGIN { fm=0 }
|
|
30
|
+
/^---$/ { fm++; next }
|
|
31
|
+
fm==1 {
|
|
32
|
+
n = length(f) + 2
|
|
33
|
+
if (substr($0, 1, n) == f ": ") {
|
|
34
|
+
val = substr($0, n+1)
|
|
35
|
+
gsub(/^"/, "", val)
|
|
36
|
+
gsub(/"$/, "", val)
|
|
37
|
+
print val
|
|
38
|
+
exit
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
fm>=2 { exit }
|
|
42
|
+
' "$file"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Get file mtime in UTC ISO8601 (portable: GNU and BSD)
|
|
46
|
+
get_mtime() {
|
|
47
|
+
local file="$1"
|
|
48
|
+
local secs
|
|
49
|
+
secs=$(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null) || return 1
|
|
50
|
+
date -u -d "@$secs" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null ||
|
|
51
|
+
date -u -r "$secs" +%Y-%m-%dT%H:%M:%SZ
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Scan a directory and produce a JSON array of skill objects
|
|
55
|
+
scan_dir_to_json() {
|
|
56
|
+
local dir="$1"
|
|
57
|
+
|
|
58
|
+
local tmpdir
|
|
59
|
+
tmpdir=$(mktemp -d)
|
|
60
|
+
local _scan_tmpdir="$tmpdir"
|
|
61
|
+
_scan_cleanup() { rm -rf "$_scan_tmpdir"; }
|
|
62
|
+
trap _scan_cleanup RETURN
|
|
63
|
+
|
|
64
|
+
local i=0
|
|
65
|
+
while IFS= read -r file; do
|
|
66
|
+
local name desc mtime dp
|
|
67
|
+
name=$(extract_field "$file" "name")
|
|
68
|
+
desc=$(extract_field "$file" "description")
|
|
69
|
+
mtime=$(get_mtime "$file")
|
|
70
|
+
dp="${file/#$HOME/~}"
|
|
71
|
+
|
|
72
|
+
jq -n \
|
|
73
|
+
--arg path "$dp" \
|
|
74
|
+
--arg name "$name" \
|
|
75
|
+
--arg description "$desc" \
|
|
76
|
+
--arg mtime "$mtime" \
|
|
77
|
+
'{path:$path,name:$name,description:$description,mtime:$mtime}' \
|
|
78
|
+
> "$tmpdir/$i.json"
|
|
79
|
+
i=$((i+1))
|
|
80
|
+
done < <(find "$dir" -name "SKILL.md" -type f 2>/dev/null | sort)
|
|
81
|
+
|
|
82
|
+
if [[ $i -eq 0 ]]; then
|
|
83
|
+
echo "[]"
|
|
84
|
+
else
|
|
85
|
+
jq -s '.' "$tmpdir"/*.json
|
|
86
|
+
fi
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# --- Main ---
|
|
90
|
+
|
|
91
|
+
global_found="false"
|
|
92
|
+
global_count=0
|
|
93
|
+
global_skills="[]"
|
|
94
|
+
|
|
95
|
+
if [[ -d "$GLOBAL_DIR" ]]; then
|
|
96
|
+
global_found="true"
|
|
97
|
+
global_skills=$(scan_dir_to_json "$GLOBAL_DIR")
|
|
98
|
+
global_count=$(echo "$global_skills" | jq 'length')
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
project_found="false"
|
|
102
|
+
project_path=""
|
|
103
|
+
project_count=0
|
|
104
|
+
project_skills="[]"
|
|
105
|
+
|
|
106
|
+
if [[ -n "$CWD_SKILLS_DIR" && -d "$CWD_SKILLS_DIR" ]]; then
|
|
107
|
+
project_found="true"
|
|
108
|
+
project_path="$CWD_SKILLS_DIR"
|
|
109
|
+
project_skills=$(scan_dir_to_json "$CWD_SKILLS_DIR")
|
|
110
|
+
project_count=$(echo "$project_skills" | jq 'length')
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# Merge global + project skills into one array
|
|
114
|
+
all_skills=$(jq -s 'add' <(echo "$global_skills") <(echo "$project_skills"))
|
|
115
|
+
|
|
116
|
+
jq -n \
|
|
117
|
+
--arg global_found "$global_found" \
|
|
118
|
+
--argjson global_count "$global_count" \
|
|
119
|
+
--arg project_found "$project_found" \
|
|
120
|
+
--arg project_path "$project_path" \
|
|
121
|
+
--argjson project_count "$project_count" \
|
|
122
|
+
--argjson skills "$all_skills" \
|
|
123
|
+
'{
|
|
124
|
+
scan_summary: {
|
|
125
|
+
global: { found: ($global_found == "true"), count: $global_count },
|
|
126
|
+
project: { found: ($project_found == "true"), path: $project_path, count: $project_count }
|
|
127
|
+
},
|
|
128
|
+
skills: $skills
|
|
129
|
+
}'
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-patterns
|
|
3
|
+
description: Idiomatic Rust patterns, ownership, error handling, traits, concurrency, and best practices for building safe, performant applications.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rust Development Patterns
|
|
8
|
+
|
|
9
|
+
Idiomatic Rust patterns and best practices for building safe, performant, and maintainable applications.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- Writing new Rust code
|
|
14
|
+
- Reviewing Rust code
|
|
15
|
+
- Refactoring existing Rust code
|
|
16
|
+
- Designing crate structure and module layout
|
|
17
|
+
|
|
18
|
+
## How It Works
|
|
19
|
+
|
|
20
|
+
This skill enforces idiomatic Rust conventions across six key areas: ownership and borrowing to prevent data races at compile time, `Result`/`?` error propagation with `thiserror` for libraries and `anyhow` for applications, enums and exhaustive pattern matching to make illegal states unrepresentable, traits and generics for zero-cost abstraction, safe concurrency via `Arc<Mutex<T>>`, channels, and async/await, and minimal `pub` surfaces organized by domain.
|
|
21
|
+
|
|
22
|
+
## Core Principles
|
|
23
|
+
|
|
24
|
+
### 1. Ownership and Borrowing
|
|
25
|
+
|
|
26
|
+
Rust's ownership system prevents data races and memory bugs at compile time.
|
|
27
|
+
|
|
28
|
+
```rust
|
|
29
|
+
// Good: Pass references when you don't need ownership
|
|
30
|
+
fn process(data: &[u8]) -> usize {
|
|
31
|
+
data.len()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Good: Take ownership only when you need to store or consume
|
|
35
|
+
fn store(data: Vec<u8>) -> Record {
|
|
36
|
+
Record { payload: data }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Bad: Cloning unnecessarily to avoid borrow checker
|
|
40
|
+
fn process_bad(data: &Vec<u8>) -> usize {
|
|
41
|
+
let cloned = data.clone(); // Wasteful — just borrow
|
|
42
|
+
cloned.len()
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Use `Cow` for Flexible Ownership
|
|
47
|
+
|
|
48
|
+
```rust
|
|
49
|
+
use std::borrow::Cow;
|
|
50
|
+
|
|
51
|
+
fn normalize(input: &str) -> Cow<'_, str> {
|
|
52
|
+
if input.contains(' ') {
|
|
53
|
+
Cow::Owned(input.replace(' ', "_"))
|
|
54
|
+
} else {
|
|
55
|
+
Cow::Borrowed(input) // Zero-cost when no mutation needed
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Error Handling
|
|
61
|
+
|
|
62
|
+
### Use `Result` and `?` — Never `unwrap()` in Production
|
|
63
|
+
|
|
64
|
+
```rust
|
|
65
|
+
// Good: Propagate errors with context
|
|
66
|
+
use anyhow::{Context, Result};
|
|
67
|
+
|
|
68
|
+
fn load_config(path: &str) -> Result<Config> {
|
|
69
|
+
let content = std::fs::read_to_string(path)
|
|
70
|
+
.with_context(|| format!("failed to read config from {path}"))?;
|
|
71
|
+
let config: Config = toml::from_str(&content)
|
|
72
|
+
.with_context(|| format!("failed to parse config from {path}"))?;
|
|
73
|
+
Ok(config)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Bad: Panics on error
|
|
77
|
+
fn load_config_bad(path: &str) -> Config {
|
|
78
|
+
let content = std::fs::read_to_string(path).unwrap(); // Panics!
|
|
79
|
+
toml::from_str(&content).unwrap()
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Library Errors with `thiserror`, Application Errors with `anyhow`
|
|
84
|
+
|
|
85
|
+
```rust
|
|
86
|
+
// Library code: structured, typed errors
|
|
87
|
+
use thiserror::Error;
|
|
88
|
+
|
|
89
|
+
#[derive(Debug, Error)]
|
|
90
|
+
pub enum StorageError {
|
|
91
|
+
#[error("record not found: {id}")]
|
|
92
|
+
NotFound { id: String },
|
|
93
|
+
#[error("connection failed")]
|
|
94
|
+
Connection(#[from] std::io::Error),
|
|
95
|
+
#[error("invalid data: {0}")]
|
|
96
|
+
InvalidData(String),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Application code: flexible error handling
|
|
100
|
+
use anyhow::{bail, Result};
|
|
101
|
+
|
|
102
|
+
fn run() -> Result<()> {
|
|
103
|
+
let config = load_config("app.toml")?;
|
|
104
|
+
if config.workers == 0 {
|
|
105
|
+
bail!("worker count must be > 0");
|
|
106
|
+
}
|
|
107
|
+
Ok(())
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### `Option` Combinators Over Nested Matching
|
|
112
|
+
|
|
113
|
+
```rust
|
|
114
|
+
// Good: Combinator chain
|
|
115
|
+
fn find_user_email(users: &[User], id: u64) -> Option<String> {
|
|
116
|
+
users.iter()
|
|
117
|
+
.find(|u| u.id == id)
|
|
118
|
+
.map(|u| u.email.clone())
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Bad: Deeply nested matching
|
|
122
|
+
fn find_user_email_bad(users: &[User], id: u64) -> Option<String> {
|
|
123
|
+
match users.iter().find(|u| u.id == id) {
|
|
124
|
+
Some(user) => match &user.email {
|
|
125
|
+
email => Some(email.clone()),
|
|
126
|
+
},
|
|
127
|
+
None => None,
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Enums and Pattern Matching
|
|
133
|
+
|
|
134
|
+
### Model States as Enums
|
|
135
|
+
|
|
136
|
+
```rust
|
|
137
|
+
// Good: Impossible states are unrepresentable
|
|
138
|
+
enum ConnectionState {
|
|
139
|
+
Disconnected,
|
|
140
|
+
Connecting { attempt: u32 },
|
|
141
|
+
Connected { session_id: String },
|
|
142
|
+
Failed { reason: String, retries: u32 },
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fn handle(state: &ConnectionState) {
|
|
146
|
+
match state {
|
|
147
|
+
ConnectionState::Disconnected => connect(),
|
|
148
|
+
ConnectionState::Connecting { attempt } if *attempt > 3 => abort(),
|
|
149
|
+
ConnectionState::Connecting { .. } => wait(),
|
|
150
|
+
ConnectionState::Connected { session_id } => use_session(session_id),
|
|
151
|
+
ConnectionState::Failed { retries, .. } if *retries < 5 => retry(),
|
|
152
|
+
ConnectionState::Failed { reason, .. } => log_failure(reason),
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Exhaustive Matching — No Catch-All for Business Logic
|
|
158
|
+
|
|
159
|
+
```rust
|
|
160
|
+
// Good: Handle every variant explicitly
|
|
161
|
+
match command {
|
|
162
|
+
Command::Start => start_service(),
|
|
163
|
+
Command::Stop => stop_service(),
|
|
164
|
+
Command::Restart => restart_service(),
|
|
165
|
+
// Adding a new variant forces handling here
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Bad: Wildcard hides new variants
|
|
169
|
+
match command {
|
|
170
|
+
Command::Start => start_service(),
|
|
171
|
+
_ => {} // Silently ignores Stop, Restart, and future variants
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Traits and Generics
|
|
176
|
+
|
|
177
|
+
### Accept Generics, Return Concrete Types
|
|
178
|
+
|
|
179
|
+
```rust
|
|
180
|
+
// Good: Generic input, concrete output
|
|
181
|
+
fn read_all(reader: &mut impl Read) -> std::io::Result<Vec<u8>> {
|
|
182
|
+
let mut buf = Vec::new();
|
|
183
|
+
reader.read_to_end(&mut buf)?;
|
|
184
|
+
Ok(buf)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Good: Trait bounds for multiple constraints
|
|
188
|
+
fn process<T: Display + Send + 'static>(item: T) -> String {
|
|
189
|
+
format!("processed: {item}")
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Trait Objects for Dynamic Dispatch
|
|
194
|
+
|
|
195
|
+
```rust
|
|
196
|
+
// Use when you need heterogeneous collections or plugin systems
|
|
197
|
+
trait Handler: Send + Sync {
|
|
198
|
+
fn handle(&self, request: &Request) -> Response;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
struct Router {
|
|
202
|
+
handlers: Vec<Box<dyn Handler>>,
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Use generics when you need performance (monomorphization)
|
|
206
|
+
fn fast_process<H: Handler>(handler: &H, request: &Request) -> Response {
|
|
207
|
+
handler.handle(request)
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Newtype Pattern for Type Safety
|
|
212
|
+
|
|
213
|
+
```rust
|
|
214
|
+
// Good: Distinct types prevent mixing up arguments
|
|
215
|
+
struct UserId(u64);
|
|
216
|
+
struct OrderId(u64);
|
|
217
|
+
|
|
218
|
+
fn get_order(user: UserId, order: OrderId) -> Result<Order> {
|
|
219
|
+
// Can't accidentally swap user and order IDs
|
|
220
|
+
todo!()
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Bad: Easy to swap arguments
|
|
224
|
+
fn get_order_bad(user_id: u64, order_id: u64) -> Result<Order> {
|
|
225
|
+
todo!()
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Structs and Data Modeling
|
|
230
|
+
|
|
231
|
+
### Builder Pattern for Complex Construction
|
|
232
|
+
|
|
233
|
+
```rust
|
|
234
|
+
struct ServerConfig {
|
|
235
|
+
host: String,
|
|
236
|
+
port: u16,
|
|
237
|
+
max_connections: usize,
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
impl ServerConfig {
|
|
241
|
+
fn builder(host: impl Into<String>, port: u16) -> ServerConfigBuilder {
|
|
242
|
+
ServerConfigBuilder { host: host.into(), port, max_connections: 100 }
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
struct ServerConfigBuilder { host: String, port: u16, max_connections: usize }
|
|
247
|
+
|
|
248
|
+
impl ServerConfigBuilder {
|
|
249
|
+
fn max_connections(mut self, n: usize) -> Self { self.max_connections = n; self }
|
|
250
|
+
fn build(self) -> ServerConfig {
|
|
251
|
+
ServerConfig { host: self.host, port: self.port, max_connections: self.max_connections }
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Usage: ServerConfig::builder("localhost", 8080).max_connections(200).build()
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Iterators and Closures
|
|
259
|
+
|
|
260
|
+
### Prefer Iterator Chains Over Manual Loops
|
|
261
|
+
|
|
262
|
+
```rust
|
|
263
|
+
// Good: Declarative, lazy, composable
|
|
264
|
+
let active_emails: Vec<String> = users.iter()
|
|
265
|
+
.filter(|u| u.is_active)
|
|
266
|
+
.map(|u| u.email.clone())
|
|
267
|
+
.collect();
|
|
268
|
+
|
|
269
|
+
// Bad: Imperative accumulation
|
|
270
|
+
let mut active_emails = Vec::new();
|
|
271
|
+
for user in &users {
|
|
272
|
+
if user.is_active {
|
|
273
|
+
active_emails.push(user.email.clone());
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Use `collect()` with Type Annotation
|
|
279
|
+
|
|
280
|
+
```rust
|
|
281
|
+
// Collect into different types
|
|
282
|
+
let names: Vec<_> = items.iter().map(|i| &i.name).collect();
|
|
283
|
+
let lookup: HashMap<_, _> = items.iter().map(|i| (i.id, i)).collect();
|
|
284
|
+
let combined: String = parts.iter().copied().collect();
|
|
285
|
+
|
|
286
|
+
// Collect Results — short-circuits on first error
|
|
287
|
+
let parsed: Result<Vec<i32>, _> = strings.iter().map(|s| s.parse()).collect();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Concurrency
|
|
291
|
+
|
|
292
|
+
### `Arc<Mutex<T>>` for Shared Mutable State
|
|
293
|
+
|
|
294
|
+
```rust
|
|
295
|
+
use std::sync::{Arc, Mutex};
|
|
296
|
+
|
|
297
|
+
let counter = Arc::new(Mutex::new(0));
|
|
298
|
+
let handles: Vec<_> = (0..10).map(|_| {
|
|
299
|
+
let counter = Arc::clone(&counter);
|
|
300
|
+
std::thread::spawn(move || {
|
|
301
|
+
let mut num = counter.lock().expect("mutex poisoned");
|
|
302
|
+
*num += 1;
|
|
303
|
+
})
|
|
304
|
+
}).collect();
|
|
305
|
+
|
|
306
|
+
for handle in handles {
|
|
307
|
+
handle.join().expect("worker thread panicked");
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Channels for Message Passing
|
|
312
|
+
|
|
313
|
+
```rust
|
|
314
|
+
use std::sync::mpsc;
|
|
315
|
+
|
|
316
|
+
let (tx, rx) = mpsc::sync_channel(16); // Bounded channel with backpressure
|
|
317
|
+
|
|
318
|
+
for i in 0..5 {
|
|
319
|
+
let tx = tx.clone();
|
|
320
|
+
std::thread::spawn(move || {
|
|
321
|
+
tx.send(format!("message {i}")).expect("receiver disconnected");
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
drop(tx); // Close sender so rx iterator terminates
|
|
325
|
+
|
|
326
|
+
for msg in rx {
|
|
327
|
+
println!("{msg}");
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Async with Tokio
|
|
332
|
+
|
|
333
|
+
```rust
|
|
334
|
+
use tokio::time::Duration;
|
|
335
|
+
|
|
336
|
+
async fn fetch_with_timeout(url: &str) -> Result<String> {
|
|
337
|
+
let response = tokio::time::timeout(
|
|
338
|
+
Duration::from_secs(5),
|
|
339
|
+
reqwest::get(url),
|
|
340
|
+
)
|
|
341
|
+
.await
|
|
342
|
+
.context("request timed out")?
|
|
343
|
+
.context("request failed")?;
|
|
344
|
+
|
|
345
|
+
response.text().await.context("failed to read body")
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Spawn concurrent tasks
|
|
349
|
+
async fn fetch_all(urls: Vec<String>) -> Vec<Result<String>> {
|
|
350
|
+
let handles: Vec<_> = urls.into_iter()
|
|
351
|
+
.map(|url| tokio::spawn(async move {
|
|
352
|
+
fetch_with_timeout(&url).await
|
|
353
|
+
}))
|
|
354
|
+
.collect();
|
|
355
|
+
|
|
356
|
+
let mut results = Vec::with_capacity(handles.len());
|
|
357
|
+
for handle in handles {
|
|
358
|
+
results.push(handle.await.unwrap_or_else(|e| panic!("spawned task panicked: {e}")));
|
|
359
|
+
}
|
|
360
|
+
results
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Unsafe Code
|
|
365
|
+
|
|
366
|
+
### When Unsafe Is Acceptable
|
|
367
|
+
|
|
368
|
+
```rust
|
|
369
|
+
// Acceptable: FFI boundary with documented invariants (Rust 2024+)
|
|
370
|
+
/// # Safety
|
|
371
|
+
/// `ptr` must be a valid, aligned pointer to an initialized `Widget`.
|
|
372
|
+
unsafe fn widget_from_raw<'a>(ptr: *const Widget) -> &'a Widget {
|
|
373
|
+
// SAFETY: caller guarantees ptr is valid and aligned
|
|
374
|
+
unsafe { &*ptr }
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Acceptable: Performance-critical path with proof of correctness
|
|
378
|
+
// SAFETY: index is always < len due to the loop bound
|
|
379
|
+
unsafe { slice.get_unchecked(index) }
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### When Unsafe Is NOT Acceptable
|
|
383
|
+
|
|
384
|
+
```rust
|
|
385
|
+
// Bad: Using unsafe to bypass borrow checker
|
|
386
|
+
// Bad: Using unsafe for convenience
|
|
387
|
+
// Bad: Using unsafe without a Safety comment
|
|
388
|
+
// Bad: Transmuting between unrelated types
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Module System and Crate Structure
|
|
392
|
+
|
|
393
|
+
### Organize by Domain, Not by Type
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
my_app/
|
|
397
|
+
├── src/
|
|
398
|
+
│ ├── main.rs
|
|
399
|
+
│ ├── lib.rs
|
|
400
|
+
│ ├── auth/ # Domain module
|
|
401
|
+
│ │ ├── mod.rs
|
|
402
|
+
│ │ ├── token.rs
|
|
403
|
+
│ │ └── middleware.rs
|
|
404
|
+
│ ├── orders/ # Domain module
|
|
405
|
+
│ │ ├── mod.rs
|
|
406
|
+
│ │ ├── model.rs
|
|
407
|
+
│ │ └── service.rs
|
|
408
|
+
│ └── db/ # Infrastructure
|
|
409
|
+
│ ├── mod.rs
|
|
410
|
+
│ └── pool.rs
|
|
411
|
+
├── tests/ # Integration tests
|
|
412
|
+
├── benches/ # Benchmarks
|
|
413
|
+
└── Cargo.toml
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Visibility — Expose Minimally
|
|
417
|
+
|
|
418
|
+
```rust
|
|
419
|
+
// Good: pub(crate) for internal sharing
|
|
420
|
+
pub(crate) fn validate_input(input: &str) -> bool {
|
|
421
|
+
!input.is_empty()
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Good: Re-export public API from lib.rs
|
|
425
|
+
pub mod auth;
|
|
426
|
+
pub use auth::AuthMiddleware;
|
|
427
|
+
|
|
428
|
+
// Bad: Making everything pub
|
|
429
|
+
pub fn internal_helper() {} // Should be pub(crate) or private
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Tooling Integration
|
|
433
|
+
|
|
434
|
+
### Essential Commands
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
# Build and check
|
|
438
|
+
cargo build
|
|
439
|
+
cargo check # Fast type checking without codegen
|
|
440
|
+
cargo clippy # Lints and suggestions
|
|
441
|
+
cargo fmt # Format code
|
|
442
|
+
|
|
443
|
+
# Testing
|
|
444
|
+
cargo test
|
|
445
|
+
cargo test -- --nocapture # Show println output
|
|
446
|
+
cargo test --lib # Unit tests only
|
|
447
|
+
cargo test --test integration # Integration tests only
|
|
448
|
+
|
|
449
|
+
# Dependencies
|
|
450
|
+
cargo audit # Security audit
|
|
451
|
+
cargo tree # Dependency tree
|
|
452
|
+
cargo update # Update dependencies
|
|
453
|
+
|
|
454
|
+
# Performance
|
|
455
|
+
cargo bench # Run benchmarks
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Quick Reference: Rust Idioms
|
|
459
|
+
|
|
460
|
+
| Idiom | Description |
|
|
461
|
+
|-------|-------------|
|
|
462
|
+
| Borrow, don't clone | Pass `&T` instead of cloning unless ownership is needed |
|
|
463
|
+
| Make illegal states unrepresentable | Use enums to model valid states only |
|
|
464
|
+
| `?` over `unwrap()` | Propagate errors, never panic in library/production code |
|
|
465
|
+
| Parse, don't validate | Convert unstructured data to typed structs at the boundary |
|
|
466
|
+
| Newtype for type safety | Wrap primitives in newtypes to prevent argument swaps |
|
|
467
|
+
| Prefer iterators over loops | Declarative chains are clearer and often faster |
|
|
468
|
+
| `#[must_use]` on Results | Ensure callers handle return values |
|
|
469
|
+
| `Cow` for flexible ownership | Avoid allocations when borrowing suffices |
|
|
470
|
+
| Exhaustive matching | No wildcard `_` for business-critical enums |
|
|
471
|
+
| Minimal `pub` surface | Use `pub(crate)` for internal APIs |
|
|
472
|
+
|
|
473
|
+
## Anti-Patterns to Avoid
|
|
474
|
+
|
|
475
|
+
```rust
|
|
476
|
+
// Bad: .unwrap() in production code
|
|
477
|
+
let value = map.get("key").unwrap();
|
|
478
|
+
|
|
479
|
+
// Bad: .clone() to satisfy borrow checker without understanding why
|
|
480
|
+
let data = expensive_data.clone();
|
|
481
|
+
process(&original, &data);
|
|
482
|
+
|
|
483
|
+
// Bad: Using String when &str suffices
|
|
484
|
+
fn greet(name: String) { /* should be &str */ }
|
|
485
|
+
|
|
486
|
+
// Bad: Box<dyn Error> in libraries (use thiserror instead)
|
|
487
|
+
fn parse(input: &str) -> Result<Data, Box<dyn std::error::Error>> { todo!() }
|
|
488
|
+
|
|
489
|
+
// Bad: Ignoring must_use warnings
|
|
490
|
+
let _ = validate(input); // Silently discarding a Result
|
|
491
|
+
|
|
492
|
+
// Bad: Blocking in async context
|
|
493
|
+
async fn bad_async() {
|
|
494
|
+
std::thread::sleep(Duration::from_secs(1)); // Blocks the executor!
|
|
495
|
+
// Use: tokio::time::sleep(Duration::from_secs(1)).await;
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
**Remember**: If it compiles, it's probably correct — but only if you avoid `unwrap()`, minimize `unsafe`, and let the type system work for you.
|