@biggora/claude-plugins 1.2.0 → 1.3.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.
Files changed (265) hide show
  1. package/README.md +13 -4
  2. package/package.json +1 -1
  3. package/registry/registry.json +334 -244
  4. package/specs/coding.md +30 -0
  5. package/specs/pod.md +2 -0
  6. package/src/commands/skills/add.js +63 -7
  7. package/src/commands/skills/list.js +23 -52
  8. package/src/commands/skills/remove.js +26 -27
  9. package/src/commands/skills/resolve.js +155 -0
  10. package/src/commands/skills/update.js +58 -74
  11. package/src/skills/captcha/README.md +221 -0
  12. package/src/skills/captcha/SKILL.md +355 -0
  13. package/src/skills/captcha/references/captcha-types.md +254 -0
  14. package/src/skills/captcha/references/services.md +172 -0
  15. package/src/skills/captcha/references/stealth.md +238 -0
  16. package/src/skills/captcha/scripts/solve_captcha.py +323 -0
  17. package/src/skills/captcha/scripts/solve_image_grid.py +350 -0
  18. package/src/skills/google-merchant-api/SKILL.md +581 -0
  19. package/src/skills/google-merchant-api/references/accounts.md +247 -0
  20. package/src/skills/google-merchant-api/references/content-api-legacy.md +216 -0
  21. package/src/skills/google-merchant-api/references/datasources.md +233 -0
  22. package/src/skills/google-merchant-api/references/inventories.md +201 -0
  23. package/src/skills/google-merchant-api/references/migration.md +267 -0
  24. package/src/skills/google-merchant-api/references/products.md +316 -0
  25. package/src/skills/google-merchant-api/references/promotions.md +201 -0
  26. package/src/skills/google-merchant-api/references/reports.md +240 -0
  27. package/src/skills/lv-aggregators-api/SKILL.md +113 -0
  28. package/src/skills/lv-aggregators-api/references/integration-guide.md +368 -0
  29. package/src/skills/lv-aggregators-api/references/kurpirkt.md +103 -0
  30. package/src/skills/lv-aggregators-api/references/salidzini.md +122 -0
  31. package/src/skills/nest-best-practices/SKILL.md +251 -0
  32. package/src/skills/nest-best-practices/references/best-practices-request-lifecycle.md +158 -0
  33. package/src/skills/nest-best-practices/references/cli-monorepo.md +106 -0
  34. package/src/skills/nest-best-practices/references/cli-overview.md +157 -0
  35. package/src/skills/nest-best-practices/references/core-controllers.md +165 -0
  36. package/src/skills/nest-best-practices/references/core-dependency-injection.md +179 -0
  37. package/src/skills/nest-best-practices/references/core-middleware.md +139 -0
  38. package/src/skills/nest-best-practices/references/core-modules.md +138 -0
  39. package/src/skills/nest-best-practices/references/core-providers.md +188 -0
  40. package/src/skills/nest-best-practices/references/faq-raw-body-hybrid.md +122 -0
  41. package/src/skills/nest-best-practices/references/fundamentals-circular-dependency.md +89 -0
  42. package/src/skills/nest-best-practices/references/fundamentals-custom-decorators.md +107 -0
  43. package/src/skills/nest-best-practices/references/fundamentals-dynamic-modules.md +125 -0
  44. package/src/skills/nest-best-practices/references/fundamentals-exception-filters.md +202 -0
  45. package/src/skills/nest-best-practices/references/fundamentals-execution-context.md +107 -0
  46. package/src/skills/nest-best-practices/references/fundamentals-guards.md +136 -0
  47. package/src/skills/nest-best-practices/references/fundamentals-interceptors.md +187 -0
  48. package/src/skills/nest-best-practices/references/fundamentals-lazy-loading.md +89 -0
  49. package/src/skills/nest-best-practices/references/fundamentals-lifecycle-events.md +87 -0
  50. package/src/skills/nest-best-practices/references/fundamentals-module-reference.md +107 -0
  51. package/src/skills/nest-best-practices/references/fundamentals-pipes.md +197 -0
  52. package/src/skills/nest-best-practices/references/fundamentals-provider-scopes.md +92 -0
  53. package/src/skills/nest-best-practices/references/fundamentals-testing.md +142 -0
  54. package/src/skills/nest-best-practices/references/graphql-overview.md +233 -0
  55. package/src/skills/nest-best-practices/references/graphql-resolvers-mutations.md +199 -0
  56. package/src/skills/nest-best-practices/references/graphql-scalars-unions-enums.md +180 -0
  57. package/src/skills/nest-best-practices/references/graphql-subscriptions.md +228 -0
  58. package/src/skills/nest-best-practices/references/microservices-grpc.md +175 -0
  59. package/src/skills/nest-best-practices/references/microservices-overview.md +221 -0
  60. package/src/skills/nest-best-practices/references/microservices-transports.md +119 -0
  61. package/src/skills/nest-best-practices/references/openapi-swagger.md +207 -0
  62. package/src/skills/nest-best-practices/references/recipes-authentication.md +97 -0
  63. package/src/skills/nest-best-practices/references/recipes-cqrs.md +176 -0
  64. package/src/skills/nest-best-practices/references/recipes-crud-generator.md +87 -0
  65. package/src/skills/nest-best-practices/references/recipes-documentation.md +93 -0
  66. package/src/skills/nest-best-practices/references/recipes-mongoose.md +153 -0
  67. package/src/skills/nest-best-practices/references/recipes-prisma.md +98 -0
  68. package/src/skills/nest-best-practices/references/recipes-terminus.md +148 -0
  69. package/src/skills/nest-best-practices/references/recipes-typeorm.md +122 -0
  70. package/src/skills/nest-best-practices/references/security-authorization.md +196 -0
  71. package/src/skills/nest-best-practices/references/security-cors-helmet-rate-limiting.md +204 -0
  72. package/src/skills/nest-best-practices/references/security-encryption-hashing.md +93 -0
  73. package/src/skills/nest-best-practices/references/techniques-caching.md +142 -0
  74. package/src/skills/nest-best-practices/references/techniques-compression-streaming-sse.md +194 -0
  75. package/src/skills/nest-best-practices/references/techniques-configuration.md +132 -0
  76. package/src/skills/nest-best-practices/references/techniques-database.md +153 -0
  77. package/src/skills/nest-best-practices/references/techniques-events.md +163 -0
  78. package/src/skills/nest-best-practices/references/techniques-fastify.md +137 -0
  79. package/src/skills/nest-best-practices/references/techniques-file-upload.md +140 -0
  80. package/src/skills/nest-best-practices/references/techniques-http-module.md +176 -0
  81. package/src/skills/nest-best-practices/references/techniques-logging.md +146 -0
  82. package/src/skills/nest-best-practices/references/techniques-mvc-serve-static.md +132 -0
  83. package/src/skills/nest-best-practices/references/techniques-queues.md +162 -0
  84. package/src/skills/nest-best-practices/references/techniques-serialization.md +158 -0
  85. package/src/skills/nest-best-practices/references/techniques-sessions-cookies.md +167 -0
  86. package/src/skills/nest-best-practices/references/techniques-task-scheduling.md +166 -0
  87. package/src/skills/nest-best-practices/references/techniques-validation.md +126 -0
  88. package/src/skills/nest-best-practices/references/techniques-versioning.md +153 -0
  89. package/src/skills/nest-best-practices/references/websockets-advanced.md +96 -0
  90. package/src/skills/nest-best-practices/references/websockets-gateways.md +215 -0
  91. package/src/skills/tailwindcss-best-practices/SKILL.md +180 -0
  92. package/src/skills/tailwindcss-best-practices/references/best-practices-utility-patterns.md +87 -0
  93. package/src/skills/tailwindcss-best-practices/references/core-installation.md +109 -0
  94. package/src/skills/tailwindcss-best-practices/references/core-preflight.md +200 -0
  95. package/src/skills/tailwindcss-best-practices/references/core-responsive.md +163 -0
  96. package/src/skills/tailwindcss-best-practices/references/core-source-detection.md +114 -0
  97. package/src/skills/tailwindcss-best-practices/references/core-theme.md +108 -0
  98. package/src/skills/tailwindcss-best-practices/references/core-utility-classes.md +59 -0
  99. package/src/skills/tailwindcss-best-practices/references/core-variants.md +204 -0
  100. package/src/skills/tailwindcss-best-practices/references/effects-form-controls.md +76 -0
  101. package/src/skills/tailwindcss-best-practices/references/effects-mask.md +91 -0
  102. package/src/skills/tailwindcss-best-practices/references/effects-scroll-snap.md +59 -0
  103. package/src/skills/tailwindcss-best-practices/references/effects-text-shadow.md +78 -0
  104. package/src/skills/tailwindcss-best-practices/references/effects-transition-animation.md +80 -0
  105. package/src/skills/tailwindcss-best-practices/references/effects-visibility-interactivity.md +82 -0
  106. package/src/skills/tailwindcss-best-practices/references/features-content-detection.md +175 -0
  107. package/src/skills/tailwindcss-best-practices/references/features-custom-styles.md +203 -0
  108. package/src/skills/tailwindcss-best-practices/references/features-dark-mode.md +137 -0
  109. package/src/skills/tailwindcss-best-practices/references/features-functions-directives.md +241 -0
  110. package/src/skills/tailwindcss-best-practices/references/features-upgrade.md +160 -0
  111. package/src/skills/tailwindcss-best-practices/references/layout-aspect-ratio.md +39 -0
  112. package/src/skills/tailwindcss-best-practices/references/layout-columns.md +80 -0
  113. package/src/skills/tailwindcss-best-practices/references/layout-display.md +110 -0
  114. package/src/skills/tailwindcss-best-practices/references/layout-flexbox.md +112 -0
  115. package/src/skills/tailwindcss-best-practices/references/layout-grid.md +87 -0
  116. package/src/skills/tailwindcss-best-practices/references/layout-height.md +97 -0
  117. package/src/skills/tailwindcss-best-practices/references/layout-inset.md +103 -0
  118. package/src/skills/tailwindcss-best-practices/references/layout-logical-properties.md +92 -0
  119. package/src/skills/tailwindcss-best-practices/references/layout-margin.md +126 -0
  120. package/src/skills/tailwindcss-best-practices/references/layout-min-max-sizing.md +63 -0
  121. package/src/skills/tailwindcss-best-practices/references/layout-object-fit-position.md +64 -0
  122. package/src/skills/tailwindcss-best-practices/references/layout-overflow.md +57 -0
  123. package/src/skills/tailwindcss-best-practices/references/layout-padding.md +77 -0
  124. package/src/skills/tailwindcss-best-practices/references/layout-position.md +85 -0
  125. package/src/skills/tailwindcss-best-practices/references/layout-tables.md +67 -0
  126. package/src/skills/tailwindcss-best-practices/references/layout-width.md +102 -0
  127. package/src/skills/tailwindcss-best-practices/references/transform-base.md +68 -0
  128. package/src/skills/tailwindcss-best-practices/references/transform-rotate.md +70 -0
  129. package/src/skills/tailwindcss-best-practices/references/transform-scale.md +83 -0
  130. package/src/skills/tailwindcss-best-practices/references/transform-skew.md +62 -0
  131. package/src/skills/tailwindcss-best-practices/references/transform-translate.md +77 -0
  132. package/src/skills/tailwindcss-best-practices/references/typography-font-text.md +142 -0
  133. package/src/skills/tailwindcss-best-practices/references/typography-list-style.md +65 -0
  134. package/src/skills/tailwindcss-best-practices/references/typography-text-align.md +60 -0
  135. package/src/skills/tailwindcss-best-practices/references/visual-background.md +76 -0
  136. package/src/skills/tailwindcss-best-practices/references/visual-border.md +108 -0
  137. package/src/skills/tailwindcss-best-practices/references/visual-effects.md +111 -0
  138. package/src/skills/tailwindcss-best-practices/references/visual-svg.md +82 -0
  139. package/src/skills/test-mobile-app/SKILL.md +11 -6
  140. package/src/skills/test-mobile-app/scripts/analyze_apk.py +15 -4
  141. package/src/skills/test-mobile-app/scripts/check_environment.py +5 -5
  142. package/src/skills/test-mobile-app/scripts/run_tests.py +1 -1
  143. package/src/skills/test-web-ui/SKILL.md +264 -84
  144. package/src/skills/test-web-ui/scripts/discover.py +25 -12
  145. package/src/skills/test-web-ui/scripts/run_tests.py +3 -2
  146. package/src/skills/typescript-expert/SKILL.md +145 -0
  147. package/src/skills/typescript-expert/commands/typescript-fix.md +65 -0
  148. package/src/skills/typescript-expert/references/advanced-conditional-types.md +190 -0
  149. package/src/skills/typescript-expert/references/advanced-decorators.md +243 -0
  150. package/src/skills/typescript-expert/references/advanced-mapped-types.md +223 -0
  151. package/src/skills/typescript-expert/references/advanced-template-literals.md +209 -0
  152. package/src/skills/typescript-expert/references/advanced-type-guards.md +308 -0
  153. package/src/skills/typescript-expert/references/best-practices-patterns.md +313 -0
  154. package/src/skills/typescript-expert/references/best-practices-performance.md +185 -0
  155. package/src/skills/typescript-expert/references/best-practices-tsconfig.md +242 -0
  156. package/src/skills/typescript-expert/references/core-generics.md +246 -0
  157. package/src/skills/typescript-expert/references/core-interfaces-types.md +231 -0
  158. package/src/skills/typescript-expert/references/core-type-system.md +261 -0
  159. package/src/skills/typescript-expert/references/core-utility-types.md +235 -0
  160. package/src/skills/typescript-expert/references/features-ts5x.md +370 -0
  161. package/src/skills/vite-best-practices/SKILL.md +115 -0
  162. package/src/skills/vite-best-practices/references/build-and-ssr.md +255 -0
  163. package/src/skills/vite-best-practices/references/core-config.md +231 -0
  164. package/src/skills/vite-best-practices/references/core-features.md +222 -0
  165. package/src/skills/vite-best-practices/references/core-plugin-api.md +294 -0
  166. package/src/skills/vite-best-practices/references/environment-api.md +108 -0
  167. package/src/skills/vite-best-practices/references/rolldown-migration.md +242 -0
  168. package/codex-cli-workspace/iteration-1/benchmark.json +0 -122
  169. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/eval_metadata.json +0 -13
  170. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/grading.json +0 -52
  171. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/outputs/response.md +0 -163
  172. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/with_skill/timing.json +0 -5
  173. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/grading.json +0 -58
  174. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/outputs/response.md +0 -151
  175. package/codex-cli-workspace/iteration-1/eval-1-ci-integration/without_skill/timing.json +0 -5
  176. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -13
  177. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -52
  178. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -86
  179. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
  180. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -58
  181. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
  182. package/codex-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
  183. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/eval_metadata.json +0 -13
  184. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/grading.json +0 -52
  185. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/outputs/response.md +0 -130
  186. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/with_skill/timing.json +0 -5
  187. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/grading.json +0 -64
  188. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/outputs/response.md +0 -209
  189. package/codex-cli-workspace/iteration-1/eval-3-profiles-troubleshooting/without_skill/timing.json +0 -5
  190. package/codex-cli-workspace/iteration-1/review.html +0 -1325
  191. package/gemini-cli-workspace/iteration-1/benchmark.json +0 -86
  192. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/eval_metadata.json +0 -37
  193. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/grading.json +0 -37
  194. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/outputs/response.md +0 -401
  195. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/with_skill/timing.json +0 -5
  196. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/grading.json +0 -37
  197. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/outputs/response.md +0 -405
  198. package/gemini-cli-workspace/iteration-1/eval-1-cicd-setup/without_skill/timing.json +0 -5
  199. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/eval_metadata.json +0 -37
  200. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/grading.json +0 -37
  201. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -212
  202. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/with_skill/timing.json +0 -5
  203. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/grading.json +0 -37
  204. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -427
  205. package/gemini-cli-workspace/iteration-1/eval-2-mcp-server-config/without_skill/timing.json +0 -5
  206. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/eval_metadata.json +0 -32
  207. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/grading.json +0 -32
  208. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -171
  209. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/with_skill/timing.json +0 -5
  210. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/grading.json +0 -32
  211. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -199
  212. package/gemini-cli-workspace/iteration-1/eval-3-custom-slash-command/without_skill/timing.json +0 -5
  213. package/gemini-cli-workspace/iteration-1/review.html +0 -1325
  214. package/gemini-cli-workspace/iteration-2/benchmark.json +0 -173
  215. package/gemini-cli-workspace/iteration-2/benchmark.md +0 -28
  216. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/eval_metadata.json +0 -37
  217. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/grading.json +0 -37
  218. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/outputs/response.md +0 -195
  219. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/with_skill/timing.json +0 -5
  220. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/grading.json +0 -37
  221. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/outputs/response.md +0 -377
  222. package/gemini-cli-workspace/iteration-2/eval-1-cicd-setup/without_skill/timing.json +0 -5
  223. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/eval_metadata.json +0 -37
  224. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/grading.json +0 -37
  225. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/outputs/response.md +0 -127
  226. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/with_skill/timing.json +0 -5
  227. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/grading.json +0 -37
  228. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/outputs/response.md +0 -164
  229. package/gemini-cli-workspace/iteration-2/eval-2-mcp-server-config/without_skill/timing.json +0 -5
  230. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/eval_metadata.json +0 -32
  231. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/grading.json +0 -32
  232. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/outputs/response.md +0 -91
  233. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/with_skill/timing.json +0 -5
  234. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/grading.json +0 -32
  235. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/outputs/response.md +0 -112
  236. package/gemini-cli-workspace/iteration-2/eval-3-custom-slash-command/without_skill/timing.json +0 -5
  237. package/gemini-cli-workspace/iteration-2/eval-viewer.html +0 -1325
  238. package/screen-recording-workspace/evals.json +0 -41
  239. package/screen-recording-workspace/iteration-1/benchmark.json +0 -102
  240. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/eval_metadata.json +0 -31
  241. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/grading.json +0 -11
  242. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/outputs/demo.mp4 +0 -0
  243. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/with_skill/timing.json +0 -5
  244. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/grading.json +0 -11
  245. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/outputs/demo.mp4 +0 -0
  246. package/screen-recording-workspace/iteration-1/eval-0-fullscreen/without_skill/timing.json +0 -5
  247. package/screen-recording-workspace/iteration-1/eval-1-region-audio/eval_metadata.json +0 -31
  248. package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/grading.json +0 -11
  249. package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/outputs/region_capture.mp4 +0 -0
  250. package/screen-recording-workspace/iteration-1/eval-1-region-audio/with_skill/timing.json +0 -5
  251. package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/grading.json +0 -11
  252. package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/outputs/region_capture.mp4 +0 -0
  253. package/screen-recording-workspace/iteration-1/eval-1-region-audio/without_skill/timing.json +0 -5
  254. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/eval_metadata.json +0 -31
  255. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/grading.json +0 -11
  256. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/outputs/fallback_recording.mp4 +0 -0
  257. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/with_skill/timing.json +0 -5
  258. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/grading.json +0 -11
  259. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/fallback_recording.mp4 +0 -0
  260. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/outputs/record_screen.py +0 -67
  261. package/screen-recording-workspace/iteration-1/eval-2-python-fallback/without_skill/timing.json +0 -5
  262. package/screen-recording-workspace/iteration-1/review.html +0 -1325
  263. package/src/skills/codex-cli/evals/evals.json +0 -47
  264. package/src/skills/gemini-cli/evals/evals.json +0 -46
  265. package/src/skills/tm-search/evals/evals.json +0 -23
@@ -2,9 +2,10 @@ import { execFileSync } from 'node:child_process';
2
2
  import { existsSync, readFileSync, readdirSync, cpSync, rmSync, mkdirSync, writeFileSync, statSync } from 'node:fs';
3
3
  import { join, basename } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
- import { getSkillsDir } from '../../config.js';
5
+ import { getSkillsDir, getPluginsDir } from '../../config.js';
6
6
  import { fetchRegistry, findPlugin } from '../../registry.js';
7
7
  import { log, spinner } from '../../utils.js';
8
+ import { hasPluginComponents, detectComponents, findInstalledSkill } from './resolve.js';
8
9
 
9
10
  export function parseFrontmatter(content) {
10
11
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
@@ -142,18 +143,30 @@ export async function add(source, options = {}) {
142
143
  const frontmatter = parseFrontmatter(skillMd);
143
144
  const skillName = frontmatter.name || options.skill || basename(targetDir === tmpDir ? repoUrl.replace(/\.git$/, '').split('/').pop() : targetDir);
144
145
 
145
- const skillsDir = getSkillsDir();
146
- const dest = join(skillsDir, skillName);
146
+ // Detect plugin components (commands, hooks, agents) alongside SKILL.md
147
+ const components = detectComponents(targetDir);
148
+ const installAsPlugin = hasPluginComponents(targetDir);
147
149
 
148
- if (existsSync(dest)) {
149
- log.warn(`Skill "${skillName}" is already installed at ${dest}`);
150
+ const destDir = installAsPlugin ? getPluginsDir() : getSkillsDir();
151
+ const dest = join(destDir, skillName);
152
+
153
+ // Check both locations for existing installation
154
+ const existing = findInstalledSkill(skillName);
155
+ if (existing) {
156
+ log.warn(`Skill "${skillName}" is already installed at ${existing.dir}`);
150
157
  log.dim(`Run "claude-plugins skills update ${skillName}" to update it`);
151
158
  rmSync(tmpDir, { recursive: true, force: true });
152
159
  return;
153
160
  }
154
161
 
155
- // Copy skill files
156
- const spin2 = spinner(`Installing skill "${skillName}"...`);
162
+ if (existsSync(dest)) {
163
+ log.warn(`"${skillName}" already exists at ${dest}`);
164
+ rmSync(tmpDir, { recursive: true, force: true });
165
+ return;
166
+ }
167
+
168
+ const label = installAsPlugin ? 'skill + components' : 'skill';
169
+ const spin2 = spinner(`Installing ${label} "${skillName}"...`);
157
170
  spin2.start();
158
171
 
159
172
  try {
@@ -165,6 +178,25 @@ export async function add(source, options = {}) {
165
178
  rmSync(gitInDest, { recursive: true, force: true });
166
179
  }
167
180
 
181
+ // Generate .claude-plugin/plugin.json if installing as plugin and none exists
182
+ if (installAsPlugin && !existsSync(join(dest, '.claude-plugin', 'plugin.json'))) {
183
+ const pluginDir = join(dest, '.claude-plugin');
184
+ mkdirSync(pluginDir, { recursive: true });
185
+
186
+ const pluginJson = {
187
+ name: skillName,
188
+ version: '1.0.0',
189
+ description: frontmatter.description || `Skill: ${skillName}`,
190
+ commands: listCommandFiles(dest),
191
+ _generatedBy: 'claude-plugins skills add',
192
+ };
193
+
194
+ writeFileSync(
195
+ join(pluginDir, 'plugin.json'),
196
+ JSON.stringify(pluginJson, null, 2)
197
+ );
198
+ }
199
+
168
200
  // Write origin metadata
169
201
  writeFileSync(
170
202
  join(dest, '.origin.json'),
@@ -172,6 +204,8 @@ export async function add(source, options = {}) {
172
204
  {
173
205
  repository: repoUrl,
174
206
  skill: options.skill || null,
207
+ installedAs: installAsPlugin ? 'plugin-skill' : 'skill',
208
+ components,
175
209
  installedAt: new Date().toISOString(),
176
210
  },
177
211
  null,
@@ -184,6 +218,13 @@ export async function add(source, options = {}) {
184
218
  if (frontmatter.description) {
185
219
  log.dim(` ${frontmatter.description}`);
186
220
  }
221
+
222
+ if (installAsPlugin) {
223
+ const extras = components.filter((c) => c !== 'skill');
224
+ log.info(`Detected: ${components.join(', ')}`);
225
+ log.dim(`Installed as plugin so Claude Code discovers ${extras.join(', ')}`);
226
+ }
227
+
187
228
  log.dim('\nRestart Claude Code to load the skill.');
188
229
  } catch (err) {
189
230
  spin2.fail(`Failed to install skill "${skillName}"`);
@@ -192,3 +233,18 @@ export async function add(source, options = {}) {
192
233
  rmSync(tmpDir, { recursive: true, force: true });
193
234
  }
194
235
  }
236
+
237
+ /**
238
+ * List command file names (without extension) from a commands/ directory.
239
+ */
240
+ function listCommandFiles(dir) {
241
+ const cmdsDir = join(dir, 'commands');
242
+ if (!existsSync(cmdsDir)) return [];
243
+ try {
244
+ return readdirSync(cmdsDir)
245
+ .filter((f) => f.endsWith('.md'))
246
+ .map((f) => `/${f.replace(/\.md$/, '')}`);
247
+ } catch {
248
+ return [];
249
+ }
250
+ }
@@ -1,52 +1,23 @@
1
- import { readdirSync, existsSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import chalk from 'chalk';
4
- import { getSkillsDir } from '../../config.js';
5
- import { log, formatTable, truncate } from '../../utils.js';
6
- import { parseFrontmatter } from './add.js';
7
-
8
- export async function list() {
9
- const skillsDir = getSkillsDir();
10
- const entries = readdirSync(skillsDir, { withFileTypes: true }).filter(
11
- (e) => e.isDirectory()
12
- );
13
-
14
- if (!entries.length) {
15
- log.info('No skills installed');
16
- log.dim('Run "claude-plugins skills add <source>" to install a skill');
17
- return;
18
- }
19
-
20
- console.log(chalk.bold(`\n ${entries.length} skill${entries.length === 1 ? '' : 's'} installed\n`));
21
-
22
- const rows = entries.map((entry) => {
23
- const dir = join(skillsDir, entry.name);
24
- const skillMdPath = join(dir, 'SKILL.md');
25
- const originPath = join(dir, '.origin.json');
26
- let description = '';
27
- let repo = '-';
28
-
29
- if (existsSync(skillMdPath)) {
30
- try {
31
- const fm = parseFrontmatter(readFileSync(skillMdPath, 'utf-8'));
32
- description = fm.description || '';
33
- } catch {
34
- // ignore
35
- }
36
- }
37
-
38
- if (existsSync(originPath)) {
39
- try {
40
- const origin = JSON.parse(readFileSync(originPath, 'utf-8'));
41
- repo = origin.repository || '-';
42
- } catch {
43
- // ignore
44
- }
45
- }
46
-
47
- return [entry.name, truncate(description, 50), truncate(repo, 40)];
48
- });
49
-
50
- formatTable(rows, ['Name', 'Description', 'Repository']);
51
- console.log();
52
- }
1
+ import chalk from 'chalk';
2
+ import { log, formatTable, truncate } from '../../utils.js';
3
+ import { listAllSkills } from './resolve.js';
4
+
5
+ export async function list() {
6
+ const skills = listAllSkills();
7
+
8
+ if (!skills.length) {
9
+ log.info('No skills installed');
10
+ log.dim('Run "claude-plugins skills add <source>" to install a skill');
11
+ return;
12
+ }
13
+
14
+ console.log(chalk.bold(`\n ${skills.length} skill${skills.length === 1 ? '' : 's'} installed\n`));
15
+
16
+ const rows = skills.map(({ name, meta, location }) => {
17
+ const type = location === 'plugins' ? chalk.cyan('plugin') : chalk.dim('skill');
18
+ return [name, truncate(meta.description, 45), type, truncate(meta.repository, 35)];
19
+ });
20
+
21
+ formatTable(rows, ['Name', 'Description', 'Type', 'Repository']);
22
+ console.log();
23
+ }
@@ -1,27 +1,26 @@
1
- import { existsSync, rmSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { getSkillsDir } from '../../config.js';
4
- import { log, spinner } from '../../utils.js';
5
-
6
- export async function remove(name) {
7
- const dest = join(getSkillsDir(), name);
8
-
9
- if (!existsSync(dest)) {
10
- log.error(`Skill "${name}" is not installed`);
11
- log.dim('Run "claude-plugins skills list" to see installed skills');
12
- process.exit(1);
13
- }
14
-
15
- const spin = spinner(`Removing skill "${name}"...`);
16
- spin.start();
17
-
18
- try {
19
- rmSync(dest, { recursive: true, force: true });
20
- spin.succeed(`Removed skill "${name}"`);
21
- log.dim('Restart Claude Code to apply changes.');
22
- } catch (err) {
23
- spin.fail(`Failed to remove skill "${name}"`);
24
- log.error(err.message);
25
- process.exit(1);
26
- }
27
- }
1
+ import { rmSync } from 'node:fs';
2
+ import { log, spinner } from '../../utils.js';
3
+ import { findInstalledSkill } from './resolve.js';
4
+
5
+ export async function remove(name) {
6
+ const found = findInstalledSkill(name);
7
+
8
+ if (!found) {
9
+ log.error(`Skill "${name}" is not installed`);
10
+ log.dim('Run "claude-plugins skills list" to see installed skills');
11
+ process.exit(1);
12
+ }
13
+
14
+ const spin = spinner(`Removing skill "${name}"...`);
15
+ spin.start();
16
+
17
+ try {
18
+ rmSync(found.dir, { recursive: true, force: true });
19
+ spin.succeed(`Removed skill "${name}" from ${found.location}`);
20
+ log.dim('Restart Claude Code to apply changes.');
21
+ } catch (err) {
22
+ spin.fail(`Failed to remove skill "${name}"`);
23
+ log.error(err.message);
24
+ process.exit(1);
25
+ }
26
+ }
@@ -0,0 +1,155 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { getSkillsDir, getPluginsDir } from '../../config.js';
4
+ import { parseFrontmatter } from './add.js';
5
+
6
+ /**
7
+ * Plugin component directories that Claude Code auto-discovers.
8
+ * When a skill repo contains any of these, it must be installed
9
+ * as a plugin so Claude Code can find them.
10
+ */
11
+ export const PLUGIN_COMPONENT_DIRS = ['commands', 'hooks', 'agents'];
12
+
13
+ /**
14
+ * Check if a directory contains plugin components (commands, hooks, agents)
15
+ * beyond just SKILL.md + references.
16
+ */
17
+ export function hasPluginComponents(dir) {
18
+ return PLUGIN_COMPONENT_DIRS.some((name) => {
19
+ const p = join(dir, name);
20
+ return existsSync(p);
21
+ });
22
+ }
23
+
24
+ /**
25
+ * Detect which plugin components exist in a directory.
26
+ * Returns an array of found component names.
27
+ */
28
+ export function detectComponents(dir) {
29
+ const found = [];
30
+ if (existsSync(join(dir, 'SKILL.md'))) found.push('skill');
31
+ for (const name of PLUGIN_COMPONENT_DIRS) {
32
+ if (existsSync(join(dir, name))) found.push(name);
33
+ }
34
+ return found;
35
+ }
36
+
37
+ /**
38
+ * Read .origin.json from a skill/plugin directory.
39
+ */
40
+ export function readOrigin(dir) {
41
+ const originPath = join(dir, '.origin.json');
42
+ if (!existsSync(originPath)) return null;
43
+ try {
44
+ return JSON.parse(readFileSync(originPath, 'utf-8'));
45
+ } catch {
46
+ return null;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Read skill metadata from a directory (SKILL.md frontmatter + .origin.json).
52
+ */
53
+ export function readSkillMeta(dir, dirName) {
54
+ const skillMdPath = join(dir, 'SKILL.md');
55
+ const meta = { name: dirName, description: '', repository: '-' };
56
+
57
+ if (existsSync(skillMdPath)) {
58
+ try {
59
+ const fm = parseFrontmatter(readFileSync(skillMdPath, 'utf-8'));
60
+ meta.name = fm.name || dirName;
61
+ meta.description = fm.description || '';
62
+ } catch {
63
+ // ignore
64
+ }
65
+ }
66
+
67
+ const origin = readOrigin(dir);
68
+ if (origin) {
69
+ meta.repository = origin.repository || '-';
70
+ meta.installedAs = origin.installedAs || 'skill';
71
+ meta.skill = origin.skill || null;
72
+ }
73
+
74
+ return meta;
75
+ }
76
+
77
+ /**
78
+ * Find a skill by name across both ~/.claude/skills/ and ~/.claude/plugins/.
79
+ * Returns { dir, location } or null.
80
+ */
81
+ export function findInstalledSkill(name) {
82
+ const skillsDir = getSkillsDir();
83
+ const pluginsDir = getPluginsDir();
84
+
85
+ // Check ~/.claude/skills/ first
86
+ const skillPath = join(skillsDir, name);
87
+ if (existsSync(skillPath) && existsSync(join(skillPath, 'SKILL.md'))) {
88
+ return { dir: skillPath, location: 'skills' };
89
+ }
90
+
91
+ // Check ~/.claude/plugins/ for skills installed as plugins
92
+ const pluginPath = join(pluginsDir, name);
93
+ if (existsSync(pluginPath)) {
94
+ const origin = readOrigin(pluginPath);
95
+ if (origin && origin.installedAs === 'plugin-skill') {
96
+ return { dir: pluginPath, location: 'plugins' };
97
+ }
98
+ // Also check if it has a SKILL.md (might be installed via skills add)
99
+ if (existsSync(join(pluginPath, 'SKILL.md'))) {
100
+ return { dir: pluginPath, location: 'plugins' };
101
+ }
102
+ }
103
+
104
+ return null;
105
+ }
106
+
107
+ /**
108
+ * List all installed skills from both directories.
109
+ * Returns array of { name, dir, location, meta }.
110
+ */
111
+ export function listAllSkills() {
112
+ const skillsDir = getSkillsDir();
113
+ const pluginsDir = getPluginsDir();
114
+ const results = [];
115
+
116
+ // Skills from ~/.claude/skills/
117
+ try {
118
+ const entries = readdirSync(skillsDir, { withFileTypes: true });
119
+ for (const entry of entries) {
120
+ if (!entry.isDirectory()) continue;
121
+ const dir = join(skillsDir, entry.name);
122
+ if (!existsSync(join(dir, 'SKILL.md'))) continue;
123
+ results.push({
124
+ name: entry.name,
125
+ dir,
126
+ location: 'skills',
127
+ meta: readSkillMeta(dir, entry.name),
128
+ });
129
+ }
130
+ } catch {
131
+ // directory might not exist yet
132
+ }
133
+
134
+ // Skills from ~/.claude/plugins/ (installed as plugin-skill)
135
+ try {
136
+ const entries = readdirSync(pluginsDir, { withFileTypes: true });
137
+ for (const entry of entries) {
138
+ if (!entry.isDirectory()) continue;
139
+ const dir = join(pluginsDir, entry.name);
140
+ const origin = readOrigin(dir);
141
+ if (origin && origin.installedAs === 'plugin-skill') {
142
+ results.push({
143
+ name: entry.name,
144
+ dir,
145
+ location: 'plugins',
146
+ meta: readSkillMeta(dir, entry.name),
147
+ });
148
+ }
149
+ }
150
+ } catch {
151
+ // directory might not exist yet
152
+ }
153
+
154
+ return results;
155
+ }
@@ -1,74 +1,58 @@
1
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { getSkillsDir } from '../../config.js';
4
- import { log, spinner } from '../../utils.js';
5
- import { add } from './add.js';
6
- import { remove } from './remove.js';
7
-
8
- function readOrigin(skillDir) {
9
- const originPath = join(skillDir, '.origin.json');
10
- if (!existsSync(originPath)) return null;
11
- try {
12
- return JSON.parse(readFileSync(originPath, 'utf-8'));
13
- } catch {
14
- return null;
15
- }
16
- }
17
-
18
- async function updateOne(name) {
19
- const skillsDir = getSkillsDir();
20
- const dest = join(skillsDir, name);
21
-
22
- if (!existsSync(dest)) {
23
- log.error(`Skill "${name}" is not installed`);
24
- return false;
25
- }
26
-
27
- const origin = readOrigin(dest);
28
- if (!origin || !origin.repository) {
29
- log.warn(`Skill "${name}" has no origin metadata, skipping`);
30
- return false;
31
- }
32
-
33
- const spin = spinner(`Updating skill "${name}"...`);
34
- spin.start();
35
- spin.stop();
36
-
37
- try {
38
- // Remove and re-add
39
- await remove(name);
40
- await add(origin.repository, { skill: origin.skill || undefined });
41
- return true;
42
- } catch (err) {
43
- log.error(`Failed to update skill "${name}": ${err.message}`);
44
- return false;
45
- }
46
- }
47
-
48
- export async function update(name) {
49
- if (name) {
50
- await updateOne(name);
51
- return;
52
- }
53
-
54
- const skillsDir = getSkillsDir();
55
- const entries = readdirSync(skillsDir, { withFileTypes: true }).filter(
56
- (e) => e.isDirectory()
57
- );
58
-
59
- if (!entries.length) {
60
- log.info('No skills installed');
61
- return;
62
- }
63
-
64
- log.info(`Updating ${entries.length} skill${entries.length === 1 ? '' : 's'}...\n`);
65
-
66
- let updated = 0;
67
- for (const entry of entries) {
68
- if (await updateOne(entry.name)) updated++;
69
- }
70
-
71
- console.log();
72
- log.success(`${updated}/${entries.length} skills updated`);
73
- log.dim('Restart Claude Code to apply changes.');
74
- }
1
+ import { log, spinner } from '../../utils.js';
2
+ import { findInstalledSkill, listAllSkills, readOrigin } from './resolve.js';
3
+ import { add } from './add.js';
4
+ import { remove } from './remove.js';
5
+
6
+ async function updateOne(name) {
7
+ const found = findInstalledSkill(name);
8
+
9
+ if (!found) {
10
+ log.error(`Skill "${name}" is not installed`);
11
+ return false;
12
+ }
13
+
14
+ const origin = readOrigin(found.dir);
15
+ if (!origin || !origin.repository) {
16
+ log.warn(`Skill "${name}" has no origin metadata, skipping`);
17
+ return false;
18
+ }
19
+
20
+ const spin = spinner(`Updating skill "${name}"...`);
21
+ spin.start();
22
+ spin.stop();
23
+
24
+ try {
25
+ // Remove and re-add
26
+ await remove(name);
27
+ await add(origin.repository, { skill: origin.skill || undefined });
28
+ return true;
29
+ } catch (err) {
30
+ log.error(`Failed to update skill "${name}": ${err.message}`);
31
+ return false;
32
+ }
33
+ }
34
+
35
+ export async function update(name) {
36
+ if (name) {
37
+ await updateOne(name);
38
+ return;
39
+ }
40
+
41
+ const skills = listAllSkills();
42
+
43
+ if (!skills.length) {
44
+ log.info('No skills installed');
45
+ return;
46
+ }
47
+
48
+ log.info(`Updating ${skills.length} skill${skills.length === 1 ? '' : 's'}...\n`);
49
+
50
+ let updated = 0;
51
+ for (const skill of skills) {
52
+ if (await updateOne(skill.name)) updated++;
53
+ }
54
+
55
+ console.log();
56
+ log.success(`${updated}/${skills.length} skills updated`);
57
+ log.dim('Restart Claude Code to apply changes.');
58
+ }