[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CST0BCH288FFQXPJR4GD63":3,"skill-same:01M6CST0BCH288FFQXPJR4GD63":94},{"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":28,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":51,"commitSha":52,"skillDirectory":53,"forksCount":14,"repositoryHtmlUrl":54,"repositoryHomepageUrl":55,"ownerHtmlUrl":56,"ownerBlogUrl":6,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M6CST0BCH288FFQXPJR4GD63","api-platform:make-dto",null,"Génère des DTOs (input\u002Foutput) API Platform avec mapping vers les entités","atournayre\u002Fclaude-personas","atournayre","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F4262077?v=4","01M6CSSGYW0E0D0M3E2T6J9X2Z","Aurélien Tournayre","01M6CSSH3DENJF2XWZ41H0F43K",0,"MIT","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Fapi-platform\u002Fskills\u002Fmake-dto\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35],"api","api platform:make dto","Bash","grep","read","write","edit","2026-11-10 10:12:30",false,"---\nname: api-platform:make-dto\ndescription: Génère des DTOs (input\u002Foutput) API Platform avec mapping vers les entités\nargument-hint: \u003Cnom-resource>\nmodel: sonnet\nallowed-tools: [AskUserQuestion, Bash, Read, Write, Edit, Grep, Glob]\nversion: 1.0.0\nlicense: MIT\n---\n\n# API Platform Make DTO\n\nGénère des Data Transfer Objects (DTOs) pour API Platform avec le mapping input\u002Foutput, les State Providers et Processors associés.\n\n## Variables\n- **{ResourceName}** - Nom de la resource en PascalCase\n- **{dtoType}** - Type : input, output, ou les deux\n- **{namespace}** - Namespace du projet (défaut: App)\n\n## Outputs\n- `src\u002FDto\u002F{ResourceName}Input.php` (si input)\n- `src\u002FDto\u002F{ResourceName}Output.php` (si output)\n- `src\u002FState\u002F{ResourceName}Provider.php` (si output DTO)\n- `src\u002FState\u002F{ResourceName}Processor.php` (si input DTO)\n\n## Instructions à Exécuter\n\n**IMPORTANT : Exécute ce workflow étape par étape :**\n\n### 1. Identifier la resource cible\n\n- Si `$ARGUMENTS` est fourni, utiliser comme nom de la resource\n- Sinon, utiliser AskUserQuestion :\n  ```\n  Question: \"Pour quelle resource créer des DTOs ?\"\n  Header: \"Resource\"\n  ```\n- Vérifier que l'entité existe dans `src\u002FEntity\u002F`\n- Lire le fichier pour comprendre les propriétés\n\n### 2. Choisir le type de DTO\n\n- Utiliser AskUserQuestion :\n  ```\n  Question: \"Quel type de DTO créer ?\"\n  Header: \"Type\"\n  Options:\n    - \"Input + Output (Recommandé)\" : \"DTOs distincts pour la lecture et l'écriture\"\n    - \"Output uniquement\" : \"DTO pour personnaliser la représentation en lecture\"\n    - \"Input uniquement\" : \"DTO pour valider et transformer les données en écriture\"\n  ```\n\n### 3. Sélectionner les propriétés\n\n- Lister les propriétés de l'entité\n- Pour le DTO output : demander quelles propriétés exposer\n- Pour le DTO input : demander quelles propriétés accepter\n- Proposer d'ajouter des propriétés calculées (output) ou des champs supplémentaires (input)\n\n### 4. Détecter le namespace du projet\n\n- Lire `composer.json` avec Read\n- Extraire le namespace depuis `autoload.psr-4`\n\n### 5. Générer le DTO Output\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\Dto;\n\nfinal readonly class {ResourceName}Output\n{\n    public function __construct(\n        public int $id,\n        \u002F\u002F Propriétés exposées en lecture\n        public string $name,\n        public string $email,\n        \u002F\u002F Propriétés calculées\n        public string $displayName,\n    ) {\n    }\n\n    public static function fromEntity({ResourceName} $entity): self\n    {\n        return new self(\n            id: $entity->getId(),\n            name: $entity->getName(),\n            email: $entity->getEmail(),\n            displayName: sprintf('%s (%s)', $entity->getName(), $entity->getEmail()),\n        );\n    }\n}\n```\n\n### 6. Générer le DTO Input\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\Dto;\n\nuse Symfony\\Component\\Validator\\Constraints as Assert;\n\nfinal class {ResourceName}Input\n{\n    public function __construct(\n        #[Assert\\NotBlank]\n        public readonly string $name,\n\n        #[Assert\\NotBlank]\n        #[Assert\\Email]\n        public readonly string $email,\n    ) {\n    }\n\n    public function toEntity(): {ResourceName}\n    {\n        \u002F\u002F Créer l'entité depuis le DTO\n    }\n\n    public function updateEntity({ResourceName} $entity): {ResourceName}\n    {\n        \u002F\u002F Mettre à jour l'entité existante\n        return $entity;\n    }\n}\n```\n\n### 7. Générer le State Provider (si output DTO)\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\State;\n\nuse ApiPlatform\\Metadata\\CollectionOperationInterface;\nuse ApiPlatform\\Metadata\\Operation;\nuse ApiPlatform\\State\\ProviderInterface;\nuse {namespace}\\Dto\\{ResourceName}Output;\n\n\u002F**\n * @implements ProviderInterface\u003C{ResourceName}Output>\n *\u002F\nfinal readonly class {ResourceName}Provider implements ProviderInterface\n{\n    public function __construct(\n        private ProviderInterface $decorated,\n    ) {\n    }\n\n    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null\n    {\n        $data = $this->decorated->provide($operation, $uriVariables, $context);\n\n        if ($operation instanceof CollectionOperationInterface) {\n            $items = [];\n            foreach ($data as $entity) {\n                $items[] = {ResourceName}Output::fromEntity($entity);\n            }\n            return $items;\n        }\n\n        if (null === $data) {\n            return null;\n        }\n\n        return {ResourceName}Output::fromEntity($data);\n    }\n}\n```\n\n### 8. Générer le State Processor (si input DTO)\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\State;\n\nuse ApiPlatform\\Metadata\\Operation;\nuse ApiPlatform\\State\\ProcessorInterface;\nuse {namespace}\\Dto\\{ResourceName}Input;\nuse {namespace}\\Dto\\{ResourceName}Output;\n\n\u002F**\n * @implements ProcessorInterface\u003C{ResourceName}Input, {ResourceName}Output>\n *\u002F\nfinal readonly class {ResourceName}Processor implements ProcessorInterface\n{\n    public function __construct(\n        private ProcessorInterface $decorated,\n    ) {\n    }\n\n    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed\n    {\n        \u002F** @var {ResourceName}Input $data *\u002F\n        $entity = $data->toEntity();\n\n        $result = $this->decorated->process($entity, $operation, $uriVariables, $context);\n\n        return {ResourceName}Output::fromEntity($result);\n    }\n}\n```\n\n### 9. Mettre à jour la resource\n\nModifier l'attribut `#[ApiResource]` pour utiliser les DTOs :\n\n```php\n#[ApiResource(\n    operations: [\n        new GetCollection(output: {ResourceName}Output::class),\n        new Get(output: {ResourceName}Output::class),\n        new Post(input: {ResourceName}Input::class, output: {ResourceName}Output::class),\n        new Put(input: {ResourceName}Input::class, output: {ResourceName}Output::class),\n        new Patch(input: {ResourceName}Input::class, output: {ResourceName}Output::class),\n        new Delete(),\n    ],\n    provider: {ResourceName}Provider::class,\n    processor: {ResourceName}Processor::class,\n)]\n```\n\n### 10. Afficher le résumé\n\n```\nDTOs générés pour {ResourceName}\n\nFichiers créés :\n- src\u002FDto\u002F{ResourceName}Input.php\n- src\u002FDto\u002F{ResourceName}Output.php\n- src\u002FState\u002F{ResourceName}Provider.php\n- src\u002FState\u002F{ResourceName}Processor.php\n\nMapping :\n- Input : POST\u002FPUT\u002FPATCH → {ResourceName}Input → Entité\n- Output : Entité → {ResourceName}Output → GET\n\nProchaines étapes :\n- Compléter la logique toEntity() et updateEntity()\n- Ajouter des validations sur le DTO Input\n- Tester : \u002Fapi-platform:make-test {ResourceName}\n```\n\n## Patterns appliqués\n\n### DTOs\n- Output DTO : `final readonly` avec factory method `fromEntity()`\n- Input DTO : `final` avec validation Symfony et méthodes `toEntity()` \u002F `updateEntity()`\n- Séparation stricte input\u002Foutput pour des contrats d'API clairs\n\n### Bonnes pratiques\n- Le DTO output est immuable (`readonly`)\n- Le DTO input porte la validation\n- La transformation entité ↔ DTO est dans le DTO lui-même (méthodes statiques)\n- Le provider transforme entité → output DTO\n- Le processor transforme input DTO → entité puis entité → output DTO\n\n## Notes\n- Les DTOs découplent la représentation API de la structure interne\n- Préférer les DTOs quand l'API ne correspond pas 1:1 avec les entités\n- Pour les cas simples, les groupes de sérialisation suffisent (pas besoin de DTOs)\n- Les DTOs permettent de versionner l'API sans impacter les entités\n","# API Platform Make DTO\n\nGénère des Data Transfer Objects (DTOs) pour API Platform avec le mapping input\u002Foutput, les State Providers et Processors associés.\n\n## Variables\n- **{ResourceName}** - Nom de la resource en PascalCase\n- **{dtoType}** - Type : input, output, ou les deux\n- **{namespace}** - Namespace du projet (défaut: App)\n\n## Outputs\n- `src\u002FDto\u002F{ResourceName}Input.php` (si input)\n- `src\u002FDto\u002F{ResourceName}Output.php` (si output)\n- `src\u002FState\u002F{ResourceName}Provider.php` (si output DTO)\n- `src\u002FState\u002F{ResourceName}Processor.php` (si input DTO)\n\n## Instructions à Exécuter\n\n**IMPORTANT : Exécute ce workflow étape par étape :**\n\n### 1. Identifier la resource cible\n\n- Si `$ARGUMENTS` est fourni, utiliser comme nom de la resource\n- Sinon, utiliser AskUserQuestion :\n  ```\n  Question: \"Pour quelle resource créer des DTOs ?\"\n  Header: \"Resource\"\n  ```\n- Vérifier que l'entité existe dans `src\u002FEntity\u002F`\n- Lire le fichier pour comprendre les propriétés\n\n### 2. Choisir le type de DTO\n\n- Utiliser AskUserQuestion :\n  ```\n  Question: \"Quel type de DTO créer ?\"\n  Header: \"Type\"\n  Options:\n    - \"Input + Output (Recommandé)\" : \"DTOs distincts pour la lecture et l'écriture\"\n    - \"Output uniquement\" : \"DTO pour personnaliser la représentation en lecture\"\n    - \"Input uniquement\" : \"DTO pour valider et transformer les données en écriture\"\n  ```\n\n### 3. Sélectionner les propriétés\n\n- Lister les propriétés de l'entité\n- Pour le DTO output : demander quelles propriétés exposer\n- Pour le DTO input : demander quelles propriétés accepter\n- Proposer d'ajouter des propriétés calculées (output) ou des champs supplémentaires (input)\n\n### 4. Détecter le namespace du projet\n\n- Lire `composer.json` avec Read\n- Extraire le namespace depuis `autoload.psr-4`\n\n### 5. Générer le DTO Output\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\Dto;\n\nfinal readonly class {ResourceName}Output\n{\n    public function __construct(\n        public int $id,\n        \u002F\u002F Propriétés exposées en lecture\n        public string $name,\n        public string $email,\n        \u002F\u002F Propriétés calculées\n        public string $displayName,\n    ) {\n    }\n\n    public static function fromEntity({ResourceName} $entity): self\n    {\n        return new self(\n            id: $entity->getId(),\n            name: $entity->getName(),\n            email: $entity->getEmail(),\n            displayName: sprintf('%s (%s)', $entity->getName(), $entity->getEmail()),\n        );\n    }\n}\n```\n\n### 6. Générer le DTO Input\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\Dto;\n\nuse Symfony\\Component\\Validator\\Constraints as Assert;\n\nfinal class {ResourceName}Input\n{\n    public function __construct(\n        #[Assert\\NotBlank]\n        public readonly string $name,\n\n        #[Assert\\NotBlank]\n        #[Assert\\Email]\n        public readonly string $email,\n    ) {\n    }\n\n    public function toEntity(): {ResourceName}\n    {\n        \u002F\u002F Créer l'entité depuis le DTO\n    }\n\n    public function updateEntity({ResourceName} $entity): {ResourceName}\n    {\n        \u002F\u002F Mettre à jour l'entité existante\n        return $entity;\n    }\n}\n```\n\n### 7. Générer le State Provider (si output DTO)\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\State;\n\nuse ApiPlatform\\Metadata\\CollectionOperationInterface;\nuse ApiPlatform\\Metadata\\Operation;\nuse ApiPlatform\\State\\ProviderInterface;\nuse {namespace}\\Dto\\{ResourceName}Output;\n\n\u002F**\n * @implements ProviderInterface\u003C{ResourceName}Output>\n *\u002F\nfinal readonly class {ResourceName}Provider implements ProviderInterface\n{\n    public function __construct(\n        private ProviderInterface $decorated,\n    ) {\n    }\n\n    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null\n    {\n        $data = $this->decorated->provide($operation, $uriVariables, $context);\n\n        if ($operation instanceof CollectionOperationInterface) {\n            $items = [];\n            foreach ($data as $entity) {\n                $items[] = {ResourceName}Output::fromEntity($entity);\n            }\n            return $items;\n        }\n\n        if (null === $data) {\n            return null;\n        }\n\n        return {ResourceName}Output::fromEntity($data);\n    }\n}\n```\n\n### 8. Générer le State Processor (si input DTO)\n\n```php\n\u003C?php\n\ndeclare(strict_types=1);\n\nnamespace {namespace}\\State;\n\nuse ApiPlatform\\Metadata\\Operation;\nuse ApiPlatform\\State\\ProcessorInterface;\nuse {namespace}\\Dto\\{ResourceName}Input;\nuse {namespace}\\Dto\\{ResourceName}Output;\n\n\u002F**\n * @implements ProcessorInterface\u003C{ResourceName}Input, {ResourceName}Output>\n *\u002F\nfinal readonly class {ResourceName}Processor implements ProcessorInterface\n{\n    public function __construct(\n        private ProcessorInterface $decorated,\n    ) {\n    }\n\n    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed\n    {\n        \u002F** @var {ResourceName}Input $data *\u002F\n        $entity = $data->toEntity();\n\n        $result = $this->decorated->process($entity, $operation, $uriVariables, $context);\n\n        return {ResourceName}Output::fromEntity($result);\n    }\n}\n```\n\n### 9. Mettre à jour la resource\n\nModifier l'attribut `#[ApiResource]` pour utiliser les DTOs :\n\n```php\n#[ApiResource(\n    operations: [\n        new GetCollection(output: {ResourceName}Output::class),\n        new Get(output: {ResourceName}Output::class),\n        new Post(input: {ResourceName}Input::class, output: {ResourceName}Output::class),\n        new Put(input: {ResourceName}Input::class, output: {ResourceName}Output::class),\n        new Patch(input: {ResourceName}Input::class, output: {ResourceName}Output::class),\n        new Delete(),\n    ],\n    provider: {ResourceName}Provider::class,\n    processor: {ResourceName}Processor::class,\n)]\n```\n\n### 10. Afficher le résumé\n\n```\nDTOs générés pour {ResourceName}\n\nFichiers créés :\n- src\u002FDto\u002F{ResourceName}Input.php\n- src\u002FDto\u002F{ResourceName}Output.php\n- src\u002FState\u002F{ResourceName}Provider.php\n- src\u002FState\u002F{ResourceName}Processor.php\n\nMapping :\n- Input : POST\u002FPUT\u002FPATCH → {ResourceName}Input → Entité\n- Output : Entité → {ResourceName}Output → GET\n\nProchaines étapes :\n- Compléter la logique toEntity() et updateEntity()\n- Ajouter des validations sur le DTO Input\n- Tester : \u002Fapi-platform:make-test {ResourceName}\n```\n\n## Patterns appliqués\n\n### DTOs\n- Output DTO : `final readonly` avec factory method `fromEntity()`\n- Input DTO : `final` avec validation Symfony et méthodes `toEntity()` \u002F `updateEntity()`\n- Séparation stricte input\u002Foutput pour des contrats d'API clairs\n\n### Bonnes pratiques\n- Le DTO output est immuable (`readonly`)\n- Le DTO input porte la validation\n- La transformation entité ↔ DTO est dans le DTO lui-même (méthodes statiques)\n- Le provider transforme entité → output DTO\n- Le processor transforme input DTO → entité puis entité → output DTO\n\n## Notes\n- Les DTOs découplent la représentation API de la structure interne\n- Préférer les DTOs quand l'API ne correspond pas 1:1 avec les entités\n- Pour les cas simples, les groupes de sérialisation suffisent (pas besoin de DTOs)\n- Les DTOs permettent de versionner l'API sans impacter les entités\n",{"name":5,"model":41,"license":15,"version":42,"description":7,"allowed-tools":43,"argument-hint":50},"sonnet","1.0.0",[44,31,45,46,47,48,49],"AskUserQuestion","Read","Write","Edit","Grep","Glob","\u003Cnom-resource>","main","bb0335112ea0991dc1dc6a29fa5a861397a5a6f6","api-platform\u002Fskills\u002Fmake-dto","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas","https:\u002F\u002Fatournayre.github.io\u002Fclaude-personas\u002F","https:\u002F\u002Fgithub.com\u002Fatournayre","🔵, Back End Developer, @symfony  :heart:, @rectorphp :heart:,  \r\n:bug: fixer (creator sometimes 🤫), member of @afup","2026-03-02 23:42:20",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add atournayre\u002Fclaude-personas --skill \"api-platform:make-dto\"",{"tool":65,"command":66},"bunx","bunx skills add atournayre\u002Fclaude-personas --skill \"api-platform:make-dto\"",{"tool":68,"command":69},"pnpm","pnpm dlx skills add atournayre\u002Fclaude-personas --skill \"api-platform:make-dto\"","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Fapi-platform\u002Fskills\u002Fmake-dto\u002FSKILL.md",true,[73,79,85,90],{"path":74,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":77,"sourceHtmlUrl":78},"assets\u002Fdeck-stage.js","SCRIPT","脚本",22748,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-pink-script\u002Fassets\u002Fdeck-stage.js",{"path":80,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":83,"sourceHtmlUrl":84},"example.html","REFERENCE","参考文档",41247,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-pink-script\u002Fexample.html",{"path":86,"resourceType":86,"resourceTypeDesc":87,"sizeBytes":88,"sourceHtmlUrl":89},"LICENSE","许可证",1067,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-pink-script\u002FLICENSE",{"path":91,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":92,"sourceHtmlUrl":93},"template.json",1852,"https:\u002F\u002Fgithub.com\u002Fendman100\u002Fskill-router-nexus\u002Fblob\u002Fmain\u002FPPT-Design\u002Fopen-design-html-ppt-zhangzara-pink-script\u002Ftemplate.json",[95,107,143,150,158,169],{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":36},"01M6CSZPR0W1K1S9BX3247CZJ1","twig:make-component","Génère un Twig Component Symfony UX (classe PHP + template Twig)","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Ftwig\u002Fskills\u002Fmake-component\u002FSKILL.md",[],[102,103,33,35,34,104,32,105,106,31],"twig:make component","component","ux","template","php",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":125,"publishedAt":36},"01M6CSZKCYYT4EAW4CDSTS3TSH","tester:ui-test","Teste automatiquement une interface utilisateur dans Chrome : navigation, clics, validation visuelle, tests fonctionnels, responsive, comportement et debug. Génère un rapport détaillé avec screenshots et optionnellement un GIF du parcours.","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Ftester\u002Fskills\u002Fui-test\u002FSKILL.md",[113,116,119,122],{"categoryNo":114,"categoryName":115,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":117,"categoryName":118,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":120,"categoryName":121,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":123,"categoryName":124,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000032","设计师",[126,127,128,129,130,131,132,133,134,135,136,31,137,138,139,140,33,34,141,142],"test","ui","tester","ui test","tester:ui test","MCP","debug","create","update","validation","messages","plan","tool","page","find","javascript","chrome",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":149,"publishedAt":36},"01M6CSZGQ8X9XNXRBYX0AA3CYE","symfony:voter","Genere un Voter de securite Symfony pour le controle d'acces granulaire","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Fsymfony\u002Fskills\u002Fvoter\u002FSKILL.md",[],[145,31,32,33,34,35],{"skillNo":151,"name":152,"nameZh":6,"description":153,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":154,"categories":155,"keywords":156,"publishedAt":36},"01M6CSZEJ3BNHCNZT18SYFGDME","symfony:message","Genere un Message Symfony Messenger avec son Handler pour traitement asynchrone","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Fsymfony\u002Fskills\u002Fmessage\u002FSKILL.md",[],[152,157,31,32,33,34,35],"message",{"skillNo":159,"name":160,"nameZh":6,"description":161,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":162,"categories":163,"keywords":167,"publishedAt":36},"01M6CSZBWSK9M6YMJX886BVWYF","symfony:mailer","Genere un email Symfony (TemplatedEmail ou Notification) avec template Twig","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Fsymfony\u002Fskills\u002Fmailer\u002FSKILL.md",[164],{"categoryNo":165,"categoryName":166,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000005","邮件与沟通",[160,35,168,31,105,32,33,34],"email",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":36},"01M6CSZ9DXMYZ9HTRE8A324AWG","symfony:form","Genere un FormType Symfony avec contraintes de validation et options","https:\u002F\u002Fgithub.com\u002Fatournayre\u002Fclaude-personas\u002Fblob\u002Fmain\u002Fsymfony\u002Fskills\u002Fform\u002FSKILL.md",[],[171,31,32,33,34,35,176,135],"options"]