@vodailoc/kilo-kit-mcp 1.1.0 → 1.2.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 (582) hide show
  1. package/.mcp/kilo-kit.codex-windows.toml +5 -0
  2. package/LICENSE +190 -190
  3. package/QUICKSTART.md +265 -255
  4. package/README.md +321 -267
  5. package/mcp/README.md +64 -12
  6. package/mcp/dist/formatters.js +142 -1
  7. package/mcp/dist/orchestration-audit.js +20 -0
  8. package/mcp/dist/orchestration-memory.js +258 -0
  9. package/mcp/dist/orchestration-types.js +1 -0
  10. package/mcp/dist/orchestrator.js +222 -0
  11. package/mcp/dist/question-templates.js +249 -0
  12. package/mcp/dist/route-analytics.js +149 -0
  13. package/mcp/dist/router.js +75 -82
  14. package/mcp/dist/routing-policy-data.js +241 -0
  15. package/mcp/dist/routing-policy.js +145 -0
  16. package/mcp/dist/server.js +93 -4
  17. package/mcp/dist/smoke-env.js +18 -0
  18. package/mcp/dist/smoke.js +68 -1
  19. package/mcp/package.json +1 -2
  20. package/package.json +3 -2
  21. package/skills/README.md +647 -647
  22. package/skills/SKILLS_INDEX.md +139 -139
  23. package/skills/ai-media/ai-multimodal/.env.example +97 -97
  24. package/skills/ai-media/ai-multimodal/SKILL.md +357 -357
  25. package/skills/ai-media/ai-multimodal/references/audio-processing.md +373 -373
  26. package/skills/ai-media/ai-multimodal/references/image-generation.md +558 -558
  27. package/skills/ai-media/ai-multimodal/references/video-analysis.md +502 -502
  28. package/skills/ai-media/ai-multimodal/references/vision-understanding.md +483 -483
  29. package/skills/ai-media/ai-multimodal/scripts/document_converter.py +395 -395
  30. package/skills/ai-media/ai-multimodal/scripts/gemini_batch_process.py +480 -480
  31. package/skills/ai-media/ai-multimodal/scripts/media_optimizer.py +506 -506
  32. package/skills/ai-media/ai-multimodal/scripts/requirements.txt +26 -26
  33. package/skills/ai-media/ai-multimodal/scripts/tests/requirements.txt +20 -20
  34. package/skills/ai-media/ai-multimodal/scripts/tests/test_document_converter.py +299 -299
  35. package/skills/ai-media/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -362
  36. package/skills/ai-media/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -373
  37. package/skills/ai-media/media-processing/SKILL.md +358 -358
  38. package/skills/ai-media/media-processing/references/ffmpeg-encoding.md +358 -358
  39. package/skills/ai-media/media-processing/references/ffmpeg-filters.md +503 -503
  40. package/skills/ai-media/media-processing/references/ffmpeg-streaming.md +403 -403
  41. package/skills/ai-media/media-processing/references/format-compatibility.md +375 -375
  42. package/skills/ai-media/media-processing/references/imagemagick-batch.md +612 -612
  43. package/skills/ai-media/media-processing/references/imagemagick-editing.md +623 -623
  44. package/skills/ai-media/media-processing/scripts/batch_resize.py +342 -342
  45. package/skills/ai-media/media-processing/scripts/media_convert.py +311 -311
  46. package/skills/ai-media/media-processing/scripts/requirements.txt +24 -24
  47. package/skills/ai-media/media-processing/scripts/tests/requirements.txt +2 -2
  48. package/skills/ai-media/media-processing/scripts/tests/test_batch_resize.py +372 -372
  49. package/skills/ai-media/media-processing/scripts/tests/test_media_convert.py +259 -259
  50. package/skills/ai-media/media-processing/scripts/tests/test_video_optimize.py +397 -397
  51. package/skills/ai-media/media-processing/scripts/video_optimize.py +414 -414
  52. package/skills/ai-media/screenshot/LICENSE.txt +201 -201
  53. package/skills/ai-media/screenshot/SKILL.md +267 -267
  54. package/skills/ai-media/screenshot/agents/openai.yaml +6 -6
  55. package/skills/ai-media/screenshot/assets/screenshot-small.svg +5 -5
  56. package/skills/ai-media/screenshot/scripts/ensure_macos_permissions.sh +54 -54
  57. package/skills/ai-media/screenshot/scripts/macos_display_info.swift +22 -22
  58. package/skills/ai-media/screenshot/scripts/macos_permissions.swift +40 -40
  59. package/skills/ai-media/screenshot/scripts/macos_window_info.swift +126 -126
  60. package/skills/ai-media/screenshot/scripts/take_screenshot.ps1 +163 -163
  61. package/skills/ai-media/screenshot/scripts/take_screenshot.py +585 -585
  62. package/skills/ai-media/sora/LICENSE.txt +201 -201
  63. package/skills/ai-media/sora/SKILL.md +153 -153
  64. package/skills/ai-media/sora/agents/openai.yaml +6 -6
  65. package/skills/ai-media/sora/assets/sora-small.svg +4 -4
  66. package/skills/ai-media/sora/references/cinematic-shots.md +53 -53
  67. package/skills/ai-media/sora/references/cli.md +248 -248
  68. package/skills/ai-media/sora/references/codex-network.md +28 -28
  69. package/skills/ai-media/sora/references/prompting.md +137 -137
  70. package/skills/ai-media/sora/references/sample-prompts.md +95 -95
  71. package/skills/ai-media/sora/references/social-ads.md +42 -42
  72. package/skills/ai-media/sora/references/troubleshooting.md +58 -58
  73. package/skills/ai-media/sora/references/video-api.md +45 -45
  74. package/skills/ai-media/sora/scripts/sora.py +970 -970
  75. package/skills/design/aesthetic/SKILL.md +121 -121
  76. package/skills/design/aesthetic/assets/design-guideline-template.md +163 -163
  77. package/skills/design/aesthetic/assets/design-story-template.md +135 -135
  78. package/skills/design/aesthetic/references/design-principles.md +62 -62
  79. package/skills/design/aesthetic/references/design-resources.md +75 -75
  80. package/skills/design/aesthetic/references/micro-interactions.md +53 -53
  81. package/skills/design/aesthetic/references/storytelling-design.md +50 -50
  82. package/skills/design/figma/LICENSE.txt +202 -202
  83. package/skills/design/figma/SKILL.md +42 -42
  84. package/skills/design/figma/agents/openai.yaml +14 -14
  85. package/skills/design/figma/assets/figma-small.svg +3 -3
  86. package/skills/design/figma/assets/icon.svg +28 -28
  87. package/skills/design/figma/references/figma-mcp-config.md +35 -35
  88. package/skills/design/figma/references/figma-tools-and-prompts.md +34 -34
  89. package/skills/design/figma-implement-design/LICENSE.txt +202 -202
  90. package/skills/design/figma-implement-design/SKILL.md +264 -264
  91. package/skills/design/figma-implement-design/agents/openai.yaml +14 -14
  92. package/skills/design/figma-implement-design/assets/figma-small.svg +3 -3
  93. package/skills/design/figma-implement-design/assets/icon.svg +28 -28
  94. package/skills/design/frontend-design/SKILL.md +41 -41
  95. package/skills/design/frontend-design/references/animejs.md +395 -395
  96. package/skills/design/ui-styling/LICENSE.txt +201 -201
  97. package/skills/design/ui-styling/SKILL.md +321 -321
  98. package/skills/design/ui-styling/canvas-fonts/ArsenalSC-OFL.txt +93 -93
  99. package/skills/design/ui-styling/canvas-fonts/BigShoulders-OFL.txt +93 -93
  100. package/skills/design/ui-styling/canvas-fonts/Boldonse-OFL.txt +93 -93
  101. package/skills/design/ui-styling/canvas-fonts/BricolageGrotesque-OFL.txt +93 -93
  102. package/skills/design/ui-styling/canvas-fonts/CrimsonPro-OFL.txt +93 -93
  103. package/skills/design/ui-styling/canvas-fonts/DMMono-OFL.txt +93 -93
  104. package/skills/design/ui-styling/canvas-fonts/EricaOne-OFL.txt +94 -94
  105. package/skills/design/ui-styling/canvas-fonts/GeistMono-OFL.txt +93 -93
  106. package/skills/design/ui-styling/canvas-fonts/Gloock-OFL.txt +93 -93
  107. package/skills/design/ui-styling/canvas-fonts/IBMPlexMono-OFL.txt +93 -93
  108. package/skills/design/ui-styling/canvas-fonts/InstrumentSans-OFL.txt +93 -93
  109. package/skills/design/ui-styling/canvas-fonts/Italiana-OFL.txt +93 -93
  110. package/skills/design/ui-styling/canvas-fonts/JetBrainsMono-OFL.txt +93 -93
  111. package/skills/design/ui-styling/canvas-fonts/Jura-OFL.txt +93 -93
  112. package/skills/design/ui-styling/canvas-fonts/LibreBaskerville-OFL.txt +93 -93
  113. package/skills/design/ui-styling/canvas-fonts/Lora-OFL.txt +93 -93
  114. package/skills/design/ui-styling/canvas-fonts/NationalPark-OFL.txt +93 -93
  115. package/skills/design/ui-styling/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -93
  116. package/skills/design/ui-styling/canvas-fonts/Outfit-OFL.txt +93 -93
  117. package/skills/design/ui-styling/canvas-fonts/PixelifySans-OFL.txt +93 -93
  118. package/skills/design/ui-styling/canvas-fonts/PoiretOne-OFL.txt +93 -93
  119. package/skills/design/ui-styling/canvas-fonts/RedHatMono-OFL.txt +93 -93
  120. package/skills/design/ui-styling/canvas-fonts/Silkscreen-OFL.txt +93 -93
  121. package/skills/design/ui-styling/canvas-fonts/SmoochSans-OFL.txt +93 -93
  122. package/skills/design/ui-styling/canvas-fonts/Tektur-OFL.txt +93 -93
  123. package/skills/design/ui-styling/canvas-fonts/WorkSans-OFL.txt +93 -93
  124. package/skills/design/ui-styling/canvas-fonts/YoungSerif-OFL.txt +93 -93
  125. package/skills/design/ui-styling/references/canvas-design-system.md +320 -320
  126. package/skills/design/ui-styling/references/shadcn-accessibility.md +471 -471
  127. package/skills/design/ui-styling/references/shadcn-components.md +424 -424
  128. package/skills/design/ui-styling/references/shadcn-theming.md +373 -373
  129. package/skills/design/ui-styling/references/tailwind-customization.md +483 -483
  130. package/skills/design/ui-styling/references/tailwind-responsive.md +382 -382
  131. package/skills/design/ui-styling/references/tailwind-utilities.md +455 -455
  132. package/skills/design/ui-styling/scripts/requirements.txt +17 -17
  133. package/skills/design/ui-styling/scripts/shadcn_add.py +292 -292
  134. package/skills/design/ui-styling/scripts/tailwind_config_gen.py +456 -456
  135. package/skills/design/ui-styling/scripts/tests/requirements.txt +3 -3
  136. package/skills/design/ui-styling/scripts/tests/test_shadcn_add.py +266 -266
  137. package/skills/design/ui-styling/scripts/tests/test_tailwind_config_gen.py +336 -336
  138. package/skills/engineering/aspnet-core/LICENSE.txt +201 -201
  139. package/skills/engineering/aspnet-core/SKILL.md +61 -61
  140. package/skills/engineering/aspnet-core/agents/openai.yaml +5 -5
  141. package/skills/engineering/aspnet-core/references/_sections.md +40 -40
  142. package/skills/engineering/aspnet-core/references/apis-minimal-and-controllers.md +81 -81
  143. package/skills/engineering/aspnet-core/references/data-state-and-services.md +69 -69
  144. package/skills/engineering/aspnet-core/references/program-and-pipeline.md +103 -103
  145. package/skills/engineering/aspnet-core/references/realtime-grpc-and-background-work.md +58 -58
  146. package/skills/engineering/aspnet-core/references/security-and-identity.md +75 -75
  147. package/skills/engineering/aspnet-core/references/source-map.md +43 -43
  148. package/skills/engineering/aspnet-core/references/stack-selection.md +63 -63
  149. package/skills/engineering/aspnet-core/references/testing-performance-and-operations.md +92 -92
  150. package/skills/engineering/aspnet-core/references/ui-blazor.md +53 -53
  151. package/skills/engineering/aspnet-core/references/ui-mvc.md +56 -56
  152. package/skills/engineering/aspnet-core/references/ui-razor-pages.md +55 -55
  153. package/skills/engineering/aspnet-core/references/versioning-and-upgrades.md +51 -51
  154. package/skills/engineering/backend-development/SKILL.md +95 -95
  155. package/skills/engineering/backend-development/references/backend-api-design.md +495 -495
  156. package/skills/engineering/backend-development/references/backend-architecture.md +454 -454
  157. package/skills/engineering/backend-development/references/backend-authentication.md +338 -338
  158. package/skills/engineering/backend-development/references/backend-code-quality.md +659 -659
  159. package/skills/engineering/backend-development/references/backend-debugging.md +904 -904
  160. package/skills/engineering/backend-development/references/backend-devops.md +494 -494
  161. package/skills/engineering/backend-development/references/backend-mindset.md +387 -387
  162. package/skills/engineering/backend-development/references/backend-performance.md +397 -397
  163. package/skills/engineering/backend-development/references/backend-security.md +290 -290
  164. package/skills/engineering/backend-development/references/backend-technologies.md +256 -256
  165. package/skills/engineering/backend-development/references/backend-testing.md +429 -429
  166. package/skills/engineering/better-auth/SKILL.md +204 -204
  167. package/skills/engineering/better-auth/references/advanced-features.md +553 -553
  168. package/skills/engineering/better-auth/references/database-integration.md +577 -577
  169. package/skills/engineering/better-auth/references/email-password-auth.md +416 -416
  170. package/skills/engineering/better-auth/references/oauth-providers.md +430 -430
  171. package/skills/engineering/better-auth/scripts/better_auth_init.py +521 -521
  172. package/skills/engineering/better-auth/scripts/requirements.txt +15 -15
  173. package/skills/engineering/better-auth/scripts/tests/test_better_auth_init.py +421 -421
  174. package/skills/engineering/code-review/SKILL.md +140 -140
  175. package/skills/engineering/code-review/references/code-review-reception.md +208 -208
  176. package/skills/engineering/code-review/references/requesting-code-review.md +104 -104
  177. package/skills/engineering/code-review/references/verification-before-completion.md +138 -138
  178. package/skills/engineering/context-engineering/SKILL.md +86 -86
  179. package/skills/engineering/context-engineering/references/context-compression.md +84 -84
  180. package/skills/engineering/context-engineering/references/context-degradation.md +93 -93
  181. package/skills/engineering/context-engineering/references/context-fundamentals.md +75 -75
  182. package/skills/engineering/context-engineering/references/context-optimization.md +82 -82
  183. package/skills/engineering/context-engineering/references/evaluation.md +89 -89
  184. package/skills/engineering/context-engineering/references/memory-systems.md +88 -88
  185. package/skills/engineering/context-engineering/references/multi-agent-patterns.md +90 -90
  186. package/skills/engineering/context-engineering/references/project-development.md +97 -97
  187. package/skills/engineering/context-engineering/references/tool-design.md +86 -86
  188. package/skills/engineering/context-engineering/scripts/compression_evaluator.py +329 -329
  189. package/skills/engineering/context-engineering/scripts/context_analyzer.py +294 -294
  190. package/skills/engineering/databases/SKILL.md +232 -232
  191. package/skills/engineering/databases/references/mongodb-aggregation.md +447 -447
  192. package/skills/engineering/databases/references/mongodb-atlas.md +465 -465
  193. package/skills/engineering/databases/references/mongodb-crud.md +408 -408
  194. package/skills/engineering/databases/references/mongodb-indexing.md +442 -442
  195. package/skills/engineering/databases/references/postgresql-administration.md +594 -594
  196. package/skills/engineering/databases/references/postgresql-performance.md +527 -527
  197. package/skills/engineering/databases/references/postgresql-psql-cli.md +467 -467
  198. package/skills/engineering/databases/references/postgresql-queries.md +475 -475
  199. package/skills/engineering/databases/scripts/db_backup.py +502 -502
  200. package/skills/engineering/databases/scripts/db_migrate.py +414 -414
  201. package/skills/engineering/databases/scripts/db_performance_check.py +444 -444
  202. package/skills/engineering/databases/scripts/requirements.txt +20 -20
  203. package/skills/engineering/databases/scripts/tests/requirements.txt +4 -4
  204. package/skills/engineering/databases/scripts/tests/test_db_backup.py +340 -340
  205. package/skills/engineering/databases/scripts/tests/test_db_migrate.py +277 -277
  206. package/skills/engineering/databases/scripts/tests/test_db_performance_check.py +370 -370
  207. package/skills/engineering/diagnose/SKILL.md +117 -117
  208. package/skills/engineering/diagnose/scripts/hitl-loop.template.sh +41 -41
  209. package/skills/engineering/docs-seeker/SKILL.md +207 -207
  210. package/skills/engineering/docs-seeker/WORKFLOWS.md +505 -505
  211. package/skills/engineering/docs-seeker/references/best-practices.md +632 -632
  212. package/skills/engineering/docs-seeker/references/documentation-sources.md +461 -461
  213. package/skills/engineering/docs-seeker/references/error-handling.md +621 -621
  214. package/skills/engineering/docs-seeker/references/limitations.md +821 -821
  215. package/skills/engineering/docs-seeker/references/performance.md +574 -574
  216. package/skills/engineering/docs-seeker/references/tool-selection.md +262 -262
  217. package/skills/engineering/frontend-development/SKILL.md +398 -398
  218. package/skills/engineering/frontend-development/resources/common-patterns.md +330 -330
  219. package/skills/engineering/frontend-development/resources/complete-examples.md +871 -871
  220. package/skills/engineering/frontend-development/resources/component-patterns.md +501 -501
  221. package/skills/engineering/frontend-development/resources/data-fetching.md +766 -766
  222. package/skills/engineering/frontend-development/resources/file-organization.md +501 -501
  223. package/skills/engineering/frontend-development/resources/loading-and-error-states.md +500 -500
  224. package/skills/engineering/frontend-development/resources/performance.md +405 -405
  225. package/skills/engineering/frontend-development/resources/routing-guide.md +363 -363
  226. package/skills/engineering/frontend-development/resources/styling-guide.md +427 -427
  227. package/skills/engineering/frontend-development/resources/typescript-standards.md +417 -417
  228. package/skills/engineering/improve-codebase-architecture/DEEPENING.md +37 -37
  229. package/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -44
  230. package/skills/engineering/improve-codebase-architecture/LANGUAGE.md +53 -53
  231. package/skills/engineering/improve-codebase-architecture/SKILL.md +71 -71
  232. package/skills/engineering/openai-docs/LICENSE.txt +201 -201
  233. package/skills/engineering/openai-docs/SKILL.md +69 -69
  234. package/skills/engineering/openai-docs/agents/openai.yaml +14 -14
  235. package/skills/engineering/openai-docs/assets/openai-small.svg +3 -3
  236. package/skills/engineering/openai-docs/references/gpt-5p4-prompting-guide.md +433 -433
  237. package/skills/engineering/openai-docs/references/latest-model.md +35 -35
  238. package/skills/engineering/openai-docs/references/upgrading-to-gpt-5p4.md +164 -164
  239. package/skills/engineering/playwright/LICENSE.txt +201 -201
  240. package/skills/engineering/playwright/NOTICE.txt +14 -14
  241. package/skills/engineering/playwright/SKILL.md +147 -147
  242. package/skills/engineering/playwright/agents/openai.yaml +6 -6
  243. package/skills/engineering/playwright/assets/playwright-small.svg +3 -3
  244. package/skills/engineering/playwright/references/cli.md +116 -116
  245. package/skills/engineering/playwright/references/workflows.md +95 -95
  246. package/skills/engineering/playwright/scripts/playwright_cli.sh +25 -25
  247. package/skills/engineering/playwright-interactive/LICENSE.txt +201 -201
  248. package/skills/engineering/playwright-interactive/NOTICE.txt +13 -13
  249. package/skills/engineering/playwright-interactive/SKILL.md +689 -689
  250. package/skills/engineering/playwright-interactive/agents/openai.yaml +6 -6
  251. package/skills/engineering/playwright-interactive/assets/playwright-small.svg +3 -3
  252. package/skills/engineering/render-deploy/LICENSE.txt +201 -201
  253. package/skills/engineering/render-deploy/SKILL.md +479 -479
  254. package/skills/engineering/render-deploy/agents/openai.yaml +14 -14
  255. package/skills/engineering/render-deploy/assets/docker.yaml +62 -62
  256. package/skills/engineering/render-deploy/assets/go-api.yaml +35 -35
  257. package/skills/engineering/render-deploy/assets/nextjs-postgres.yaml +35 -35
  258. package/skills/engineering/render-deploy/assets/node-express.yaml +25 -25
  259. package/skills/engineering/render-deploy/assets/python-django.yaml +89 -89
  260. package/skills/engineering/render-deploy/assets/render-small.svg +3 -3
  261. package/skills/engineering/render-deploy/assets/static-site.yaml +54 -54
  262. package/skills/engineering/render-deploy/references/blueprint-spec.md +718 -718
  263. package/skills/engineering/render-deploy/references/codebase-analysis.md +49 -49
  264. package/skills/engineering/render-deploy/references/configuration-guide.md +603 -603
  265. package/skills/engineering/render-deploy/references/deployment-details.md +224 -224
  266. package/skills/engineering/render-deploy/references/direct-creation.md +113 -113
  267. package/skills/engineering/render-deploy/references/error-patterns.md +13 -13
  268. package/skills/engineering/render-deploy/references/post-deploy-checks.md +36 -36
  269. package/skills/engineering/render-deploy/references/runtimes.md +473 -473
  270. package/skills/engineering/render-deploy/references/service-types.md +450 -450
  271. package/skills/engineering/render-deploy/references/troubleshooting-basics.md +36 -36
  272. package/skills/engineering/repomix/SKILL.md +215 -215
  273. package/skills/engineering/repomix/references/configuration.md +211 -211
  274. package/skills/engineering/repomix/references/usage-patterns.md +232 -232
  275. package/skills/engineering/repomix/scripts/README.md +179 -179
  276. package/skills/engineering/repomix/scripts/repomix_batch.py +455 -455
  277. package/skills/engineering/repomix/scripts/repos.example.json +15 -15
  278. package/skills/engineering/repomix/scripts/requirements.txt +15 -15
  279. package/skills/engineering/repomix/scripts/tests/test_repomix_batch.py +531 -531
  280. package/skills/engineering/setup-matt-pocock-skills/SKILL.md +121 -121
  281. package/skills/engineering/setup-matt-pocock-skills/domain.md +51 -51
  282. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-github.md +22 -22
  283. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-gitlab.md +23 -23
  284. package/skills/engineering/setup-matt-pocock-skills/issue-tracker-local.md +19 -19
  285. package/skills/engineering/setup-matt-pocock-skills/triage-labels.md +15 -15
  286. package/skills/engineering/shopify/README.md +66 -66
  287. package/skills/engineering/shopify/SKILL.md +319 -319
  288. package/skills/engineering/shopify/references/app-development.md +470 -470
  289. package/skills/engineering/shopify/references/extensions.md +493 -493
  290. package/skills/engineering/shopify/references/themes.md +498 -498
  291. package/skills/engineering/shopify/scripts/requirements.txt +19 -19
  292. package/skills/engineering/shopify/scripts/shopify_init.py +423 -423
  293. package/skills/engineering/shopify/scripts/tests/test_shopify_init.py +385 -385
  294. package/skills/engineering/tdd/SKILL.md +109 -109
  295. package/skills/engineering/tdd/deep-modules.md +33 -33
  296. package/skills/engineering/tdd/interface-design.md +31 -31
  297. package/skills/engineering/tdd/mocking.md +59 -59
  298. package/skills/engineering/tdd/refactoring.md +10 -10
  299. package/skills/engineering/tdd/tests.md +61 -61
  300. package/skills/engineering/to-issues/SKILL.md +81 -81
  301. package/skills/engineering/to-prd/SKILL.md +74 -74
  302. package/skills/engineering/triage/AGENT-BRIEF.md +168 -168
  303. package/skills/engineering/triage/OUT-OF-SCOPE.md +101 -101
  304. package/skills/engineering/triage/SKILL.md +103 -103
  305. package/skills/engineering/web-frameworks/SKILL.md +324 -324
  306. package/skills/engineering/web-frameworks/references/nextjs-app-router.md +465 -465
  307. package/skills/engineering/web-frameworks/references/nextjs-data-fetching.md +459 -459
  308. package/skills/engineering/web-frameworks/references/nextjs-optimization.md +511 -511
  309. package/skills/engineering/web-frameworks/references/nextjs-server-components.md +495 -495
  310. package/skills/engineering/web-frameworks/references/remix-icon-integration.md +603 -603
  311. package/skills/engineering/web-frameworks/references/turborepo-caching.md +551 -551
  312. package/skills/engineering/web-frameworks/references/turborepo-pipelines.md +517 -517
  313. package/skills/engineering/web-frameworks/references/turborepo-setup.md +542 -542
  314. package/skills/engineering/web-frameworks/scripts/nextjs_init.py +547 -547
  315. package/skills/engineering/web-frameworks/scripts/requirements.txt +16 -16
  316. package/skills/engineering/web-frameworks/scripts/tests/requirements.txt +3 -3
  317. package/skills/engineering/web-frameworks/scripts/tests/test_nextjs_init.py +319 -319
  318. package/skills/engineering/web-frameworks/scripts/tests/test_turborepo_migrate.py +374 -374
  319. package/skills/engineering/web-frameworks/scripts/turborepo_migrate.py +394 -394
  320. package/skills/engineering/write-a-skill/SKILL.md +117 -117
  321. package/skills/kilo-kit/SKILL.md +346 -346
  322. package/skills/kilo-kit/_template/SKILL.md +185 -185
  323. package/skills/kilo-kit/debugging/root-cause/SKILL.md +360 -360
  324. package/skills/kilo-kit/debugging/systematic/SKILL.md +339 -339
  325. package/skills/kilo-kit/debugging/verification/SKILL.md +424 -424
  326. package/skills/kilo-kit/development/backend/SKILL.md +540 -540
  327. package/skills/kilo-kit/development/security/SKILL.md +529 -529
  328. package/skills/kilo-kit/quality/code-review/SKILL.md +297 -297
  329. package/skills/kilo-kit/quality/testing/SKILL.md +540 -540
  330. package/skills/kilo-kit/references/output-formats.md +204 -204
  331. package/skills/kilo-kit/references/patterns.md +156 -156
  332. package/skills/kilo-kit/references/performance-benchmarks.md +90 -90
  333. package/skills/operations/chrome-devtools/SKILL.md +392 -392
  334. package/skills/operations/chrome-devtools/references/cdp-domains.md +694 -694
  335. package/skills/operations/chrome-devtools/references/performance-guide.md +940 -940
  336. package/skills/operations/chrome-devtools/references/puppeteer-reference.md +953 -953
  337. package/skills/operations/chrome-devtools/scripts/PERSISTENT-BROWSER.md +107 -107
  338. package/skills/operations/chrome-devtools/scripts/README.md +213 -213
  339. package/skills/operations/chrome-devtools/scripts/__tests__/selector.test.js +210 -210
  340. package/skills/operations/chrome-devtools/scripts/click.js +79 -79
  341. package/skills/operations/chrome-devtools/scripts/close-persistent.js +36 -36
  342. package/skills/operations/chrome-devtools/scripts/console.js +75 -75
  343. package/skills/operations/chrome-devtools/scripts/evaluate.js +49 -49
  344. package/skills/operations/chrome-devtools/scripts/fill.js +72 -72
  345. package/skills/operations/chrome-devtools/scripts/install-deps.sh +181 -181
  346. package/skills/operations/chrome-devtools/scripts/install.sh +83 -83
  347. package/skills/operations/chrome-devtools/scripts/launch-persistent.js +71 -71
  348. package/skills/operations/chrome-devtools/scripts/lib/browser.js +144 -144
  349. package/skills/operations/chrome-devtools/scripts/lib/selector.js +178 -178
  350. package/skills/operations/chrome-devtools/scripts/navigate.js +46 -46
  351. package/skills/operations/chrome-devtools/scripts/network.js +102 -102
  352. package/skills/operations/chrome-devtools/scripts/package-lock.json +1206 -1206
  353. package/skills/operations/chrome-devtools/scripts/package.json +15 -15
  354. package/skills/operations/chrome-devtools/scripts/performance.js +145 -145
  355. package/skills/operations/chrome-devtools/scripts/screenshot.js +180 -180
  356. package/skills/operations/chrome-devtools/scripts/snapshot.js +131 -131
  357. package/skills/operations/devops/.env.example +76 -76
  358. package/skills/operations/devops/SKILL.md +285 -285
  359. package/skills/operations/devops/references/browser-rendering.md +305 -305
  360. package/skills/operations/devops/references/cloudflare-d1-kv.md +123 -123
  361. package/skills/operations/devops/references/cloudflare-platform.md +271 -271
  362. package/skills/operations/devops/references/cloudflare-r2-storage.md +280 -280
  363. package/skills/operations/devops/references/cloudflare-workers-advanced.md +312 -312
  364. package/skills/operations/devops/references/cloudflare-workers-apis.md +309 -309
  365. package/skills/operations/devops/references/cloudflare-workers-basics.md +418 -418
  366. package/skills/operations/devops/references/docker-basics.md +297 -297
  367. package/skills/operations/devops/references/docker-compose.md +292 -292
  368. package/skills/operations/devops/references/gcloud-platform.md +297 -297
  369. package/skills/operations/devops/references/gcloud-services.md +304 -304
  370. package/skills/operations/devops/scripts/cloudflare_deploy.py +269 -269
  371. package/skills/operations/devops/scripts/docker_optimize.py +320 -320
  372. package/skills/operations/devops/scripts/requirements.txt +20 -20
  373. package/skills/operations/devops/scripts/tests/requirements.txt +3 -3
  374. package/skills/operations/devops/scripts/tests/test_cloudflare_deploy.py +285 -285
  375. package/skills/operations/devops/scripts/tests/test_docker_optimize.py +436 -436
  376. package/skills/operations/mcp-builder/LICENSE.txt +201 -201
  377. package/skills/operations/mcp-builder/SKILL.md +328 -328
  378. package/skills/operations/mcp-builder/reference/evaluation.md +601 -601
  379. package/skills/operations/mcp-builder/reference/mcp_best_practices.md +915 -915
  380. package/skills/operations/mcp-builder/reference/node_mcp_server.md +915 -915
  381. package/skills/operations/mcp-builder/reference/python_mcp_server.md +751 -751
  382. package/skills/operations/mcp-builder/scripts/connections.py +151 -151
  383. package/skills/operations/mcp-builder/scripts/evaluation.py +373 -373
  384. package/skills/operations/mcp-builder/scripts/example_evaluation.xml +22 -22
  385. package/skills/operations/mcp-builder/scripts/requirements.txt +2 -2
  386. package/skills/operations/mcp-management/README.md +219 -219
  387. package/skills/operations/mcp-management/SKILL.md +175 -175
  388. package/skills/operations/mcp-management/assets/tools.json +3043 -3043
  389. package/skills/operations/mcp-management/references/configuration.md +114 -114
  390. package/skills/operations/mcp-management/references/gemini-cli-integration.md +201 -201
  391. package/skills/operations/mcp-management/references/mcp-protocol.md +116 -116
  392. package/skills/operations/mcp-management/scripts/.env.example +10 -10
  393. package/skills/operations/mcp-management/scripts/cli.ts +155 -155
  394. package/skills/operations/mcp-management/scripts/dist/analyze-tools.js +70 -70
  395. package/skills/operations/mcp-management/scripts/dist/cli.js +131 -131
  396. package/skills/operations/mcp-management/scripts/dist/mcp-client.js +115 -115
  397. package/skills/operations/mcp-management/scripts/mcp-client.ts +163 -163
  398. package/skills/operations/mcp-management/scripts/package.json +18 -18
  399. package/skills/operations/mcp-management/scripts/tsconfig.json +15 -15
  400. package/skills/problem-solving/collision-zone-thinking/SKILL.md +62 -62
  401. package/skills/problem-solving/defense-in-depth/SKILL.md +130 -130
  402. package/skills/problem-solving/inversion-exercise/SKILL.md +58 -58
  403. package/skills/problem-solving/meta-pattern-recognition/SKILL.md +54 -54
  404. package/skills/problem-solving/root-cause-tracing/SKILL.md +177 -177
  405. package/skills/problem-solving/root-cause-tracing/find-polluter.sh +63 -63
  406. package/skills/problem-solving/scale-game/SKILL.md +63 -63
  407. package/skills/problem-solving/sequential-thinking/README.md +118 -118
  408. package/skills/problem-solving/sequential-thinking/SKILL.md +93 -93
  409. package/skills/problem-solving/sequential-thinking/references/advanced.md +122 -122
  410. package/skills/problem-solving/sequential-thinking/references/examples.md +274 -274
  411. package/skills/problem-solving/simplification-cascades/SKILL.md +76 -76
  412. package/skills/problem-solving/when-stuck/SKILL.md +88 -88
  413. package/skills/productivity/caveman/SKILL.md +49 -49
  414. package/skills/productivity/grill-me/SKILL.md +10 -10
  415. package/skills/productivity/grill-with-docs/ADR-FORMAT.md +47 -47
  416. package/skills/productivity/grill-with-docs/CONTEXT-FORMAT.md +77 -77
  417. package/skills/productivity/grill-with-docs/SKILL.md +88 -88
  418. package/skills/productivity/writing-skills/graphviz-conventions.dot +171 -171
  419. package/skills/productivity/zoom-out/SKILL.md +7 -7
  420. package/skills/writing-docs/doc/LICENSE.txt +201 -201
  421. package/skills/writing-docs/doc/SKILL.md +80 -80
  422. package/skills/writing-docs/doc/agents/openai.yaml +6 -6
  423. package/skills/writing-docs/doc/assets/doc-small.svg +3 -3
  424. package/skills/writing-docs/doc/scripts/render_docx.py +296 -296
  425. package/skills/writing-docs/docx/LICENSE.txt +30 -30
  426. package/skills/writing-docs/docx/SKILL.md +196 -196
  427. package/skills/writing-docs/docx/docx-js.md +349 -349
  428. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
  429. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
  430. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
  431. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
  432. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
  433. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
  434. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
  435. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
  436. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
  437. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
  438. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
  439. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
  440. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
  441. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
  442. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
  443. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
  444. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
  445. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
  446. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
  447. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
  448. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
  449. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
  450. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
  451. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
  452. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
  453. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
  454. package/skills/writing-docs/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
  455. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
  456. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
  457. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
  458. package/skills/writing-docs/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
  459. package/skills/writing-docs/docx/ooxml/schemas/mce/mc.xsd +75 -75
  460. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -560
  461. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -67
  462. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -14
  463. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -20
  464. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -13
  465. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
  466. package/skills/writing-docs/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -8
  467. package/skills/writing-docs/docx/ooxml/scripts/pack.py +159 -159
  468. package/skills/writing-docs/docx/ooxml/scripts/unpack.py +29 -29
  469. package/skills/writing-docs/docx/ooxml/scripts/validate.py +69 -69
  470. package/skills/writing-docs/docx/ooxml/scripts/validation/__init__.py +15 -15
  471. package/skills/writing-docs/docx/ooxml/scripts/validation/base.py +951 -951
  472. package/skills/writing-docs/docx/ooxml/scripts/validation/docx.py +274 -274
  473. package/skills/writing-docs/docx/ooxml/scripts/validation/pptx.py +315 -315
  474. package/skills/writing-docs/docx/ooxml/scripts/validation/redlining.py +279 -279
  475. package/skills/writing-docs/docx/ooxml.md +609 -609
  476. package/skills/writing-docs/docx/scripts/__init__.py +1 -1
  477. package/skills/writing-docs/docx/scripts/document.py +1276 -1276
  478. package/skills/writing-docs/docx/scripts/templates/comments.xml +2 -2
  479. package/skills/writing-docs/docx/scripts/templates/commentsExtended.xml +2 -2
  480. package/skills/writing-docs/docx/scripts/templates/commentsExtensible.xml +2 -2
  481. package/skills/writing-docs/docx/scripts/templates/commentsIds.xml +2 -2
  482. package/skills/writing-docs/docx/scripts/templates/people.xml +2 -2
  483. package/skills/writing-docs/docx/scripts/utilities.py +374 -374
  484. package/skills/writing-docs/mermaidjs-v11/SKILL.md +115 -115
  485. package/skills/writing-docs/mermaidjs-v11/references/cli-usage.md +228 -228
  486. package/skills/writing-docs/mermaidjs-v11/references/configuration.md +232 -232
  487. package/skills/writing-docs/mermaidjs-v11/references/diagram-types.md +315 -315
  488. package/skills/writing-docs/mermaidjs-v11/references/examples.md +344 -344
  489. package/skills/writing-docs/mermaidjs-v11/references/integration.md +310 -310
  490. package/skills/writing-docs/pdf/LICENSE.txt +30 -30
  491. package/skills/writing-docs/pdf/SKILL.md +294 -294
  492. package/skills/writing-docs/pdf/forms.md +205 -205
  493. package/skills/writing-docs/pdf/reference.md +611 -611
  494. package/skills/writing-docs/pdf/scripts/check_bounding_boxes.py +70 -70
  495. package/skills/writing-docs/pdf/scripts/check_bounding_boxes_test.py +226 -226
  496. package/skills/writing-docs/pdf/scripts/check_fillable_fields.py +12 -12
  497. package/skills/writing-docs/pdf/scripts/convert_pdf_to_images.py +35 -35
  498. package/skills/writing-docs/pdf/scripts/create_validation_image.py +41 -41
  499. package/skills/writing-docs/pdf/scripts/extract_form_field_info.py +152 -152
  500. package/skills/writing-docs/pdf/scripts/fill_fillable_fields.py +114 -114
  501. package/skills/writing-docs/pdf/scripts/fill_pdf_form_with_annotations.py +107 -107
  502. package/skills/writing-docs/pptx/LICENSE.txt +30 -30
  503. package/skills/writing-docs/pptx/SKILL.md +483 -483
  504. package/skills/writing-docs/pptx/html2pptx.md +624 -624
  505. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -1499
  506. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -146
  507. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -1085
  508. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -11
  509. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -3081
  510. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -23
  511. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -185
  512. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -287
  513. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -1676
  514. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -28
  515. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -144
  516. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -174
  517. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -25
  518. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -18
  519. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -59
  520. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -56
  521. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -195
  522. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -582
  523. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -25
  524. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -4439
  525. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -570
  526. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -509
  527. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -12
  528. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -108
  529. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -96
  530. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -3646
  531. package/skills/writing-docs/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -116
  532. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -42
  533. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -50
  534. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -49
  535. package/skills/writing-docs/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -33
  536. package/skills/writing-docs/pptx/ooxml/schemas/mce/mc.xsd +75 -75
  537. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -560
  538. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -67
  539. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -14
  540. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -20
  541. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -13
  542. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -4
  543. package/skills/writing-docs/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -8
  544. package/skills/writing-docs/pptx/ooxml/scripts/pack.py +159 -159
  545. package/skills/writing-docs/pptx/ooxml/scripts/unpack.py +29 -29
  546. package/skills/writing-docs/pptx/ooxml/scripts/validate.py +69 -69
  547. package/skills/writing-docs/pptx/ooxml/scripts/validation/__init__.py +15 -15
  548. package/skills/writing-docs/pptx/ooxml/scripts/validation/base.py +951 -951
  549. package/skills/writing-docs/pptx/ooxml/scripts/validation/docx.py +274 -274
  550. package/skills/writing-docs/pptx/ooxml/scripts/validation/pptx.py +315 -315
  551. package/skills/writing-docs/pptx/ooxml/scripts/validation/redlining.py +279 -279
  552. package/skills/writing-docs/pptx/ooxml.md +426 -426
  553. package/skills/writing-docs/pptx/scripts/html2pptx.js +978 -978
  554. package/skills/writing-docs/pptx/scripts/inventory.py +1020 -1020
  555. package/skills/writing-docs/pptx/scripts/rearrange.py +231 -231
  556. package/skills/writing-docs/pptx/scripts/replace.py +385 -385
  557. package/skills/writing-docs/pptx/scripts/thumbnail.py +450 -450
  558. package/skills/writing-docs/slides/LICENSE.txt +201 -201
  559. package/skills/writing-docs/slides/SKILL.md +71 -71
  560. package/skills/writing-docs/slides/agents/openai.yaml +6 -6
  561. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/code.js +104 -104
  562. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/image.js +333 -333
  563. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/index.js +33 -33
  564. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/latex.js +51 -51
  565. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/layout.js +643 -643
  566. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/layout_builders.js +358 -358
  567. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/svg.js +36 -36
  568. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/text.js +789 -789
  569. package/skills/writing-docs/slides/assets/pptxgenjs_helpers/util.js +24 -24
  570. package/skills/writing-docs/slides/assets/slides-small.svg +3 -3
  571. package/skills/writing-docs/slides/references/pptxgenjs-helpers.md +61 -61
  572. package/skills/writing-docs/slides/scripts/create_montage.py +300 -300
  573. package/skills/writing-docs/slides/scripts/detect_font.py +873 -873
  574. package/skills/writing-docs/slides/scripts/ensure_raster_image.py +202 -202
  575. package/skills/writing-docs/slides/scripts/render_slides.py +273 -273
  576. package/skills/writing-docs/slides/scripts/slides_test.py +201 -201
  577. package/skills/writing-docs/template-skill/SKILL.md +26 -26
  578. package/skills/writing-docs/xlsx/LICENSE.txt +30 -30
  579. package/skills/writing-docs/xlsx/SKILL.md +288 -288
  580. package/skills/writing-docs/xlsx/recalc.py +177 -177
  581. package/src/core/KILO_MASTER.md +448 -448
  582. package/src/tools/validate-skill.js +421 -421
@@ -1,689 +1,689 @@
1
- ---
2
- name: "playwright-interactive"
3
- description: "Persistent browser and Electron interaction through `js_repl` for fast iterative UI debugging."
4
- ---
5
-
6
- # Playwright Interactive Skill
7
-
8
- Use a persistent `js_repl` Playwright session to debug local web or Electron apps, keep the same handles alive across iterations, and run functional plus visual QA without restarting the whole toolchain unless the process ownership changed.
9
-
10
- ## Preconditions
11
-
12
- - `js_repl` must be enabled for this skill.
13
- - If `js_repl` is missing, enable it in `~/.codex/config.toml`:
14
-
15
- ```toml
16
- [features]
17
- js_repl = true
18
- ```
19
-
20
- - You can also start a new session with `--enable js_repl` (equivalent to `-c features.js_repl=true`).
21
- - After enabling `js_repl`, start a new Codex session so the tool list refreshes.
22
- - For now, run this workflow with sandboxing disabled: start Codex with `--sandbox danger-full-access` (or the equivalent config for `sandbox_mode=danger-full-access`). This is a temporary requirement while `js_repl` + Playwright support inside the sandbox is still being completed.
23
- - Run setup from the same project directory you need to debug.
24
- - Treat `js_repl_reset` as a recovery tool, not routine cleanup. Resetting the kernel destroys your Playwright handles.
25
-
26
- ## One-time setup
27
-
28
- ```bash
29
- test -f package.json || npm init -y
30
- npm install playwright
31
- # Web-only, for headed Chromium or mobile emulation:
32
- # npx playwright install chromium
33
- # Electron-only, and only if the target workspace is the app itself:
34
- # npm install --save-dev electron
35
- node -e "import('playwright').then(() => console.log('playwright import ok')).catch((error) => { console.error(error); process.exit(1); })"
36
- ```
37
-
38
- If you switch to a different workspace later, repeat setup there.
39
-
40
- ## Core Workflow
41
-
42
- 1. Write a brief QA inventory before testing:
43
- - Build the inventory from three sources: the user's requested requirements, the user-visible features or behaviors you actually implemented, and the claims you expect to make in the final response.
44
- - Anything that appears in any of those three sources must map to at least one QA check before signoff.
45
- - List the user-visible claims you intend to sign off on.
46
- - List every meaningful user-facing control, mode switch, or implemented interactive behavior.
47
- - List the state changes or view changes each control or implemented behavior can cause.
48
- - Use this as the shared coverage list for both functional QA and visual QA.
49
- - For each claim or control-state pair, note the intended functional check, the specific state where the visual check must happen, and the evidence you expect to capture.
50
- - If a requirement is visually central but subjective, convert it into an observable QA check instead of leaving it implicit.
51
- - Add at least 2 exploratory or off-happy-path scenarios that could expose fragile behavior.
52
- 2. Run the bootstrap cell once.
53
- 3. Start or confirm any required dev server in a persistent TTY session.
54
- 4. Launch the correct runtime and keep reusing the same Playwright handles.
55
- 5. After each code change, reload for renderer-only changes or relaunch for main-process/startup changes.
56
- 6. Run functional QA with normal user input.
57
- 7. Run a separate visual QA pass.
58
- 8. Verify viewport fit and capture the screenshots needed to support your claims.
59
- 9. Clean up the Playwright session only when the task is actually finished.
60
-
61
- ## Bootstrap (Run Once)
62
-
63
- ```javascript
64
- var chromium;
65
- var electronLauncher;
66
- var browser;
67
- var context;
68
- var page;
69
- var mobileContext;
70
- var mobilePage;
71
- var electronApp;
72
- var appWindow;
73
-
74
- try {
75
- ({ chromium, _electron: electronLauncher } = await import("playwright"));
76
- console.log("Playwright loaded");
77
- } catch (error) {
78
- throw new Error(
79
- `Could not load playwright from the current js_repl cwd. Run the setup commands from this workspace first. Original error: ${error}`
80
- );
81
- }
82
- ```
83
-
84
- Binding rules:
85
-
86
- - Use `var` for the shared top-level Playwright handles because later `js_repl` cells reuse them.
87
- - The setup cells below are intentionally short happy paths. If a handle looks stale, set that binding to `undefined` and rerun the cell instead of adding recovery logic everywhere.
88
- - Prefer one named handle per surface you care about (`page`, `mobilePage`, `appWindow`) over repeatedly rediscovering pages from the context.
89
-
90
- Shared web helpers:
91
-
92
- ```javascript
93
- var resetWebHandles = function () {
94
- context = undefined;
95
- page = undefined;
96
- mobileContext = undefined;
97
- mobilePage = undefined;
98
- };
99
-
100
- var ensureWebBrowser = async function () {
101
- if (browser && !browser.isConnected()) {
102
- browser = undefined;
103
- resetWebHandles();
104
- }
105
-
106
- browser ??= await chromium.launch({ headless: false });
107
- return browser;
108
- };
109
-
110
- var reloadWebContexts = async function () {
111
- for (const currentContext of [context, mobileContext]) {
112
- if (!currentContext) continue;
113
- for (const p of currentContext.pages()) {
114
- await p.reload({ waitUntil: "domcontentloaded" });
115
- }
116
- }
117
- console.log("Reloaded existing web tabs");
118
- };
119
- ```
120
-
121
- ## Choose Session Mode
122
-
123
- For web apps, use an explicit viewport by default and treat native-window mode as a separate validation pass.
124
-
125
- - Use an explicit viewport for routine iteration, breakpoint checks, reproducible screenshots, snapshot diffs, and model-assisted localization. This is the default because it is stable across machines and avoids host window-manager variability.
126
- - When you need deterministic high-DPI behavior, keep the explicit viewport and add `deviceScaleFactor` rather than switching straight to native-window mode.
127
- - Use native-window mode (`viewport: null`) for a separate headed pass when you need to validate launched window size, OS-level DPI behavior, browser chrome interactions, or bugs that may depend on the host display configuration.
128
- - For Electron, assume native-window behavior all the time. Electron launches through Playwright with `noDefaultViewport`, so treat it like a real desktop window and check the as-launched size and layout before resizing anything.
129
- - When signoff depends on both layout breakpoints and real desktop behavior, do both passes: explicit viewport first for deterministic QA, then native-window validation for final environment-specific checks.
130
- - Treat switching modes as a context reset. Do not reuse a viewport-emulated `context` for a native-window pass or vice versa; close the old `page` and `context`, then create a new one for the new mode.
131
-
132
- ## Start or Reuse Web Session
133
-
134
- Desktop and mobile web sessions share the same `browser`, helpers, and QA flow. The main difference is which context and page pair you create.
135
-
136
- ### Desktop Web Context
137
-
138
- Set `TARGET_URL` to the app you are debugging. For local servers, prefer `127.0.0.1` over `localhost`.
139
-
140
- ```javascript
141
- var TARGET_URL = "http://127.0.0.1:3000";
142
-
143
- if (page?.isClosed()) page = undefined;
144
-
145
- await ensureWebBrowser();
146
- context ??= await browser.newContext({
147
- viewport: { width: 1600, height: 900 },
148
- });
149
- page ??= await context.newPage();
150
-
151
- await page.goto(TARGET_URL, { waitUntil: "domcontentloaded" });
152
- console.log("Loaded:", await page.title());
153
- ```
154
-
155
- If `context` or `page` is stale, set `context = page = undefined` and rerun the cell.
156
-
157
- ### Mobile Web Context
158
-
159
- Reuse `TARGET_URL` when it already exists; otherwise set a mobile target directly.
160
-
161
- ```javascript
162
- var MOBILE_TARGET_URL = typeof TARGET_URL === "string"
163
- ? TARGET_URL
164
- : "http://127.0.0.1:3000";
165
-
166
- if (mobilePage?.isClosed()) mobilePage = undefined;
167
-
168
- await ensureWebBrowser();
169
- mobileContext ??= await browser.newContext({
170
- viewport: { width: 390, height: 844 },
171
- isMobile: true,
172
- hasTouch: true,
173
- });
174
- mobilePage ??= await mobileContext.newPage();
175
-
176
- await mobilePage.goto(MOBILE_TARGET_URL, { waitUntil: "domcontentloaded" });
177
- console.log("Loaded mobile:", await mobilePage.title());
178
- ```
179
-
180
- If `mobileContext` or `mobilePage` is stale, set `mobileContext = mobilePage = undefined` and rerun the cell.
181
-
182
- ### Native-Window Web Pass
183
-
184
- ```javascript
185
- var TARGET_URL = "http://127.0.0.1:3000";
186
-
187
- await ensureWebBrowser();
188
-
189
- await page?.close().catch(() => {});
190
- await context?.close().catch(() => {});
191
- page = undefined;
192
- context = undefined;
193
-
194
- browser ??= await chromium.launch({ headless: false });
195
- context = await browser.newContext({ viewport: null });
196
- page = await context.newPage();
197
-
198
- await page.goto(TARGET_URL, { waitUntil: "domcontentloaded" });
199
- console.log("Loaded native window:", await page.title());
200
- ```
201
-
202
- ## Start or Reuse Electron Session
203
-
204
- Set `ELECTRON_ENTRY` to `.` when the current workspace is the Electron app and `package.json` points `main` to the right entry file. If you need to target a specific main-process file directly, use a path such as `./main.js` instead.
205
-
206
- ```javascript
207
- var ELECTRON_ENTRY = ".";
208
-
209
- if (appWindow?.isClosed()) appWindow = undefined;
210
-
211
- if (!appWindow && electronApp) {
212
- await electronApp.close().catch(() => {});
213
- electronApp = undefined;
214
- }
215
-
216
- electronApp ??= await electronLauncher.launch({
217
- args: [ELECTRON_ENTRY],
218
- });
219
-
220
- appWindow ??= await electronApp.firstWindow();
221
-
222
- console.log("Loaded Electron window:", await appWindow.title());
223
- ```
224
-
225
- If `js_repl` is not already running from the Electron app workspace, pass `cwd` explicitly when launching.
226
-
227
- If the app process looks stale, set `electronApp = appWindow = undefined` and rerun the cell.
228
-
229
- If you already have an Electron session but need a fresh process after a main-process, preload, or startup change, use the restart cell in the next section instead of rerunning this one.
230
-
231
- ## Reuse Sessions During Iteration
232
-
233
- Keep the same session alive whenever you can.
234
-
235
- Web renderer reload:
236
-
237
- ```javascript
238
- await reloadWebContexts();
239
- ```
240
-
241
- Electron renderer-only reload:
242
-
243
- ```javascript
244
- await appWindow.reload({ waitUntil: "domcontentloaded" });
245
- console.log("Reloaded Electron window");
246
- ```
247
-
248
- Electron restart after main-process, preload, or startup changes:
249
-
250
- ```javascript
251
- await electronApp.close().catch(() => {});
252
- electronApp = undefined;
253
- appWindow = undefined;
254
-
255
- electronApp = await electronLauncher.launch({
256
- args: [ELECTRON_ENTRY],
257
- });
258
-
259
- appWindow = await electronApp.firstWindow();
260
- console.log("Relaunched Electron window:", await appWindow.title());
261
- ```
262
-
263
- If your launch requires an explicit `cwd`, include the same `cwd` here.
264
-
265
- Default posture:
266
-
267
- - Keep each `js_repl` cell short and focused on one interaction burst.
268
- - Reuse the existing top-level bindings (`browser`, `context`, `page`, `electronApp`, `appWindow`) instead of redeclaring them.
269
- - If you need isolation, create a new page or a new context inside the same browser.
270
- - For Electron, use `electronApp.evaluate(...)` only for main-process inspection or purpose-built diagnostics.
271
- - Fix helper mistakes in place; do not reset the REPL unless the kernel is actually broken.
272
-
273
- ## Checklists
274
-
275
- ### Session Loop
276
-
277
- - Bootstrap `js_repl` once, then keep the same Playwright handles alive across iterations.
278
- - Launch the target runtime from the current workspace.
279
- - Make the code change.
280
- - Reload or relaunch using the correct path for that change.
281
- - Update the shared QA inventory if exploration reveals an additional control, state, or visible claim.
282
- - Re-run functional QA.
283
- - Re-run visual QA.
284
- - Capture final artifacts only after the current state is the one you are evaluating.
285
-
286
- ### Reload Decision
287
-
288
- - Renderer-only change: reload the existing page or Electron window.
289
- - Main-process, preload, or startup change: relaunch Electron.
290
- - New uncertainty about process ownership or startup code: relaunch instead of guessing.
291
-
292
- ### Functional QA
293
-
294
- - Use real user controls for signoff: keyboard, mouse, click, touch, or equivalent Playwright input APIs.
295
- - Verify at least one end-to-end critical flow.
296
- - Confirm the visible result of that flow, not just internal state.
297
- - For realtime or animation-heavy apps, verify behavior under actual interaction timing.
298
- - Work through the shared QA inventory rather than ad hoc spot checks.
299
- - Cover every obvious visible control at least once before signoff, not only the main happy path.
300
- - For reversible controls or stateful toggles in the inventory, test the full cycle: initial state, changed state, and return to the initial state.
301
- - After the scripted checks pass, do a short exploratory pass using normal input for 30-90 seconds instead of following only the intended path.
302
- - If the exploratory pass reveals a new state, control, or claim, add it to the shared QA inventory and cover it before signoff.
303
- - `page.evaluate(...)` and `electronApp.evaluate(...)` may inspect or stage state, but they do not count as signoff input.
304
-
305
- ### Visual QA
306
-
307
- - Treat visual QA as separate from functional QA.
308
- - Use the same shared QA inventory defined before testing and updated during QA; do not start visual coverage from a different implicit list.
309
- - Restate the user-visible claims and verify each one explicitly; do not assume a functional pass proves a visual claim.
310
- - A user-visible claim is not signed off until it has been inspected in the specific state where it is meant to be perceived.
311
- - Inspect the initial viewport before scrolling.
312
- - Confirm that the initial view visibly supports the interface's primary claims; if a core promised element is not clearly perceptible there, treat that as a bug.
313
- - Inspect all required visible regions, not just the main interaction surface.
314
- - Inspect the states and modes already enumerated in the shared QA inventory, including at least one meaningful post-interaction state when the task is interactive.
315
- - If motion or transitions are part of the experience, inspect at least one in-transition state in addition to the settled endpoints.
316
- - If labels, overlays, annotations, guides, or highlights are meant to track changing content, verify that relationship after the relevant state change.
317
- - For dynamic or interaction-dependent visuals, inspect long enough to judge stability, layering, and readability; do not rely on a single screenshot for signoff.
318
- - For interfaces that can become denser after loading or interaction, inspect the densest realistic state you can reach during QA, not only the empty, loading, or collapsed state.
319
- - If the product has a defined minimum supported viewport or window size, run a separate visual QA pass there; otherwise, choose a smaller but still realistic size and inspect it explicitly.
320
- - Distinguish presence from implementation: if an intended affordance is technically there but not clearly perceptible because of weak contrast, occlusion, clipping, or instability, treat that as a visual failure.
321
- - If any required visible region is clipped, cut off, obscured, or pushed outside the viewport in the state you are evaluating, treat that as a bug even if page-level scroll metrics appear acceptable.
322
- - Look for clipping, overflow, distortion, layout imbalance, inconsistent spacing, alignment problems, illegible text, weak contrast, broken layering, and awkward motion states.
323
- - Judge aesthetic quality as well as correctness. The UI should feel intentional, coherent, and visually pleasing for the task.
324
- - Prefer viewport screenshots for signoff. Use full-page captures only as secondary debugging artifacts, and capture a focused screenshot when a region needs closer inspection.
325
- - If motion makes a screenshot ambiguous, wait briefly for the UI to settle, then capture the image you are actually evaluating.
326
- - Before signoff, explicitly ask: what visible part of this interface have I not yet inspected closely?
327
- - Before signoff, explicitly ask: what visible defect would most likely embarrass this result if the user looked closely?
328
-
329
- ### Signoff
330
-
331
- - The functional path passed with normal user input.
332
- - Coverage is explicit against the shared QA inventory: note which requirements, implemented features, controls, states, and claims were exercised, and call out any intentional exclusions.
333
- - The visual QA pass covered the whole relevant interface.
334
- - Each user-visible claim has a matching visual check and reviewed screenshot artifact from the state and viewport or window size where that claim matters.
335
- - The viewport-fit checks passed for the intended initial view and any required minimum supported viewport or window size.
336
- - If the product launches in a window, the as-launched size, placement, and initial layout were checked before any manual resize or repositioning.
337
- - The UI is not just functional; it is visually coherent and not aesthetically weak for the task.
338
- - Functional correctness, viewport fit, and visual quality must each pass on their own; one does not imply the others.
339
- - A short exploratory pass was completed for interactive products, and the response mentions what that pass covered.
340
- - If screenshot review and numeric checks disagreed at any point, the discrepancy was investigated before signoff; visible clipping in screenshots is a failure to resolve, not something metrics can overrule.
341
- - Include a brief negative confirmation of the main defect classes you checked for and did not find.
342
- - Cleanup was executed, or you intentionally kept the session alive for further work.
343
-
344
- ## Screenshot Examples
345
-
346
- If you plan to emit a screenshot through `codex.emitImage(...)`, use the CSS-normalized paths in the next section by default. Those are the canonical examples for screenshots that will be interpreted by the model or used for coordinate-based follow-up actions. Keep raw captures as an exception for fidelity-sensitive debugging only; the raw exception examples appear after the normalization guidance.
347
-
348
- ### Model-bound screenshots (default)
349
-
350
- If you will emit a screenshot with `codex.emitImage(...)` for model interpretation, normalize it to CSS pixels for the exact region you captured before emitting. This keeps returned coordinates aligned with Playwright CSS pixels if the reply is later used for clicking, and it also reduces image payload size and model token cost.
351
-
352
- Do not emit raw native-window screenshots by default. Skip normalization only when you explicitly need device-pixel fidelity, such as Retina or DPI artifact debugging, pixel-accurate rendering inspection, or another fidelity-sensitive case where raw pixels matter more than payload size. For local-only inspection that will not be emitted to the model, raw capture is fine.
353
-
354
- Do not assume `page.screenshot({ scale: "css" })` is enough in native-window mode (`viewport: null`). In Chromium on macOS Retina displays, headed native-window screenshots can still come back at device-pixel size even when `scale: "css"` is requested. The same caveat applies to Electron windows launched through Playwright because Electron runs with `noDefaultViewport`, and `appWindow.screenshot({ scale: "css" })` may still return device-pixel output.
355
-
356
- Use separate normalization paths for web pages and Electron windows:
357
-
358
- - Web: prefer `page.screenshot({ scale: "css" })` directly. If native-window Chromium still returns device-pixel output, resize inside the current page with canvas; no scratch page is required.
359
- - Electron: do not use `appWindow.context().newPage()` or `electronApp.context().newPage()` as a scratch page. Electron contexts do not support that path reliably. Capture in the main process with `BrowserWindow.capturePage(...)`, resize with `nativeImage.resize(...)`, and emit those bytes directly.
360
-
361
- Shared helpers and conventions:
362
-
363
- ```javascript
364
- var emitJpeg = async function (bytes) {
365
- await codex.emitImage({
366
- bytes,
367
- mimeType: "image/jpeg",
368
- });
369
- };
370
-
371
- var emitWebJpeg = async function (surface, options = {}) {
372
- await emitJpeg(await surface.screenshot({
373
- type: "jpeg",
374
- quality: 85,
375
- scale: "css",
376
- ...options,
377
- }));
378
- };
379
-
380
- var clickCssPoint = async function ({ surface, x, y, clip }) {
381
- await surface.mouse.click(
382
- clip ? clip.x + x : x,
383
- clip ? clip.y + y : y
384
- );
385
- };
386
-
387
- var tapCssPoint = async function ({ page, x, y, clip }) {
388
- await page.touchscreen.tap(
389
- clip ? clip.x + x : x,
390
- clip ? clip.y + y : y
391
- );
392
- };
393
- ```
394
-
395
- - Use `page` or `mobilePage` for web, or `appWindow` for Electron, as the `surface`.
396
- - Treat `clip` as CSS pixels from `getBoundingClientRect()` in the renderer.
397
- - Prefer JPEG at `quality: 85` unless lossless fidelity is specifically required.
398
- - For full-image captures, use returned `{ x, y }` directly.
399
- - For clipped captures, add the clip origin back when clicking.
400
-
401
- ### Web CSS normalization
402
-
403
- Preferred web path for explicit-viewport contexts, and often for web in general:
404
-
405
- ```javascript
406
- await emitWebJpeg(page);
407
- ```
408
-
409
- Mobile web uses the same path; substitute `mobilePage` for `page`:
410
-
411
- ```javascript
412
- await emitWebJpeg(mobilePage);
413
- ```
414
-
415
- If the model returns `{ x, y }`, click it directly:
416
-
417
- ```javascript
418
- await clickCssPoint({ surface: page, x, y });
419
- ```
420
-
421
- Mobile web click path:
422
-
423
- ```javascript
424
- await tapCssPoint({ page: mobilePage, x, y });
425
- ```
426
-
427
- For web `clip` screenshots or element screenshots in this normal path, `scale: "css"` usually works directly. Add the region origin back when clicking.
428
-
429
- - `await emitWebJpeg(page, { clip })`
430
- - `await emitWebJpeg(mobilePage, { clip })`
431
- - `await clickCssPoint({ surface: page, clip, x, y })`
432
- - `await tapCssPoint({ page: mobilePage, clip, x, y })`
433
- - `await clickCssPoint({ surface: page, clip: box, x, y })` after `const box = await locator.boundingBox()`
434
-
435
- Web native-window fallback when `scale: "css"` still comes back at device-pixel size:
436
-
437
- ```javascript
438
- var emitWebScreenshotCssScaled = async function ({ page, clip, quality = 0.85 } = {}) {
439
- var NodeBuffer = (await import("node:buffer")).Buffer;
440
- const target = clip
441
- ? { width: clip.width, height: clip.height }
442
- : await page.evaluate(() => ({
443
- width: window.innerWidth,
444
- height: window.innerHeight,
445
- }));
446
-
447
- const screenshotBuffer = await page.screenshot({
448
- type: "png",
449
- ...(clip ? { clip } : {}),
450
- });
451
-
452
- const bytes = await page.evaluate(
453
- async ({ imageBase64, targetWidth, targetHeight, quality }) => {
454
- const image = new Image();
455
- image.src = `data:image/png;base64,${imageBase64}`;
456
- await image.decode();
457
-
458
- const canvas = document.createElement("canvas");
459
- canvas.width = targetWidth;
460
- canvas.height = targetHeight;
461
-
462
- const ctx = canvas.getContext("2d");
463
- ctx.imageSmoothingEnabled = true;
464
- ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
465
-
466
- const blob = await new Promise((resolve) =>
467
- canvas.toBlob(resolve, "image/jpeg", quality)
468
- );
469
-
470
- return new Uint8Array(await blob.arrayBuffer());
471
- },
472
- {
473
- imageBase64: NodeBuffer.from(screenshotBuffer).toString("base64"),
474
- targetWidth: target.width,
475
- targetHeight: target.height,
476
- quality,
477
- }
478
- );
479
-
480
- await emitJpeg(bytes);
481
- };
482
- ```
483
-
484
- For a full viewport fallback capture, treat returned `{ x, y }` as direct CSS coordinates:
485
-
486
- ```javascript
487
- await emitWebScreenshotCssScaled({ page });
488
- await clickCssPoint({ surface: page, x, y });
489
- ```
490
-
491
- For a clipped fallback capture, add the clip origin back:
492
-
493
- ```javascript
494
- await emitWebScreenshotCssScaled({ page, clip });
495
- await clickCssPoint({ surface: page, clip, x, y });
496
- ```
497
-
498
- ### Electron CSS normalization
499
-
500
- For Electron, normalize in the main process instead of opening a scratch Playwright page. The helper below returns CSS-scaled bytes for the full content area or for a clipped CSS-pixel region. Treat `clip` as content-area CSS pixels, for example values taken from `getBoundingClientRect()` in the renderer.
501
-
502
- ```javascript
503
- var emitElectronScreenshotCssScaled = async function ({ electronApp, clip, quality = 85 } = {}) {
504
- const bytes = await electronApp.evaluate(async ({ BrowserWindow }, { clip, quality }) => {
505
- const win = BrowserWindow.getAllWindows()[0];
506
- const image = clip ? await win.capturePage(clip) : await win.capturePage();
507
-
508
- const target = clip
509
- ? { width: clip.width, height: clip.height }
510
- : (() => {
511
- const [width, height] = win.getContentSize();
512
- return { width, height };
513
- })();
514
-
515
- const resized = image.resize({
516
- width: target.width,
517
- height: target.height,
518
- quality: "best",
519
- });
520
-
521
- return resized.toJPEG(quality);
522
- }, { clip, quality });
523
-
524
- await emitJpeg(bytes);
525
- };
526
- ```
527
-
528
- Full Electron window:
529
-
530
- ```javascript
531
- await emitElectronScreenshotCssScaled({ electronApp });
532
- await clickCssPoint({ surface: appWindow, x, y });
533
- ```
534
-
535
- Clipped Electron region using CSS pixels from the renderer:
536
-
537
- ```javascript
538
- var clip = await appWindow.evaluate(() => {
539
- const rect = document.getElementById("board").getBoundingClientRect();
540
- return {
541
- x: Math.round(rect.x),
542
- y: Math.round(rect.y),
543
- width: Math.round(rect.width),
544
- height: Math.round(rect.height),
545
- };
546
- });
547
-
548
- await emitElectronScreenshotCssScaled({ electronApp, clip });
549
- await clickCssPoint({ surface: appWindow, clip, x, y });
550
- ```
551
-
552
- ### Raw Screenshot Exception Examples
553
-
554
- Use these only when raw pixels matter more than CSS-coordinate alignment, such as Retina or DPI artifact debugging, pixel-accurate rendering inspection, or other fidelity-sensitive review.
555
-
556
- Web desktop raw emit:
557
-
558
- ```javascript
559
- await codex.emitImage({
560
- bytes: await page.screenshot({ type: "jpeg", quality: 85 }),
561
- mimeType: "image/jpeg",
562
- });
563
- ```
564
-
565
- Electron raw emit:
566
-
567
- ```javascript
568
- await codex.emitImage({
569
- bytes: await appWindow.screenshot({ type: "jpeg", quality: 85 }),
570
- mimeType: "image/jpeg",
571
- });
572
- ```
573
-
574
- Mobile raw emit after the mobile web context is already running:
575
-
576
- ```javascript
577
- await codex.emitImage({
578
- bytes: await mobilePage.screenshot({ type: "jpeg", quality: 85 }),
579
- mimeType: "image/jpeg",
580
- });
581
- ```
582
-
583
- ## Viewport Fit Checks (Required)
584
-
585
- Do not assume a screenshot is acceptable just because the main widget is visible. Before signoff, explicitly verify that the intended initial view matches the product requirement, using both screenshot review and numeric checks.
586
-
587
- - Define the intended initial view before signoff. For scrollable pages, this is the above-the-fold experience. For app-like shells, games, editors, dashboards, or tools, this is the full interactive surface plus the controls and status needed to use it.
588
- - Use screenshots as the primary evidence for fit. Numeric checks support the screenshots; they do not overrule visible clipping.
589
- - Signoff fails if any required visible region is clipped, cut off, obscured, or pushed outside the viewport in the intended initial view, even if page-level scroll metrics appear acceptable.
590
- - Scrolling is acceptable when the product is designed to scroll and the initial view still communicates the core experience and exposes the primary call to action or required starting context.
591
- - For fixed-shell interfaces, scrolling is not an acceptable workaround if it is needed to reach part of the primary interactive surface or essential controls.
592
- - Do not rely on document scroll metrics alone. Fixed-height shells, internal panes, and hidden-overflow containers can clip required UI while page-level scroll checks still look clean.
593
- - Check region bounds, not just document bounds. Verify that each required visible region fits within the viewport in the startup state.
594
- - For Electron or desktop apps, verify both the launched window size and placement and the renderer's initial visible layout before any manual resize or repositioning.
595
- - Passing viewport-fit checks only proves that the intended initial view is visible without unintended clipping or scrolling. It does not prove that the UI is visually correct or aesthetically successful.
596
-
597
- Web or renderer check:
598
-
599
- ```javascript
600
- console.log(await page.evaluate(() => ({
601
- innerWidth: window.innerWidth,
602
- innerHeight: window.innerHeight,
603
- clientWidth: document.documentElement.clientWidth,
604
- clientHeight: document.documentElement.clientHeight,
605
- scrollWidth: document.documentElement.scrollWidth,
606
- scrollHeight: document.documentElement.scrollHeight,
607
- canScrollX: document.documentElement.scrollWidth > document.documentElement.clientWidth,
608
- canScrollY: document.documentElement.scrollHeight > document.documentElement.clientHeight,
609
- })));
610
- ```
611
-
612
- Electron check:
613
-
614
- ```javascript
615
- console.log(await appWindow.evaluate(() => ({
616
- innerWidth: window.innerWidth,
617
- innerHeight: window.innerHeight,
618
- clientWidth: document.documentElement.clientWidth,
619
- clientHeight: document.documentElement.clientHeight,
620
- scrollWidth: document.documentElement.scrollWidth,
621
- scrollHeight: document.documentElement.scrollHeight,
622
- canScrollX: document.documentElement.scrollWidth > document.documentElement.clientWidth,
623
- canScrollY: document.documentElement.scrollHeight > document.documentElement.clientHeight,
624
- })));
625
- ```
626
-
627
- Augment the numeric check with `getBoundingClientRect()` checks for the required visible regions in your specific UI when clipping is a realistic failure mode; document-level metrics alone are not sufficient for fixed shells.
628
-
629
- ## Dev Server
630
-
631
- For local web debugging, keep the app running in a persistent TTY session. Do not rely on one-shot background commands from a short-lived shell.
632
-
633
- Use the project's normal start command, for example:
634
-
635
- ```bash
636
- npm start
637
- ```
638
-
639
- Before `page.goto(...)`, verify the chosen port is listening and the app responds.
640
-
641
- For Electron debugging, launch the app from `js_repl` through `_electron.launch(...)` so the same session owns the process. If the Electron renderer depends on a separate dev server (for example Vite or Next), keep that server running in a persistent TTY session and then relaunch or reload the Electron app from `js_repl`.
642
-
643
- ## Cleanup
644
-
645
- Only run cleanup when the task is actually finished:
646
-
647
- - This cleanup is manual. Exiting Codex, closing the terminal, or losing the `js_repl` session does not implicitly run `electronApp.close()`, `context.close()`, or `browser.close()`.
648
- - For Electron specifically, assume the app may keep running if you leave the session without executing the cleanup cell first.
649
-
650
- ```javascript
651
- if (electronApp) {
652
- await electronApp.close().catch(() => {});
653
- }
654
-
655
- if (mobileContext) {
656
- await mobileContext.close().catch(() => {});
657
- }
658
-
659
- if (context) {
660
- await context.close().catch(() => {});
661
- }
662
-
663
- if (browser) {
664
- await browser.close().catch(() => {});
665
- }
666
-
667
- browser = undefined;
668
- context = undefined;
669
- page = undefined;
670
- mobileContext = undefined;
671
- mobilePage = undefined;
672
- electronApp = undefined;
673
- appWindow = undefined;
674
-
675
- console.log("Playwright session closed");
676
- ```
677
-
678
- If you plan to exit Codex immediately after debugging, run the cleanup cell first and wait for the `"Playwright session closed"` log before quitting.
679
-
680
- ## Common Failure Modes
681
-
682
- - `Cannot find module 'playwright'`: run the one-time setup in the current workspace and verify the import before using `js_repl`.
683
- - Playwright package is installed but the browser executable is missing: run `npx playwright install chromium`.
684
- - `page.goto: net::ERR_CONNECTION_REFUSED`: make sure the dev server is still running in a persistent TTY session, recheck the port, and prefer `http://127.0.0.1:<port>`.
685
- - `electron.launch` hangs, times out, or exits immediately: verify the local `electron` dependency, confirm the `args` target, and make sure any renderer dev server is already running before launch.
686
- - `Identifier has already been declared`: reuse the existing top-level bindings, choose a new name, or wrap the code in `{ ... }`. Use `js_repl_reset` only when the kernel is genuinely stuck.
687
- - `browserContext.newPage: Protocol error (Target.createTarget): Not supported` while working with Electron: do not use `appWindow.context().newPage()` or `electronApp.context().newPage()` as a scratch page; use the Electron-specific screenshot normalization flow in the model-bound screenshots section.
688
- - `js_repl` timed out or reset: rerun the bootstrap cell and recreate the session with shorter, more focused cells.
689
- - Browser launch or network operations fail immediately: confirm the session was started with `--sandbox danger-full-access` and restart that way if needed.
1
+ ---
2
+ name: "playwright-interactive"
3
+ description: "Persistent browser and Electron interaction through `js_repl` for fast iterative UI debugging."
4
+ ---
5
+
6
+ # Playwright Interactive Skill
7
+
8
+ Use a persistent `js_repl` Playwright session to debug local web or Electron apps, keep the same handles alive across iterations, and run functional plus visual QA without restarting the whole toolchain unless the process ownership changed.
9
+
10
+ ## Preconditions
11
+
12
+ - `js_repl` must be enabled for this skill.
13
+ - If `js_repl` is missing, enable it in `~/.codex/config.toml`:
14
+
15
+ ```toml
16
+ [features]
17
+ js_repl = true
18
+ ```
19
+
20
+ - You can also start a new session with `--enable js_repl` (equivalent to `-c features.js_repl=true`).
21
+ - After enabling `js_repl`, start a new Codex session so the tool list refreshes.
22
+ - For now, run this workflow with sandboxing disabled: start Codex with `--sandbox danger-full-access` (or the equivalent config for `sandbox_mode=danger-full-access`). This is a temporary requirement while `js_repl` + Playwright support inside the sandbox is still being completed.
23
+ - Run setup from the same project directory you need to debug.
24
+ - Treat `js_repl_reset` as a recovery tool, not routine cleanup. Resetting the kernel destroys your Playwright handles.
25
+
26
+ ## One-time setup
27
+
28
+ ```bash
29
+ test -f package.json || npm init -y
30
+ npm install playwright
31
+ # Web-only, for headed Chromium or mobile emulation:
32
+ # npx playwright install chromium
33
+ # Electron-only, and only if the target workspace is the app itself:
34
+ # npm install --save-dev electron
35
+ node -e "import('playwright').then(() => console.log('playwright import ok')).catch((error) => { console.error(error); process.exit(1); })"
36
+ ```
37
+
38
+ If you switch to a different workspace later, repeat setup there.
39
+
40
+ ## Core Workflow
41
+
42
+ 1. Write a brief QA inventory before testing:
43
+ - Build the inventory from three sources: the user's requested requirements, the user-visible features or behaviors you actually implemented, and the claims you expect to make in the final response.
44
+ - Anything that appears in any of those three sources must map to at least one QA check before signoff.
45
+ - List the user-visible claims you intend to sign off on.
46
+ - List every meaningful user-facing control, mode switch, or implemented interactive behavior.
47
+ - List the state changes or view changes each control or implemented behavior can cause.
48
+ - Use this as the shared coverage list for both functional QA and visual QA.
49
+ - For each claim or control-state pair, note the intended functional check, the specific state where the visual check must happen, and the evidence you expect to capture.
50
+ - If a requirement is visually central but subjective, convert it into an observable QA check instead of leaving it implicit.
51
+ - Add at least 2 exploratory or off-happy-path scenarios that could expose fragile behavior.
52
+ 2. Run the bootstrap cell once.
53
+ 3. Start or confirm any required dev server in a persistent TTY session.
54
+ 4. Launch the correct runtime and keep reusing the same Playwright handles.
55
+ 5. After each code change, reload for renderer-only changes or relaunch for main-process/startup changes.
56
+ 6. Run functional QA with normal user input.
57
+ 7. Run a separate visual QA pass.
58
+ 8. Verify viewport fit and capture the screenshots needed to support your claims.
59
+ 9. Clean up the Playwright session only when the task is actually finished.
60
+
61
+ ## Bootstrap (Run Once)
62
+
63
+ ```javascript
64
+ var chromium;
65
+ var electronLauncher;
66
+ var browser;
67
+ var context;
68
+ var page;
69
+ var mobileContext;
70
+ var mobilePage;
71
+ var electronApp;
72
+ var appWindow;
73
+
74
+ try {
75
+ ({ chromium, _electron: electronLauncher } = await import("playwright"));
76
+ console.log("Playwright loaded");
77
+ } catch (error) {
78
+ throw new Error(
79
+ `Could not load playwright from the current js_repl cwd. Run the setup commands from this workspace first. Original error: ${error}`
80
+ );
81
+ }
82
+ ```
83
+
84
+ Binding rules:
85
+
86
+ - Use `var` for the shared top-level Playwright handles because later `js_repl` cells reuse them.
87
+ - The setup cells below are intentionally short happy paths. If a handle looks stale, set that binding to `undefined` and rerun the cell instead of adding recovery logic everywhere.
88
+ - Prefer one named handle per surface you care about (`page`, `mobilePage`, `appWindow`) over repeatedly rediscovering pages from the context.
89
+
90
+ Shared web helpers:
91
+
92
+ ```javascript
93
+ var resetWebHandles = function () {
94
+ context = undefined;
95
+ page = undefined;
96
+ mobileContext = undefined;
97
+ mobilePage = undefined;
98
+ };
99
+
100
+ var ensureWebBrowser = async function () {
101
+ if (browser && !browser.isConnected()) {
102
+ browser = undefined;
103
+ resetWebHandles();
104
+ }
105
+
106
+ browser ??= await chromium.launch({ headless: false });
107
+ return browser;
108
+ };
109
+
110
+ var reloadWebContexts = async function () {
111
+ for (const currentContext of [context, mobileContext]) {
112
+ if (!currentContext) continue;
113
+ for (const p of currentContext.pages()) {
114
+ await p.reload({ waitUntil: "domcontentloaded" });
115
+ }
116
+ }
117
+ console.log("Reloaded existing web tabs");
118
+ };
119
+ ```
120
+
121
+ ## Choose Session Mode
122
+
123
+ For web apps, use an explicit viewport by default and treat native-window mode as a separate validation pass.
124
+
125
+ - Use an explicit viewport for routine iteration, breakpoint checks, reproducible screenshots, snapshot diffs, and model-assisted localization. This is the default because it is stable across machines and avoids host window-manager variability.
126
+ - When you need deterministic high-DPI behavior, keep the explicit viewport and add `deviceScaleFactor` rather than switching straight to native-window mode.
127
+ - Use native-window mode (`viewport: null`) for a separate headed pass when you need to validate launched window size, OS-level DPI behavior, browser chrome interactions, or bugs that may depend on the host display configuration.
128
+ - For Electron, assume native-window behavior all the time. Electron launches through Playwright with `noDefaultViewport`, so treat it like a real desktop window and check the as-launched size and layout before resizing anything.
129
+ - When signoff depends on both layout breakpoints and real desktop behavior, do both passes: explicit viewport first for deterministic QA, then native-window validation for final environment-specific checks.
130
+ - Treat switching modes as a context reset. Do not reuse a viewport-emulated `context` for a native-window pass or vice versa; close the old `page` and `context`, then create a new one for the new mode.
131
+
132
+ ## Start or Reuse Web Session
133
+
134
+ Desktop and mobile web sessions share the same `browser`, helpers, and QA flow. The main difference is which context and page pair you create.
135
+
136
+ ### Desktop Web Context
137
+
138
+ Set `TARGET_URL` to the app you are debugging. For local servers, prefer `127.0.0.1` over `localhost`.
139
+
140
+ ```javascript
141
+ var TARGET_URL = "http://127.0.0.1:3000";
142
+
143
+ if (page?.isClosed()) page = undefined;
144
+
145
+ await ensureWebBrowser();
146
+ context ??= await browser.newContext({
147
+ viewport: { width: 1600, height: 900 },
148
+ });
149
+ page ??= await context.newPage();
150
+
151
+ await page.goto(TARGET_URL, { waitUntil: "domcontentloaded" });
152
+ console.log("Loaded:", await page.title());
153
+ ```
154
+
155
+ If `context` or `page` is stale, set `context = page = undefined` and rerun the cell.
156
+
157
+ ### Mobile Web Context
158
+
159
+ Reuse `TARGET_URL` when it already exists; otherwise set a mobile target directly.
160
+
161
+ ```javascript
162
+ var MOBILE_TARGET_URL = typeof TARGET_URL === "string"
163
+ ? TARGET_URL
164
+ : "http://127.0.0.1:3000";
165
+
166
+ if (mobilePage?.isClosed()) mobilePage = undefined;
167
+
168
+ await ensureWebBrowser();
169
+ mobileContext ??= await browser.newContext({
170
+ viewport: { width: 390, height: 844 },
171
+ isMobile: true,
172
+ hasTouch: true,
173
+ });
174
+ mobilePage ??= await mobileContext.newPage();
175
+
176
+ await mobilePage.goto(MOBILE_TARGET_URL, { waitUntil: "domcontentloaded" });
177
+ console.log("Loaded mobile:", await mobilePage.title());
178
+ ```
179
+
180
+ If `mobileContext` or `mobilePage` is stale, set `mobileContext = mobilePage = undefined` and rerun the cell.
181
+
182
+ ### Native-Window Web Pass
183
+
184
+ ```javascript
185
+ var TARGET_URL = "http://127.0.0.1:3000";
186
+
187
+ await ensureWebBrowser();
188
+
189
+ await page?.close().catch(() => {});
190
+ await context?.close().catch(() => {});
191
+ page = undefined;
192
+ context = undefined;
193
+
194
+ browser ??= await chromium.launch({ headless: false });
195
+ context = await browser.newContext({ viewport: null });
196
+ page = await context.newPage();
197
+
198
+ await page.goto(TARGET_URL, { waitUntil: "domcontentloaded" });
199
+ console.log("Loaded native window:", await page.title());
200
+ ```
201
+
202
+ ## Start or Reuse Electron Session
203
+
204
+ Set `ELECTRON_ENTRY` to `.` when the current workspace is the Electron app and `package.json` points `main` to the right entry file. If you need to target a specific main-process file directly, use a path such as `./main.js` instead.
205
+
206
+ ```javascript
207
+ var ELECTRON_ENTRY = ".";
208
+
209
+ if (appWindow?.isClosed()) appWindow = undefined;
210
+
211
+ if (!appWindow && electronApp) {
212
+ await electronApp.close().catch(() => {});
213
+ electronApp = undefined;
214
+ }
215
+
216
+ electronApp ??= await electronLauncher.launch({
217
+ args: [ELECTRON_ENTRY],
218
+ });
219
+
220
+ appWindow ??= await electronApp.firstWindow();
221
+
222
+ console.log("Loaded Electron window:", await appWindow.title());
223
+ ```
224
+
225
+ If `js_repl` is not already running from the Electron app workspace, pass `cwd` explicitly when launching.
226
+
227
+ If the app process looks stale, set `electronApp = appWindow = undefined` and rerun the cell.
228
+
229
+ If you already have an Electron session but need a fresh process after a main-process, preload, or startup change, use the restart cell in the next section instead of rerunning this one.
230
+
231
+ ## Reuse Sessions During Iteration
232
+
233
+ Keep the same session alive whenever you can.
234
+
235
+ Web renderer reload:
236
+
237
+ ```javascript
238
+ await reloadWebContexts();
239
+ ```
240
+
241
+ Electron renderer-only reload:
242
+
243
+ ```javascript
244
+ await appWindow.reload({ waitUntil: "domcontentloaded" });
245
+ console.log("Reloaded Electron window");
246
+ ```
247
+
248
+ Electron restart after main-process, preload, or startup changes:
249
+
250
+ ```javascript
251
+ await electronApp.close().catch(() => {});
252
+ electronApp = undefined;
253
+ appWindow = undefined;
254
+
255
+ electronApp = await electronLauncher.launch({
256
+ args: [ELECTRON_ENTRY],
257
+ });
258
+
259
+ appWindow = await electronApp.firstWindow();
260
+ console.log("Relaunched Electron window:", await appWindow.title());
261
+ ```
262
+
263
+ If your launch requires an explicit `cwd`, include the same `cwd` here.
264
+
265
+ Default posture:
266
+
267
+ - Keep each `js_repl` cell short and focused on one interaction burst.
268
+ - Reuse the existing top-level bindings (`browser`, `context`, `page`, `electronApp`, `appWindow`) instead of redeclaring them.
269
+ - If you need isolation, create a new page or a new context inside the same browser.
270
+ - For Electron, use `electronApp.evaluate(...)` only for main-process inspection or purpose-built diagnostics.
271
+ - Fix helper mistakes in place; do not reset the REPL unless the kernel is actually broken.
272
+
273
+ ## Checklists
274
+
275
+ ### Session Loop
276
+
277
+ - Bootstrap `js_repl` once, then keep the same Playwright handles alive across iterations.
278
+ - Launch the target runtime from the current workspace.
279
+ - Make the code change.
280
+ - Reload or relaunch using the correct path for that change.
281
+ - Update the shared QA inventory if exploration reveals an additional control, state, or visible claim.
282
+ - Re-run functional QA.
283
+ - Re-run visual QA.
284
+ - Capture final artifacts only after the current state is the one you are evaluating.
285
+
286
+ ### Reload Decision
287
+
288
+ - Renderer-only change: reload the existing page or Electron window.
289
+ - Main-process, preload, or startup change: relaunch Electron.
290
+ - New uncertainty about process ownership or startup code: relaunch instead of guessing.
291
+
292
+ ### Functional QA
293
+
294
+ - Use real user controls for signoff: keyboard, mouse, click, touch, or equivalent Playwright input APIs.
295
+ - Verify at least one end-to-end critical flow.
296
+ - Confirm the visible result of that flow, not just internal state.
297
+ - For realtime or animation-heavy apps, verify behavior under actual interaction timing.
298
+ - Work through the shared QA inventory rather than ad hoc spot checks.
299
+ - Cover every obvious visible control at least once before signoff, not only the main happy path.
300
+ - For reversible controls or stateful toggles in the inventory, test the full cycle: initial state, changed state, and return to the initial state.
301
+ - After the scripted checks pass, do a short exploratory pass using normal input for 30-90 seconds instead of following only the intended path.
302
+ - If the exploratory pass reveals a new state, control, or claim, add it to the shared QA inventory and cover it before signoff.
303
+ - `page.evaluate(...)` and `electronApp.evaluate(...)` may inspect or stage state, but they do not count as signoff input.
304
+
305
+ ### Visual QA
306
+
307
+ - Treat visual QA as separate from functional QA.
308
+ - Use the same shared QA inventory defined before testing and updated during QA; do not start visual coverage from a different implicit list.
309
+ - Restate the user-visible claims and verify each one explicitly; do not assume a functional pass proves a visual claim.
310
+ - A user-visible claim is not signed off until it has been inspected in the specific state where it is meant to be perceived.
311
+ - Inspect the initial viewport before scrolling.
312
+ - Confirm that the initial view visibly supports the interface's primary claims; if a core promised element is not clearly perceptible there, treat that as a bug.
313
+ - Inspect all required visible regions, not just the main interaction surface.
314
+ - Inspect the states and modes already enumerated in the shared QA inventory, including at least one meaningful post-interaction state when the task is interactive.
315
+ - If motion or transitions are part of the experience, inspect at least one in-transition state in addition to the settled endpoints.
316
+ - If labels, overlays, annotations, guides, or highlights are meant to track changing content, verify that relationship after the relevant state change.
317
+ - For dynamic or interaction-dependent visuals, inspect long enough to judge stability, layering, and readability; do not rely on a single screenshot for signoff.
318
+ - For interfaces that can become denser after loading or interaction, inspect the densest realistic state you can reach during QA, not only the empty, loading, or collapsed state.
319
+ - If the product has a defined minimum supported viewport or window size, run a separate visual QA pass there; otherwise, choose a smaller but still realistic size and inspect it explicitly.
320
+ - Distinguish presence from implementation: if an intended affordance is technically there but not clearly perceptible because of weak contrast, occlusion, clipping, or instability, treat that as a visual failure.
321
+ - If any required visible region is clipped, cut off, obscured, or pushed outside the viewport in the state you are evaluating, treat that as a bug even if page-level scroll metrics appear acceptable.
322
+ - Look for clipping, overflow, distortion, layout imbalance, inconsistent spacing, alignment problems, illegible text, weak contrast, broken layering, and awkward motion states.
323
+ - Judge aesthetic quality as well as correctness. The UI should feel intentional, coherent, and visually pleasing for the task.
324
+ - Prefer viewport screenshots for signoff. Use full-page captures only as secondary debugging artifacts, and capture a focused screenshot when a region needs closer inspection.
325
+ - If motion makes a screenshot ambiguous, wait briefly for the UI to settle, then capture the image you are actually evaluating.
326
+ - Before signoff, explicitly ask: what visible part of this interface have I not yet inspected closely?
327
+ - Before signoff, explicitly ask: what visible defect would most likely embarrass this result if the user looked closely?
328
+
329
+ ### Signoff
330
+
331
+ - The functional path passed with normal user input.
332
+ - Coverage is explicit against the shared QA inventory: note which requirements, implemented features, controls, states, and claims were exercised, and call out any intentional exclusions.
333
+ - The visual QA pass covered the whole relevant interface.
334
+ - Each user-visible claim has a matching visual check and reviewed screenshot artifact from the state and viewport or window size where that claim matters.
335
+ - The viewport-fit checks passed for the intended initial view and any required minimum supported viewport or window size.
336
+ - If the product launches in a window, the as-launched size, placement, and initial layout were checked before any manual resize or repositioning.
337
+ - The UI is not just functional; it is visually coherent and not aesthetically weak for the task.
338
+ - Functional correctness, viewport fit, and visual quality must each pass on their own; one does not imply the others.
339
+ - A short exploratory pass was completed for interactive products, and the response mentions what that pass covered.
340
+ - If screenshot review and numeric checks disagreed at any point, the discrepancy was investigated before signoff; visible clipping in screenshots is a failure to resolve, not something metrics can overrule.
341
+ - Include a brief negative confirmation of the main defect classes you checked for and did not find.
342
+ - Cleanup was executed, or you intentionally kept the session alive for further work.
343
+
344
+ ## Screenshot Examples
345
+
346
+ If you plan to emit a screenshot through `codex.emitImage(...)`, use the CSS-normalized paths in the next section by default. Those are the canonical examples for screenshots that will be interpreted by the model or used for coordinate-based follow-up actions. Keep raw captures as an exception for fidelity-sensitive debugging only; the raw exception examples appear after the normalization guidance.
347
+
348
+ ### Model-bound screenshots (default)
349
+
350
+ If you will emit a screenshot with `codex.emitImage(...)` for model interpretation, normalize it to CSS pixels for the exact region you captured before emitting. This keeps returned coordinates aligned with Playwright CSS pixels if the reply is later used for clicking, and it also reduces image payload size and model token cost.
351
+
352
+ Do not emit raw native-window screenshots by default. Skip normalization only when you explicitly need device-pixel fidelity, such as Retina or DPI artifact debugging, pixel-accurate rendering inspection, or another fidelity-sensitive case where raw pixels matter more than payload size. For local-only inspection that will not be emitted to the model, raw capture is fine.
353
+
354
+ Do not assume `page.screenshot({ scale: "css" })` is enough in native-window mode (`viewport: null`). In Chromium on macOS Retina displays, headed native-window screenshots can still come back at device-pixel size even when `scale: "css"` is requested. The same caveat applies to Electron windows launched through Playwright because Electron runs with `noDefaultViewport`, and `appWindow.screenshot({ scale: "css" })` may still return device-pixel output.
355
+
356
+ Use separate normalization paths for web pages and Electron windows:
357
+
358
+ - Web: prefer `page.screenshot({ scale: "css" })` directly. If native-window Chromium still returns device-pixel output, resize inside the current page with canvas; no scratch page is required.
359
+ - Electron: do not use `appWindow.context().newPage()` or `electronApp.context().newPage()` as a scratch page. Electron contexts do not support that path reliably. Capture in the main process with `BrowserWindow.capturePage(...)`, resize with `nativeImage.resize(...)`, and emit those bytes directly.
360
+
361
+ Shared helpers and conventions:
362
+
363
+ ```javascript
364
+ var emitJpeg = async function (bytes) {
365
+ await codex.emitImage({
366
+ bytes,
367
+ mimeType: "image/jpeg",
368
+ });
369
+ };
370
+
371
+ var emitWebJpeg = async function (surface, options = {}) {
372
+ await emitJpeg(await surface.screenshot({
373
+ type: "jpeg",
374
+ quality: 85,
375
+ scale: "css",
376
+ ...options,
377
+ }));
378
+ };
379
+
380
+ var clickCssPoint = async function ({ surface, x, y, clip }) {
381
+ await surface.mouse.click(
382
+ clip ? clip.x + x : x,
383
+ clip ? clip.y + y : y
384
+ );
385
+ };
386
+
387
+ var tapCssPoint = async function ({ page, x, y, clip }) {
388
+ await page.touchscreen.tap(
389
+ clip ? clip.x + x : x,
390
+ clip ? clip.y + y : y
391
+ );
392
+ };
393
+ ```
394
+
395
+ - Use `page` or `mobilePage` for web, or `appWindow` for Electron, as the `surface`.
396
+ - Treat `clip` as CSS pixels from `getBoundingClientRect()` in the renderer.
397
+ - Prefer JPEG at `quality: 85` unless lossless fidelity is specifically required.
398
+ - For full-image captures, use returned `{ x, y }` directly.
399
+ - For clipped captures, add the clip origin back when clicking.
400
+
401
+ ### Web CSS normalization
402
+
403
+ Preferred web path for explicit-viewport contexts, and often for web in general:
404
+
405
+ ```javascript
406
+ await emitWebJpeg(page);
407
+ ```
408
+
409
+ Mobile web uses the same path; substitute `mobilePage` for `page`:
410
+
411
+ ```javascript
412
+ await emitWebJpeg(mobilePage);
413
+ ```
414
+
415
+ If the model returns `{ x, y }`, click it directly:
416
+
417
+ ```javascript
418
+ await clickCssPoint({ surface: page, x, y });
419
+ ```
420
+
421
+ Mobile web click path:
422
+
423
+ ```javascript
424
+ await tapCssPoint({ page: mobilePage, x, y });
425
+ ```
426
+
427
+ For web `clip` screenshots or element screenshots in this normal path, `scale: "css"` usually works directly. Add the region origin back when clicking.
428
+
429
+ - `await emitWebJpeg(page, { clip })`
430
+ - `await emitWebJpeg(mobilePage, { clip })`
431
+ - `await clickCssPoint({ surface: page, clip, x, y })`
432
+ - `await tapCssPoint({ page: mobilePage, clip, x, y })`
433
+ - `await clickCssPoint({ surface: page, clip: box, x, y })` after `const box = await locator.boundingBox()`
434
+
435
+ Web native-window fallback when `scale: "css"` still comes back at device-pixel size:
436
+
437
+ ```javascript
438
+ var emitWebScreenshotCssScaled = async function ({ page, clip, quality = 0.85 } = {}) {
439
+ var NodeBuffer = (await import("node:buffer")).Buffer;
440
+ const target = clip
441
+ ? { width: clip.width, height: clip.height }
442
+ : await page.evaluate(() => ({
443
+ width: window.innerWidth,
444
+ height: window.innerHeight,
445
+ }));
446
+
447
+ const screenshotBuffer = await page.screenshot({
448
+ type: "png",
449
+ ...(clip ? { clip } : {}),
450
+ });
451
+
452
+ const bytes = await page.evaluate(
453
+ async ({ imageBase64, targetWidth, targetHeight, quality }) => {
454
+ const image = new Image();
455
+ image.src = `data:image/png;base64,${imageBase64}`;
456
+ await image.decode();
457
+
458
+ const canvas = document.createElement("canvas");
459
+ canvas.width = targetWidth;
460
+ canvas.height = targetHeight;
461
+
462
+ const ctx = canvas.getContext("2d");
463
+ ctx.imageSmoothingEnabled = true;
464
+ ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
465
+
466
+ const blob = await new Promise((resolve) =>
467
+ canvas.toBlob(resolve, "image/jpeg", quality)
468
+ );
469
+
470
+ return new Uint8Array(await blob.arrayBuffer());
471
+ },
472
+ {
473
+ imageBase64: NodeBuffer.from(screenshotBuffer).toString("base64"),
474
+ targetWidth: target.width,
475
+ targetHeight: target.height,
476
+ quality,
477
+ }
478
+ );
479
+
480
+ await emitJpeg(bytes);
481
+ };
482
+ ```
483
+
484
+ For a full viewport fallback capture, treat returned `{ x, y }` as direct CSS coordinates:
485
+
486
+ ```javascript
487
+ await emitWebScreenshotCssScaled({ page });
488
+ await clickCssPoint({ surface: page, x, y });
489
+ ```
490
+
491
+ For a clipped fallback capture, add the clip origin back:
492
+
493
+ ```javascript
494
+ await emitWebScreenshotCssScaled({ page, clip });
495
+ await clickCssPoint({ surface: page, clip, x, y });
496
+ ```
497
+
498
+ ### Electron CSS normalization
499
+
500
+ For Electron, normalize in the main process instead of opening a scratch Playwright page. The helper below returns CSS-scaled bytes for the full content area or for a clipped CSS-pixel region. Treat `clip` as content-area CSS pixels, for example values taken from `getBoundingClientRect()` in the renderer.
501
+
502
+ ```javascript
503
+ var emitElectronScreenshotCssScaled = async function ({ electronApp, clip, quality = 85 } = {}) {
504
+ const bytes = await electronApp.evaluate(async ({ BrowserWindow }, { clip, quality }) => {
505
+ const win = BrowserWindow.getAllWindows()[0];
506
+ const image = clip ? await win.capturePage(clip) : await win.capturePage();
507
+
508
+ const target = clip
509
+ ? { width: clip.width, height: clip.height }
510
+ : (() => {
511
+ const [width, height] = win.getContentSize();
512
+ return { width, height };
513
+ })();
514
+
515
+ const resized = image.resize({
516
+ width: target.width,
517
+ height: target.height,
518
+ quality: "best",
519
+ });
520
+
521
+ return resized.toJPEG(quality);
522
+ }, { clip, quality });
523
+
524
+ await emitJpeg(bytes);
525
+ };
526
+ ```
527
+
528
+ Full Electron window:
529
+
530
+ ```javascript
531
+ await emitElectronScreenshotCssScaled({ electronApp });
532
+ await clickCssPoint({ surface: appWindow, x, y });
533
+ ```
534
+
535
+ Clipped Electron region using CSS pixels from the renderer:
536
+
537
+ ```javascript
538
+ var clip = await appWindow.evaluate(() => {
539
+ const rect = document.getElementById("board").getBoundingClientRect();
540
+ return {
541
+ x: Math.round(rect.x),
542
+ y: Math.round(rect.y),
543
+ width: Math.round(rect.width),
544
+ height: Math.round(rect.height),
545
+ };
546
+ });
547
+
548
+ await emitElectronScreenshotCssScaled({ electronApp, clip });
549
+ await clickCssPoint({ surface: appWindow, clip, x, y });
550
+ ```
551
+
552
+ ### Raw Screenshot Exception Examples
553
+
554
+ Use these only when raw pixels matter more than CSS-coordinate alignment, such as Retina or DPI artifact debugging, pixel-accurate rendering inspection, or other fidelity-sensitive review.
555
+
556
+ Web desktop raw emit:
557
+
558
+ ```javascript
559
+ await codex.emitImage({
560
+ bytes: await page.screenshot({ type: "jpeg", quality: 85 }),
561
+ mimeType: "image/jpeg",
562
+ });
563
+ ```
564
+
565
+ Electron raw emit:
566
+
567
+ ```javascript
568
+ await codex.emitImage({
569
+ bytes: await appWindow.screenshot({ type: "jpeg", quality: 85 }),
570
+ mimeType: "image/jpeg",
571
+ });
572
+ ```
573
+
574
+ Mobile raw emit after the mobile web context is already running:
575
+
576
+ ```javascript
577
+ await codex.emitImage({
578
+ bytes: await mobilePage.screenshot({ type: "jpeg", quality: 85 }),
579
+ mimeType: "image/jpeg",
580
+ });
581
+ ```
582
+
583
+ ## Viewport Fit Checks (Required)
584
+
585
+ Do not assume a screenshot is acceptable just because the main widget is visible. Before signoff, explicitly verify that the intended initial view matches the product requirement, using both screenshot review and numeric checks.
586
+
587
+ - Define the intended initial view before signoff. For scrollable pages, this is the above-the-fold experience. For app-like shells, games, editors, dashboards, or tools, this is the full interactive surface plus the controls and status needed to use it.
588
+ - Use screenshots as the primary evidence for fit. Numeric checks support the screenshots; they do not overrule visible clipping.
589
+ - Signoff fails if any required visible region is clipped, cut off, obscured, or pushed outside the viewport in the intended initial view, even if page-level scroll metrics appear acceptable.
590
+ - Scrolling is acceptable when the product is designed to scroll and the initial view still communicates the core experience and exposes the primary call to action or required starting context.
591
+ - For fixed-shell interfaces, scrolling is not an acceptable workaround if it is needed to reach part of the primary interactive surface or essential controls.
592
+ - Do not rely on document scroll metrics alone. Fixed-height shells, internal panes, and hidden-overflow containers can clip required UI while page-level scroll checks still look clean.
593
+ - Check region bounds, not just document bounds. Verify that each required visible region fits within the viewport in the startup state.
594
+ - For Electron or desktop apps, verify both the launched window size and placement and the renderer's initial visible layout before any manual resize or repositioning.
595
+ - Passing viewport-fit checks only proves that the intended initial view is visible without unintended clipping or scrolling. It does not prove that the UI is visually correct or aesthetically successful.
596
+
597
+ Web or renderer check:
598
+
599
+ ```javascript
600
+ console.log(await page.evaluate(() => ({
601
+ innerWidth: window.innerWidth,
602
+ innerHeight: window.innerHeight,
603
+ clientWidth: document.documentElement.clientWidth,
604
+ clientHeight: document.documentElement.clientHeight,
605
+ scrollWidth: document.documentElement.scrollWidth,
606
+ scrollHeight: document.documentElement.scrollHeight,
607
+ canScrollX: document.documentElement.scrollWidth > document.documentElement.clientWidth,
608
+ canScrollY: document.documentElement.scrollHeight > document.documentElement.clientHeight,
609
+ })));
610
+ ```
611
+
612
+ Electron check:
613
+
614
+ ```javascript
615
+ console.log(await appWindow.evaluate(() => ({
616
+ innerWidth: window.innerWidth,
617
+ innerHeight: window.innerHeight,
618
+ clientWidth: document.documentElement.clientWidth,
619
+ clientHeight: document.documentElement.clientHeight,
620
+ scrollWidth: document.documentElement.scrollWidth,
621
+ scrollHeight: document.documentElement.scrollHeight,
622
+ canScrollX: document.documentElement.scrollWidth > document.documentElement.clientWidth,
623
+ canScrollY: document.documentElement.scrollHeight > document.documentElement.clientHeight,
624
+ })));
625
+ ```
626
+
627
+ Augment the numeric check with `getBoundingClientRect()` checks for the required visible regions in your specific UI when clipping is a realistic failure mode; document-level metrics alone are not sufficient for fixed shells.
628
+
629
+ ## Dev Server
630
+
631
+ For local web debugging, keep the app running in a persistent TTY session. Do not rely on one-shot background commands from a short-lived shell.
632
+
633
+ Use the project's normal start command, for example:
634
+
635
+ ```bash
636
+ npm start
637
+ ```
638
+
639
+ Before `page.goto(...)`, verify the chosen port is listening and the app responds.
640
+
641
+ For Electron debugging, launch the app from `js_repl` through `_electron.launch(...)` so the same session owns the process. If the Electron renderer depends on a separate dev server (for example Vite or Next), keep that server running in a persistent TTY session and then relaunch or reload the Electron app from `js_repl`.
642
+
643
+ ## Cleanup
644
+
645
+ Only run cleanup when the task is actually finished:
646
+
647
+ - This cleanup is manual. Exiting Codex, closing the terminal, or losing the `js_repl` session does not implicitly run `electronApp.close()`, `context.close()`, or `browser.close()`.
648
+ - For Electron specifically, assume the app may keep running if you leave the session without executing the cleanup cell first.
649
+
650
+ ```javascript
651
+ if (electronApp) {
652
+ await electronApp.close().catch(() => {});
653
+ }
654
+
655
+ if (mobileContext) {
656
+ await mobileContext.close().catch(() => {});
657
+ }
658
+
659
+ if (context) {
660
+ await context.close().catch(() => {});
661
+ }
662
+
663
+ if (browser) {
664
+ await browser.close().catch(() => {});
665
+ }
666
+
667
+ browser = undefined;
668
+ context = undefined;
669
+ page = undefined;
670
+ mobileContext = undefined;
671
+ mobilePage = undefined;
672
+ electronApp = undefined;
673
+ appWindow = undefined;
674
+
675
+ console.log("Playwright session closed");
676
+ ```
677
+
678
+ If you plan to exit Codex immediately after debugging, run the cleanup cell first and wait for the `"Playwright session closed"` log before quitting.
679
+
680
+ ## Common Failure Modes
681
+
682
+ - `Cannot find module 'playwright'`: run the one-time setup in the current workspace and verify the import before using `js_repl`.
683
+ - Playwright package is installed but the browser executable is missing: run `npx playwright install chromium`.
684
+ - `page.goto: net::ERR_CONNECTION_REFUSED`: make sure the dev server is still running in a persistent TTY session, recheck the port, and prefer `http://127.0.0.1:<port>`.
685
+ - `electron.launch` hangs, times out, or exits immediately: verify the local `electron` dependency, confirm the `args` target, and make sure any renderer dev server is already running before launch.
686
+ - `Identifier has already been declared`: reuse the existing top-level bindings, choose a new name, or wrap the code in `{ ... }`. Use `js_repl_reset` only when the kernel is genuinely stuck.
687
+ - `browserContext.newPage: Protocol error (Target.createTarget): Not supported` while working with Electron: do not use `appWindow.context().newPage()` or `electronApp.context().newPage()` as a scratch page; use the Electron-specific screenshot normalization flow in the model-bound screenshots section.
688
+ - `js_repl` timed out or reset: rerun the bootstrap cell and recreate the session with shorter, more focused cells.
689
+ - Browser launch or network operations fail immediately: confirm the session was started with `--sandbox danger-full-access` and restart that way if needed.