[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6BXVCG904KP6JBVVXVR01CN":3,"skill-same:01M6BXVCG904KP6JBVVXVR01CN":79},{"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":20,"linkOnly":21,"markdownContent":22,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":30,"ownerHtmlUrl":31,"ownerBlogUrl":32,"ownerDescription":33,"updatedAt":34,"install":35,"resources":48},"01M6BXVCG904KP6JBVVXVR01CN","kotlin patterns",null,"Conventions for using Kotlin","jesperancinha\u002Fkotlin-mysteries","jesperancinha","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F11569930?v=4","01M6BXV038GJ2R8FQNEPT7AVZC","João Filipe Sabino Esperancinha","01M6BXV07CCQXNTGXREN86RZBR",2,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fkotlin\u002FSKILL.md",[],[5,19],"kotlin","2026-11-10 10:12:30",false,"---\nname: kotlin patterns\ndescription: Conventions for using Kotlin\n---\n\n## 1. Remove usage of `!!` operator\n\nThe `!!` operator should be avoided in Kotlin as it can lead to `NullPointerException` at runtime. Instead, use safe calls (`?.`) or the `let` scope function to handle nullable values more gracefully.\n\n## 2. Remove the safe call operator (`?.`) when possible\n\nUsing the safe call operator (`?.`) is a good practice, but it should be used judiciously.\nIt makes no sense to use this operator when the value is guaranteed to be non-null, as it can lead to unnecessary null checks and reduce code readability.\n\n## 3. Avoid using `var` when possible\n\nIn Kotlin, it is recommended to use `val` instead of `var` whenever possible. This helps to make the code more readable and maintainable, as it makes it clear that the value of a variable is not expected to change.\n\n## 4. Use Duration overload when possible\n\n### Example 1\n\nWhen using the `delay` function, it is recommended to use the overload that accepts a `Duration` parameter instead of a `Long` parameter. This makes the code more readable and easier to understand, as it clearly indicates the intended duration of the delay.\n\nreplace this:\n\n```kotlin\ndelay(100)\n```\n\nwith this:\n\n```kotlin\ndelay(100.milliseconds)\n```\n\nAdd import: `import kotlin.time.Duration.Companion.milliseconds`\n\n## 5. Remove all code signatures\n\nCode does not need to be signed. The code signature used to have some value, but in current times, the commit already has a signature.\nOld code may contain signatures that look like this:\n\n```kotlin\n\u002F**\n * Created by joao on 28-4-16.\n *\u002F\n```\n\nThey should all be removed, as they are not needed and add no value to the code.\n\n## 6. When using Kotlin code make sure to use the kotlin extensions for parsing\n\n### Example 1\n\nWhen finding this:\n\n```kotlin\n    .getForEntity(\"\u002Ftulips\", String::class.java)\n```\nreplace with:\n```kotlin\n    .getForEntity\u003CString>(\"\u002Ftulips\")\n```\n\n## 7. Update the usage of `CSVParser` which is now deprecated\n\nThis skill refers to the `CSVParser` from `org.apache.commons.csv.*`\n\n### Example 1\n\nReplace\n```kotlin\nval csvParser = CSVParser(reader, CSV_HEADER)\n```\n\nwith\n\n```kotlin\nval csvParser = CSVParser.builder()\n    .setReader(reader)\n    .setFormat(CSV_HEADER).get()\n```\n\n### Example 2\n\nReplace this\n\n```kotlin\nprivate val CSV_HEADER = DEFAULT\n    .withHeader(\n        \"id\",\n        \"description\",\n        \"year\",\n        \"value\",\n        \"currency\",\n        \"type\",\n        \"diameterMM\",\n        \"internalDiameterMM\",\n        \"heightMM\",\n        \"widthMM\"\n    )\n```\n\nwith:\n\n```kotlin\nprivate val CSV_HEADER = CSVFormat.DEFAULT.builder()\n    .setHeader(\n        \"id\",\n        \"description\",\n        \"year\",\n        \"value\",\n        \"currency\",\n        \"type\",\n        \"diameterMM\",\n        \"internalDiameterMM\",\n        \"heightMM\",\n        \"widthMM\"\n    ).get()\n```\n\n## 8. For all uses of Lombok in Kotlin classes that still use its builder pattern, please convert them to data classes\n\nDue to Java conversions to Kotlin, some of them, due to their automatic nature, didn't consider the existence of data classes.\nIf Kotlin classes still use lombok for the builder pattern please convert them to `data class`.\n\n## 9. Checklist\n\n[ ] The code does not use the `!!` operator.\n[ ] The code does not use the safe call operator (`?.`) when the value is guaranteed to be non-null.\n[ ] The code uses `val` instead of `var` whenever possible.\n[ ] The code uses the `Duration` overload when using the `delay` function.\n[ ] The code does not contain any code signatures.\n[ ] The code uses the kotlin extensions for parsing when using Kotlin code.\n[ ] The code should not use the `CSVParser` constructuro directly","## 1. Remove usage of `!!` operator\n\nThe `!!` operator should be avoided in Kotlin as it can lead to `NullPointerException` at runtime. Instead, use safe calls (`?.`) or the `let` scope function to handle nullable values more gracefully.\n\n## 2. Remove the safe call operator (`?.`) when possible\n\nUsing the safe call operator (`?.`) is a good practice, but it should be used judiciously.\nIt makes no sense to use this operator when the value is guaranteed to be non-null, as it can lead to unnecessary null checks and reduce code readability.\n\n## 3. Avoid using `var` when possible\n\nIn Kotlin, it is recommended to use `val` instead of `var` whenever possible. This helps to make the code more readable and maintainable, as it makes it clear that the value of a variable is not expected to change.\n\n## 4. Use Duration overload when possible\n\n### Example 1\n\nWhen using the `delay` function, it is recommended to use the overload that accepts a `Duration` parameter instead of a `Long` parameter. This makes the code more readable and easier to understand, as it clearly indicates the intended duration of the delay.\n\nreplace this:\n\n```kotlin\ndelay(100)\n```\n\nwith this:\n\n```kotlin\ndelay(100.milliseconds)\n```\n\nAdd import: `import kotlin.time.Duration.Companion.milliseconds`\n\n## 5. Remove all code signatures\n\nCode does not need to be signed. The code signature used to have some value, but in current times, the commit already has a signature.\nOld code may contain signatures that look like this:\n\n```kotlin\n\u002F**\n * Created by joao on 28-4-16.\n *\u002F\n```\n\nThey should all be removed, as they are not needed and add no value to the code.\n\n## 6. When using Kotlin code make sure to use the kotlin extensions for parsing\n\n### Example 1\n\nWhen finding this:\n\n```kotlin\n    .getForEntity(\"\u002Ftulips\", String::class.java)\n```\nreplace with:\n```kotlin\n    .getForEntity\u003CString>(\"\u002Ftulips\")\n```\n\n## 7. Update the usage of `CSVParser` which is now deprecated\n\nThis skill refers to the `CSVParser` from `org.apache.commons.csv.*`\n\n### Example 1\n\nReplace\n```kotlin\nval csvParser = CSVParser(reader, CSV_HEADER)\n```\n\nwith\n\n```kotlin\nval csvParser = CSVParser.builder()\n    .setReader(reader)\n    .setFormat(CSV_HEADER).get()\n```\n\n### Example 2\n\nReplace this\n\n```kotlin\nprivate val CSV_HEADER = DEFAULT\n    .withHeader(\n        \"id\",\n        \"description\",\n        \"year\",\n        \"value\",\n        \"currency\",\n        \"type\",\n        \"diameterMM\",\n        \"internalDiameterMM\",\n        \"heightMM\",\n        \"widthMM\"\n    )\n```\n\nwith:\n\n```kotlin\nprivate val CSV_HEADER = CSVFormat.DEFAULT.builder()\n    .setHeader(\n        \"id\",\n        \"description\",\n        \"year\",\n        \"value\",\n        \"currency\",\n        \"type\",\n        \"diameterMM\",\n        \"internalDiameterMM\",\n        \"heightMM\",\n        \"widthMM\"\n    ).get()\n```\n\n## 8. For all uses of Lombok in Kotlin classes that still use its builder pattern, please convert them to data classes\n\nDue to Java conversions to Kotlin, some of them, due to their automatic nature, didn't consider the existence of data classes.\nIf Kotlin classes still use lombok for the builder pattern please convert them to `data class`.\n\n## 9. Checklist\n\n[ ] The code does not use the `!!` operator.\n[ ] The code does not use the safe call operator (`?.`) when the value is guaranteed to be non-null.\n[ ] The code uses `val` instead of `var` whenever possible.\n[ ] The code uses the `Duration` overload when using the `delay` function.\n[ ] The code does not contain any code signatures.\n[ ] The code uses the kotlin extensions for parsing when using Kotlin code.\n[ ] The code should not use the `CSVParser` constructuro directly",{"name":5,"description":7},"main","697d8147950c43487405f9593abb95dc5dc7aabe",".claude\u002Fskills\u002Fkotlin",0,"https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries","https:\u002F\u002Fjesperancinha.github.io\u002Fkotlin-mysteries\u002F","https:\u002F\u002Fgithub.com\u002Fjesperancinha","http:\u002F\u002Fjoaofilipesabinoesperancinha.nl\u002F","IT Engineer","2026-07-20 17:47:29",{"source":8,"skillName":5,"commands":36,"prompt":46,"zipAvailable":47},[37,40,43],{"tool":38,"command":39},"npx","npx skills add jesperancinha\u002Fkotlin-mysteries --skill \"kotlin patterns\"",{"tool":41,"command":42},"bunx","bunx skills add jesperancinha\u002Fkotlin-mysteries --skill \"kotlin patterns\"",{"tool":44,"command":45},"pnpm","pnpm dlx skills add jesperancinha\u002Fkotlin-mysteries --skill \"kotlin patterns\"","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fkotlin\u002FSKILL.md",true,[49,55,61,67,71,75],{"path":50,"resourceType":51,"resourceTypeDesc":52,"sizeBytes":53,"sourceHtmlUrl":54},"assets\u002FREADME.md","ASSET","资产文件",350,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fdatabase\u002Fdatabase-documentation-gen\u002Fskills\u002Fdatabase-documentation-gen\u002Fassets\u002FREADME.md",{"path":56,"resourceType":57,"resourceTypeDesc":58,"sizeBytes":59,"sourceHtmlUrl":60},"references\u002FREADME.md","REFERENCE","参考文档",493,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fdatabase\u002Fdatabase-documentation-gen\u002Fskills\u002Fdatabase-documentation-gen\u002Freferences\u002FREADME.md",{"path":62,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":66},"scripts\u002Ferd_generator.py","SCRIPT","脚本",12185,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fdatabase\u002Fdatabase-documentation-gen\u002Fskills\u002Fdatabase-documentation-gen\u002Fscripts\u002Ferd_generator.py",{"path":68,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":69,"sourceHtmlUrl":70},"scripts\u002Finit_db_docs.py",5048,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fdatabase\u002Fdatabase-documentation-gen\u002Fskills\u002Fdatabase-documentation-gen\u002Fscripts\u002Finit_db_docs.py",{"path":72,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":73,"sourceHtmlUrl":74},"scripts\u002FREADME.md",1089,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fdatabase\u002Fdatabase-documentation-gen\u002Fskills\u002Fdatabase-documentation-gen\u002Fscripts\u002FREADME.md",{"path":76,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":77,"sourceHtmlUrl":78},"scripts\u002Fvalidate_config.py",10017,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fdatabase\u002Fdatabase-documentation-gen\u002Fskills\u002Fdatabase-documentation-gen\u002Fscripts\u002Fvalidate_config.py",[80,97,111,120,127,134],{"skillNo":81,"name":82,"nameZh":6,"description":83,"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":20},"01M6BXVS2Q1EJRCHG37A671S8K","spring","Conventions for dependency injection and mocking in Spring Boot in this project. Use this whenever writing, reviewing, or refactoring integration test classes (anything annotated @SpringBootTest, or under src\u002Ftest that talks to a real Spring context), especially when deciding how to wire dependencies or mock collaborators. Also consult this before adding @Autowired, @MockBean, @MockitoBean, or field injection in any test class.","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fspring\u002FSKILL.md",[],[82,87,88,89,90,91,92,93,94,95,96],"src","refactoring","consult","how","injection","integration","spring boot","boot","test","writing",{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":108,"publishedAt":20},"01M6BXVP5QBEYCNWG56FFBBHZK","spring-integration-test-wiring","Conventions for dependency injection and mocking in Spring Boot integration tests in this project. Use this whenever writing, reviewing, or refactoring integration test classes (anything annotated @SpringBootTest, or under src\u002Ftest that talks to a real Spring context), especially when deciding how to wire dependencies or mock collaborators. Also consult this before adding @Autowired, @MockBean, @MockitoBean, or field injection in any test class.","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fspring-test\u002FSKILL.md",[103],{"categoryNo":104,"categoryName":105,"taxonomyType":106,"taxonomyTypeDesc":107},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[109,92,95,87,88,89,90,91,93,94,110,96],"spring integration test wiring","integration tests",{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":20},"01M6BXVM9KDEWYJ7WWJSTA22GR","Scripts patterns","Conventions for using sh, bash, bat, python scripts","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fscripts\u002FSKILL.md",[],[113,118,119],"Bash","python",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":20},"01M6BXVJETCKANCGG2ZVJJVWYN","Readme standards","Conventions to use in Readme files","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Freadme\u002FSKILL.md",[],[122],{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":20},"01M6BXVGR52RYGR5R2A4N4C3SE","parallelization","Conventions for using parallelization in all tests using Jupiter","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fparallel\u002FSKILL.md",[],[129],{"skillNo":135,"name":136,"nameZh":6,"description":137,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":138,"categories":139,"keywords":140,"publishedAt":20},"01M6BXVEP33NG1YREVBDF5R3TN","Maven standards","Conventions to use in Maven files, mostly the `pom.xml` files","https:\u002F\u002Fgithub.com\u002Fjesperancinha\u002Fkotlin-mysteries\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fmaven\u002FSKILL.md",[],[141,136,142],"maven","xml"]