[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CB9RV2NMMPFEY3WPPV3CQP":3,"skill-same:01M6CB9RV2NMMPFEY3WPPV3CQP":61},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":25,"linkOnly":26,"markdownContent":27,"markdownBody":28,"frontMatter":29,"refName":33,"commitSha":34,"skillDirectory":35,"forksCount":36,"repositoryHtmlUrl":37,"repositoryHomepageUrl":38,"ownerHtmlUrl":39,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":40,"install":41,"resources":54},"01M6CB9RV2NMMPFEY3WPPV3CQP","flutter",null,"Flutter\u002FDart best practices with Riverpod, freezed, and feature-based architecture","shahboura\u002Fagents-opencode","shahboura","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F210767?v=4","01M6C6WKTBT0NH92BEPQRHQSYM","Shehab El Hadidy","01M6C6WKYXG8AE68MCGBNE5ZFR",2,"MIT","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fflutter\u002FSKILL.md",[],[5,19,20,21,22,23,24],"dart best practices","architecture","development","best practices","dart","opencode","2026-11-10 10:12:30",false,"---\nname: flutter\ndescription: Flutter\u002FDart best practices with Riverpod, freezed, and feature-based architecture\nlicense: MIT\ncompatibility: opencode\nmetadata:\n  author: shahboura\n  version: \"2.0.0\"\n  audience: developers\n  workflow: development\n---\n\n## What I do\n- Enforce feature-based project architecture with clean layer separation\n- Guide state management with Riverpod and immutable models with freezed\n- Apply error handling patterns and widget testing conventions\n\n## When to use me\nUse this when working on Flutter\u002FDart projects with Riverpod state management.\n\n## Key Rules\n- Use feature-based directory structure: `lib\u002Fcore\u002F`, `lib\u002Ffeatures\u002F\u003Cname>\u002F{data,domain,presentation}\u002F`, `lib\u002Fshared\u002F`\n- Prefer Riverpod (`StateNotifierProvider`, `ConsumerWidget`) for app\u002Fshared state; use `setState` for simple local UI state\n- Prefer immutable data models (for example `freezed`) for domain\u002Fnetwork DTOs; avoid mutable models unless justified\n- Error handling via sealed `Result\u003CT>` class: `Success\u003CT>` and `Error\u003CT>` — never throw across layers\n- Prefer `StatelessWidget` and `ConsumerWidget`; only use `StatefulWidget` when absolutely necessary\n- Mark widgets and constructors `const` wherever possible — the analyzer will catch misses\n- Prefer `go_router` for app-scale declarative routing; `Navigator` APIs are fine for simple\u002Flocal flows\n- Use `ThemeExtension\u003CT>` for custom theme properties — never hardcode colors or spacing\n- Riverpod providers serve as dependency injection — no service locators or get_it needed\n- Wrap async calls in try\u002Fcatch at the repository layer; return `Result`, not raw exceptions\n- Require widget tests for critical UI behavior; use risk-based coverage across unit\u002Fwidget\u002Fintegration tests\n- Use `super.key` in widget constructors (Dart 3+), not `Key? key` with `super(key: key)`\n- Use a verify-fix-verify loop: run the validation commands below, fix any failures, and rerun until all checks pass\n\n## Naming Conventions\n- `PascalCase` for classes\u002Fwidgets\n- `camelCase` for methods\u002Fvariables\n- `snake_case.dart` for file names\n- Name providers by domain intent (`userProfileProvider`, `checkoutNotifierProvider`)\n\n## Common Pitfalls\n- Business logic embedded directly in widgets\n- Mutable model classes instead of immutable data contracts\n- Async exceptions crossing layers without normalization to `Result`\n- Hardcoded spacing\u002Fcolors that bypass theme and break responsive consistency\n\n## Example Patterns\n```dart\nfinal userProvider = FutureProvider\u003CResult\u003CUser>>((ref) async {\n  try {\n    final user = await ref.read(apiClientProvider).getUser();\n    return Result.success(user);\n  } catch (e) {\n    return Result.error('Failed to load user: $e');\n  }\n});\n\n\u002F\u002F Result\u003CT> is an app-defined sealed type used for cross-layer error handling.\n```\n\n## Validation Commands\nPrefer project scripts when present; use defaults below otherwise.\n\n```bash\nflutter analyze\nflutter test\nflutter test --coverage\ndart format --set-exit-if-changed .\n```\n","## What I do\n- Enforce feature-based project architecture with clean layer separation\n- Guide state management with Riverpod and immutable models with freezed\n- Apply error handling patterns and widget testing conventions\n\n## When to use me\nUse this when working on Flutter\u002FDart projects with Riverpod state management.\n\n## Key Rules\n- Use feature-based directory structure: `lib\u002Fcore\u002F`, `lib\u002Ffeatures\u002F\u003Cname>\u002F{data,domain,presentation}\u002F`, `lib\u002Fshared\u002F`\n- Prefer Riverpod (`StateNotifierProvider`, `ConsumerWidget`) for app\u002Fshared state; use `setState` for simple local UI state\n- Prefer immutable data models (for example `freezed`) for domain\u002Fnetwork DTOs; avoid mutable models unless justified\n- Error handling via sealed `Result\u003CT>` class: `Success\u003CT>` and `Error\u003CT>` — never throw across layers\n- Prefer `StatelessWidget` and `ConsumerWidget`; only use `StatefulWidget` when absolutely necessary\n- Mark widgets and constructors `const` wherever possible — the analyzer will catch misses\n- Prefer `go_router` for app-scale declarative routing; `Navigator` APIs are fine for simple\u002Flocal flows\n- Use `ThemeExtension\u003CT>` for custom theme properties — never hardcode colors or spacing\n- Riverpod providers serve as dependency injection — no service locators or get_it needed\n- Wrap async calls in try\u002Fcatch at the repository layer; return `Result`, not raw exceptions\n- Require widget tests for critical UI behavior; use risk-based coverage across unit\u002Fwidget\u002Fintegration tests\n- Use `super.key` in widget constructors (Dart 3+), not `Key? key` with `super(key: key)`\n- Use a verify-fix-verify loop: run the validation commands below, fix any failures, and rerun until all checks pass\n\n## Naming Conventions\n- `PascalCase` for classes\u002Fwidgets\n- `camelCase` for methods\u002Fvariables\n- `snake_case.dart` for file names\n- Name providers by domain intent (`userProfileProvider`, `checkoutNotifierProvider`)\n\n## Common Pitfalls\n- Business logic embedded directly in widgets\n- Mutable model classes instead of immutable data contracts\n- Async exceptions crossing layers without normalization to `Result`\n- Hardcoded spacing\u002Fcolors that bypass theme and break responsive consistency\n\n## Example Patterns\n```dart\nfinal userProvider = FutureProvider\u003CResult\u003CUser>>((ref) async {\n  try {\n    final user = await ref.read(apiClientProvider).getUser();\n    return Result.success(user);\n  } catch (e) {\n    return Result.error('Failed to load user: $e');\n  }\n});\n\n\u002F\u002F Result\u003CT> is an app-defined sealed type used for cross-layer error handling.\n```\n\n## Validation Commands\nPrefer project scripts when present; use defaults below otherwise.\n\n```bash\nflutter analyze\nflutter test\nflutter test --coverage\ndart format --set-exit-if-changed .\n```\n",{"name":5,"license":15,"metadata":30,"description":7,"compatibility":24},{"author":9,"version":31,"audience":32,"workflow":21},"2.0.0","developers","main","9b951b5b2e5d07d427baff330db5deb2a8c67511",".opencode\u002Fskills\u002Fflutter",0,"https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode","https:\u002F\u002Fagnts.elkodr.com\u002F","https:\u002F\u002Fgithub.com\u002Fshahboura","2026-11-05 13:30:42",{"source":8,"skillName":5,"commands":42,"prompt":52,"zipAvailable":53},[43,46,49],{"tool":44,"command":45},"npx","npx skills add shahboura\u002Fagents-opencode --skill flutter",{"tool":47,"command":48},"bunx","bunx skills add shahboura\u002Fagents-opencode --skill flutter",{"tool":50,"command":51},"pnpm","pnpm dlx skills add shahboura\u002Fagents-opencode --skill flutter","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002F.opencode\u002Fskills\u002Fflutter\u002FSKILL.md",true,[55],{"path":56,"resourceType":57,"resourceTypeDesc":58,"sizeBytes":59,"sourceHtmlUrl":60},"agents\u002Fopenai.yaml","REFERENCE","参考文档",266,"https:\u002F\u002Fgithub.com\u002Fwelflau\u002Fai-dev-system\u002Fblob\u002Fmain\u002Fbackend\u002Fconfig_packs\u002Fweb-dev\u002Fshared\u002Fskills\u002Fbackend-patterns\u002Fagents\u002Fopenai.yaml",[62,68,77,82,87,92],{"skillNo":63,"name":64,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":67,"publishedAt":25},"01M6CBBX1C6NV7VY8XK21DV5FW","python","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fvalidate-agents\u002Fvalid\u002F.opencode\u002Fskills\u002Fpython\u002FSKILL.md",[],[64],{"skillNo":69,"name":70,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":73,"publishedAt":25},"01M6CBBVB7W6ABJH8XP3Z8PPMK","docs-validation","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fvalidate-agents\u002Fvalid\u002F.opencode\u002Fskills\u002Fdocs-validation\u002FSKILL.md",[],[74,75,76],"docs","validation","docs validation",{"skillNo":78,"name":64,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":25},"01M6CBBT2WC781609MH5RN7KM7","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fvalidate-agents\u002Funknown-skill\u002F.opencode\u002Fskills\u002Fpython\u002FSKILL.md",[],[64],{"skillNo":83,"name":70,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":25},"01M6CBBRNY6TDRZ5627GC8436D","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fvalidate-agents\u002Funknown-skill\u002F.opencode\u002Fskills\u002Fdocs-validation\u002FSKILL.md",[],[74,75,76],{"skillNo":88,"name":64,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":25},"01M6CBBQDS170GBYA1CVW3DC5D","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fvalidate-agents\u002Finline-skill\u002F.opencode\u002Fskills\u002Fpython\u002FSKILL.md",[],[64],{"skillNo":93,"name":70,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":25},"01M6CBBP222WAW802YHY37F48A","https:\u002F\u002Fgithub.com\u002Fshahboura\u002Fagents-opencode\u002Fblob\u002Fmain\u002Fscripts\u002Ffixtures\u002Fvalidate-agents\u002Finline-skill\u002F.opencode\u002Fskills\u002Fdocs-validation\u002FSKILL.md",[],[74,75,76]]