oh-my-opencode 5.0.0-beta.62 → 5.0.0-beta.64

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 (249) hide show
  1. package/THIRD-PARTY-NOTICES.md +8 -6
  2. package/dist/cli/doctor/checks/browser-provider.d.ts +2 -0
  3. package/dist/cli/index.js +70 -41
  4. package/dist/cli-node/index.js +70 -41
  5. package/dist/config/schema/agent-names.d.ts +0 -1
  6. package/dist/config/schema/browser-automation.d.ts +0 -2
  7. package/dist/config/schema/oh-my-opencode-config.d.ts +0 -1
  8. package/dist/hooks/comment-checker/__fixtures__/download-probe.fixture.d.ts +1 -0
  9. package/dist/index.js +89 -588
  10. package/dist/oh-my-opencode.schema.json +4 -5
  11. package/dist/skills/ast-grep/SKILL.md +12 -0
  12. package/dist/skills/debugging/references/tools/playwright-cli.md +79 -161
  13. package/dist/skills/frontend/SKILL.md +1 -1
  14. package/dist/skills/frontend/references/design/aside.md +1 -1
  15. package/dist/skills/frontend/references/design/clone-from-url.md +1 -1
  16. package/dist/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  17. package/dist/skills/review-work/SKILL.md +1 -1
  18. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +1 -82
  19. package/dist/skills/ultimate-browsing/SKILL.md +17 -29
  20. package/dist/skills/ultimate-browsing/engine/AGENTS.md +2 -1
  21. package/dist/skills/ultimate-browsing/engine/templates/package.json +2 -2
  22. package/dist/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  23. package/dist/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  24. package/dist/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  25. package/dist/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  26. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +86 -100
  27. package/dist/skills/ultimate-browsing/references/insane-search/README.md +9 -3
  28. package/dist/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  29. package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  30. package/dist/skills/ulw-execute/SKILL.md +1 -1
  31. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  32. package/dist/skills/ulw-research/SKILL.md +3 -3
  33. package/dist/skills/visual-qa/AGENTS.md +1 -1
  34. package/dist/skills/visual-qa/SKILL.md +1 -1
  35. package/dist/skills/visual-qa/references/browser-setup.md +75 -0
  36. package/dist/tui.js +18 -11
  37. package/package.json +16 -23
  38. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  39. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +4 -2
  40. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  41. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  42. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  43. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  44. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  45. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  47. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  48. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  49. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  50. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  52. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  53. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  56. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  57. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  58. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +5 -4
  59. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  60. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  61. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  62. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +1 -1
  63. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  64. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  65. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +13 -0
  66. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +5 -4
  67. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +7 -5
  68. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +7 -2
  69. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +7 -4
  70. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +931 -442
  71. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +6 -0
  72. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +20 -12
  73. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +8 -0
  74. package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.d.ts +4 -0
  75. package/packages/omo-codex/plugin/components/ulw-loop/dist/driver-objective-ack.js +18 -0
  76. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.d.ts +1 -0
  77. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence-artifacts.js +37 -0
  78. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +1 -0
  79. package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +24 -12
  80. package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.d.ts +4 -0
  81. package/packages/omo-codex/plugin/components/ulw-loop/dist/ledger.js +34 -0
  82. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +1 -0
  83. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +6 -0
  84. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.d.ts +19 -0
  85. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-commit.js +107 -0
  86. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +6 -2
  87. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +54 -25
  88. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.d.ts +10 -3
  89. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.js +38 -31
  90. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +9 -7
  91. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +105 -114
  92. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.d.ts +15 -0
  93. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-log.js +86 -0
  94. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.d.ts +5 -1
  95. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-missing-recovery.js +15 -3
  96. package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +11 -8
  97. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/factory.js +28 -12
  98. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.d.ts +335 -0
  99. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/manifest.js +109 -10
  100. package/packages/omo-codex/plugin/components/ulw-loop/dist/sdk/types.d.ts +3 -0
  101. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.d.ts +5 -0
  102. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-budget-io.js +67 -0
  103. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +8 -62
  104. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.d.ts +11 -1
  105. package/packages/omo-codex/plugin/components/ulw-loop/dist/state-lock.js +120 -88
  106. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.d.ts +3 -2
  107. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +18 -10
  108. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +4 -4
  109. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +3 -2
  110. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +4 -4
  111. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +9 -1
  112. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +3 -2
  113. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +11 -11
  114. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +8 -17
  115. package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.d.ts +9 -0
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/success-criteria-input.js +41 -0
  117. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  118. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  119. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -2
  120. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +15 -3
  121. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +7 -4
  122. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +26 -14
  123. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +8 -0
  124. package/packages/omo-codex/plugin/components/ulw-loop/src/driver-objective-ack.ts +20 -0
  125. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence-artifacts.ts +45 -0
  126. package/packages/omo-codex/plugin/components/ulw-loop/src/evidence.ts +23 -16
  127. package/packages/omo-codex/plugin/components/ulw-loop/src/ledger.ts +33 -0
  128. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +7 -0
  129. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-commit.ts +124 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +67 -54
  131. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-goal-factory.ts +63 -31
  132. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +126 -140
  133. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-log.ts +84 -0
  134. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-missing-recovery.ts +26 -3
  135. package/packages/omo-codex/plugin/components/ulw-loop/src/review-blockers.ts +11 -7
  136. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/factory.ts +47 -12
  137. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/manifest.ts +124 -10
  138. package/packages/omo-codex/plugin/components/ulw-loop/src/sdk/types.ts +3 -0
  139. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-budget-io.ts +59 -0
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +8 -59
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/state-lock.ts +129 -111
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +19 -10
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +4 -4
  144. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +5 -4
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +13 -1
  146. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +12 -10
  147. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +8 -16
  148. package/packages/omo-codex/plugin/components/ulw-loop/src/success-criteria-input.ts +56 -0
  149. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +37 -1
  150. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/barrier.ts +13 -0
  151. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-child.ts +65 -0
  152. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-cli-qa.mjs +76 -0
  153. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-crash.ts +23 -0
  154. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-mutations.mjs +58 -0
  155. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/commit-writer.ts +65 -0
  156. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/lease-clock.ts +23 -0
  157. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-log.test.ts +252 -0
  158. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-commit-recovery.test.ts +190 -0
  159. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +50 -35
  160. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-log-newest.test.ts +72 -0
  161. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-completed-plan.test.ts +43 -0
  162. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-driver-states.test.ts +33 -4
  163. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-dx.test.ts +219 -0
  164. package/packages/omo-codex/plugin/components/ulw-loop/test/sdk-session-context.test.ts +21 -0
  165. package/packages/omo-codex/plugin/components/ulw-loop/test/state-lock.test.ts +92 -0
  166. package/packages/omo-codex/plugin/components/ulw-loop/test/status-next-actions-surface.test.ts +133 -0
  167. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +12 -12
  168. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +4 -1
  169. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  170. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  171. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  172. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  173. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  174. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  175. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  176. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  177. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  178. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  179. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  180. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  181. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  182. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  183. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  184. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  185. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  186. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  187. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  188. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  189. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  190. package/packages/omo-codex/plugin/package-lock.json +12 -12
  191. package/packages/omo-codex/plugin/package.json +1 -1
  192. package/packages/omo-codex/plugin/scripts/sync-skills.d.mts +4 -0
  193. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +15 -7
  194. package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +12 -0
  195. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +79 -161
  196. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +1 -1
  197. package/packages/omo-codex/plugin/skills/frontend/references/design/aside.md +1 -1
  198. package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
  199. package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  200. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +1 -1
  201. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +1 -82
  202. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +17 -29
  203. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +2 -1
  204. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +2 -2
  205. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  206. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  207. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  208. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  209. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +86 -100
  210. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +9 -3
  211. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  212. package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  213. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +5 -4
  214. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +1 -1
  215. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -2
  216. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +3 -3
  217. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +1 -1
  218. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +1 -1
  219. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +75 -0
  220. package/packages/omo-codex/scripts/install-dist/install-local.mjs +6 -4
  221. package/packages/prompts-core/prompts/ultrawork/codex.md +5 -4
  222. package/packages/shared-skills/skills/ast-grep/SKILL.md +12 -0
  223. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +79 -161
  224. package/packages/shared-skills/skills/frontend/SKILL.md +1 -1
  225. package/packages/shared-skills/skills/frontend/references/design/aside.md +1 -1
  226. package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
  227. package/packages/shared-skills/skills/frontend/scripts/perfection/lighthouse-audit.py +2 -2
  228. package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
  229. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +1 -82
  230. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +17 -29
  231. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +2 -1
  232. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +2 -2
  233. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_mobile_chrome.js +5 -2
  234. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/playwright_real_chrome.js +8 -6
  235. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +86 -0
  236. package/packages/shared-skills/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +4 -7
  237. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +86 -100
  238. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +9 -3
  239. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +16 -13
  240. package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +3 -3
  241. package/packages/shared-skills/skills/ulw-execute/SKILL.md +1 -1
  242. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +1 -1
  243. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  244. package/packages/shared-skills/skills/visual-qa/AGENTS.md +1 -1
  245. package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
  246. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +75 -0
  247. package/dist/skills/visual-qa/references/agent-browser-setup.md +0 -45
  248. package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +0 -45
  249. package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +0 -45
@@ -16,10 +16,10 @@
16
16
 
17
17
  ### 의존성
18
18
 
19
- ```bash
20
- claude mcp list 2>/dev/null | grep -q playwright && echo "OK" || echo "NOT CONNECTED"
21
- claude mcp add playwright -- npx @playwright/mcp@latest
22
- ```
19
+ 이 항목은 이미 연결된 MCP를 사용하는 엔진 어댑터의 설명이다.
20
+ 새 브라우저 세션은 js eval의 Bun.WebView(Bun >= 1.4, macOS 기본;
21
+ Linux/Windows는 설치된 Chrome/Chromium/Edge 필요), 그 외 또는 Chrome 동작·stealth·trace·인증은
22
+ 로컬 Chrome을 제어하는 `playwright-core` 스크립트로 실행한다. MCP를 새로 설치하지 않는다.
23
23
 
24
24
  ### 기본 워크플로
25
25
 
@@ -56,11 +56,11 @@ claude mcp add playwright -- npx @playwright/mcp@latest
56
56
  # Node (시스템 설치)
57
57
  node -v # v18+ 권장
58
58
 
59
- # Playwright + stealth 플러그인
60
- npm i -g playwright playwright-extra puppeteer-extra-plugin-stealth
61
-
62
- # 시스템 Chrome 바이너리 (번들 Chromium 아님)
63
- npx playwright install chrome
59
+ # 사용자가 엔진 디렉터리에서 한 번 설치하는 스크립트 의존성
60
+ cd "$SKILL_DIR/engine"
61
+ test -f package.json || cp templates/package.json package.json
62
+ bun add playwright-core@1.62.1 playwright-extra@4.3.6 puppeteer-extra-plugin-stealth@2.11.2
63
+ # Chrome은 이미 시스템에 설치되어 있어야 한다. 브라우저 다운로드 명령은 없다.
64
64
  ```
65
65
 
66
66
  ### 호출 (engine 내부)
@@ -81,7 +81,8 @@ attempt, html = run_playwright_fallback(
81
81
  ### 데스크톱 템플릿 (`playwright_real_chrome.js`)
82
82
 
83
83
  ```js
84
- const { chromium } = require('playwright-extra');
84
+ const { addExtra } = require('playwright-extra');
85
+ const chromium = addExtra(require('playwright-core').chromium);
85
86
  const stealth = require('puppeteer-extra-plugin-stealth')();
86
87
  chromium.use(stealth);
87
88
 
@@ -95,7 +96,9 @@ const ctx = await chromium.launchPersistentContext(profileDir, {
95
96
  ### 모바일 템플릿 (`playwright_mobile_chrome.js`)
96
97
 
97
98
  ```js
98
- const { chromium, devices } = require('playwright-extra');
99
+ const { devices } = require('playwright-core');
100
+ const { addExtra } = require('playwright-extra');
101
+ const chromium = addExtra(require('playwright-core').chromium);
99
102
  const iPhone = devices['iPhone 13 Pro'];
100
103
 
101
104
  const ctx = await chromium.launchPersistentContext(profileDir, {
@@ -126,8 +129,8 @@ const ctx = await chromium.launchPersistentContext(profileDir, {
126
129
 
127
130
  ## 디버깅 팁
128
131
 
129
- - `profileDir`를 고정 경로로 두면 세션·쿠키가 유지되어 재시도 빠름 (`/tmp/.insane_pw_profile`)
130
- - Akamai 재시도가 잦으면 `profileDir`를 삭제해 fresh 상태로 리셋
132
+ - 템플릿은 js eval에서 스크립트로 실행한다. `profileDir`는 작업 전용 경로나 사용자 프로필의 복제본만 사용한다.
133
+ - 사용자의 실제 프로필을 실행·초기화·삭제하지 않는다. 작업 종료 시 컨텍스트를 닫고 작업 전용 복제본만 정리한다.
131
134
  - 실패 시 `result.trace`의 `error` 필드에 Node stderr 200자가 포함됨
132
135
 
133
136
  ## 사이트 예시 (독자 이해용, 코드 분기 근거 아님)
@@ -4,7 +4,7 @@
4
4
  The OS-keyring lookup is an injected boundary: cookie_paths resolves profile
5
5
  paths and cookie_crypto derives keys + decrypts values, both pure and testable
6
6
  with synthetic fixtures on any OS. This module wires them to a real browser DB
7
- and the agent-browser CDP session.
7
+ and a local Chrome CDP session controlled by playwright-core scripts.
8
8
 
9
9
  Usage:
10
10
  python extract_cookies.py --browser chrome --domain youtube.com --output /tmp/cookies.json
@@ -255,7 +255,7 @@ def inject_cookies(cookies: list[CookieRecord], cdp_port: int) -> None:
255
255
  if proc.returncode != 0:
256
256
  raise RuntimeError((proc.stderr or "CDP cookie injection failed").strip())
257
257
  ok = int((proc.stdout or "0").strip() or "0")
258
- print(f"Injected {ok}/{len(filtered)} cookies into agent-browser (CDP {cdp_port})")
258
+ print(f"Injected {ok}/{len(filtered)} cookies into local Chrome (playwright-core CDP {cdp_port})")
259
259
 
260
260
 
261
261
  def main() -> None:
@@ -263,7 +263,7 @@ def main() -> None:
263
263
  parser.add_argument("--browser", required=True, choices=sorted(BROWSERS.keys()))
264
264
  parser.add_argument("--domain", required=True, action="append", dest="domains")
265
265
  parser.add_argument("--output", help="Write cookies JSON to file")
266
- parser.add_argument("--inject", action="store_true", help="Inject into agent-browser")
266
+ parser.add_argument("--inject", action="store_true", help="Inject into the local Chrome CDP endpoint used by a playwright-core script")
267
267
  parser.add_argument("--cdp", type=int, default=9242, help="CDP port (default 9242)")
268
268
  args = parser.parse_args()
269
269
 
@@ -69,16 +69,17 @@ exercises the surface; capture the artifact.
69
69
  for color / layout / CJK evidence, which degrades truecolor.
70
70
  3. Browser use — in Codex, use `browser:control-in-app-browser`
71
71
  first when available and no authenticated/persistent user browser
72
- profile is required. Otherwise use Chrome to drive the REAL page;
73
- if Chrome is not available, download and use agent-browser
74
- (https://github.com/vercel-labs/agent-browser). Capture action
72
+ profile is required. Otherwise, or for Chrome semantics, stealth,
73
+ or trace, WRITE a `playwright-core` script and run it from js eval
74
+ against local Chrome (`chromium.launch({ channel: "chrome" })` /
75
+ `launchPersistentContext` on a CLONED profile). Capture action
75
76
  log + screenshot path. Never downgrade to a non-browser surface
76
77
  for a browser-facing criterion. NEVER clear cookies, cache, or
77
78
  site data (`Network.clearBrowserCookies`, `Storage.clearCookies`,
78
79
  `chrome.browsingData.remove`, "clear browsing data") on the user's
79
80
  real/main browser profile — it wipes their logged-in state. If you
80
81
  need that profile's login state, clone it first (`rsync -a
81
- <profile>/ <tmp-clone>/`) and launch Chrome / agent-browser against
82
+ <profile>/ <tmp-clone>/`) and launch Chrome against
82
83
  the clone as the user-data-dir; run any clearing there only.
83
84
  4. Computer use — when the surface is a desktop/GUI app rather than a
84
85
  page, drive it via OS-level automation (a computer-use agent,
@@ -169,7 +169,7 @@ Each sub-task message must include:
169
169
  5. One Manual-QA channel, named with the exact tool and exact invocation (the literal `curl`, `send-keys`, `browser:control-in-app-browser` action, `page.click`, payload, selectors, and the binary observable that decides PASS/FAIL), not "verify it works". A LIGHT checkbox needs one real-surface proof of its deliverable, and auxiliary surfaces (CLI stdout, DB state diff, parsed config dump) are first-class when the surface is CLI- or data-shaped:
170
170
  - HTTP call: `curl -i` against the live endpoint.
171
171
  - Terminal / TUI: drive a real pty; `tmux send-keys` is fine for a boot/behavior smoke, but color/layout/CJK evidence goes through the xterm.js web terminal below, NEVER `tmux capture-pane`.
172
- - Browser use: prefer the harness's in-app browser control when available and the scenario does not need an authenticated or persistent user browser profile; otherwise drive the real page with Chrome, or agent-browser (https://github.com/vercel-labs/agent-browser) when Chrome is unavailable.
172
+ - Browser use: from js eval, use `new Bun.WebView()` on Bun >= 1.4 (macOS default; Linux/Windows need Chrome/Chromium/Edge). Otherwise, or for Chrome semantics, stealth, trace, or auth, write and run a `playwright-core` script against local Chrome (`channel: "chrome"`; persistent context on a CLONED profile). Codex: `browser:control-in-app-browser` for ordinary page control.
173
173
  - Computer use: OS-level GUI automation against the running desktop app when the surface is not a page.
174
174
  - TUI visual evidence: when a TUI claim needs visual QA or PR proof, run `bun script/qa/web-terminal-visual-qa.mjs --command "<cmd>" --input "{Enter}" --evidence-dir <dir>` (real pty rendered through xterm.js in Chrome) and attach `terminal.png` plus `metadata.json`.
175
175
  6. The adversarial classes that apply to this sub-task (from the 9 ultraqa classes) and how each is probed.
@@ -20,7 +20,7 @@ Run each criterion's real-surface proof yourself through the channel that faithf
20
20
 
21
21
  1. **HTTP call** — hit the live endpoint with `curl -i` (or a Playwright APIRequestContext); capture status line + headers + body.
22
22
  2. **Terminal / TUI** - prove it through the xterm.js web terminal; tmux `send-keys` is fine for a boot smoke, but NEVER `tmux capture-pane` for color/layout/CJK evidence (it degrades truecolor).
23
- 3. **Browser use** — in Codex, use `browser:control-in-app-browser` first when available and the scenario does not need an authenticated or persistent user browser profile. Otherwise use Chrome to drive the REAL page; if unavailable, use agent-browser. Capture action log + screenshot path. Never downgrade a browser-facing criterion.
23
+ 3. **Browser use** — in Codex, prefer `browser:control-in-app-browser`. Otherwise, or for Chrome semantics, stealth, trace, or auth, WRITE a `playwright-core` script and run it from js eval against local Chrome (`channel: "chrome"`; persistent context on a CLONED profile, never the live one). Capture action log + screenshot path. Never downgrade a browser-facing criterion.
24
24
  4. **Computer use** — for desktop/GUI apps, drive the running app via OS automation (computer-use, AppleScript, xdotool, etc.); capture action log + screenshot.
25
25
 
26
26
  For TUI visual QA (mandatory when a PR or review must inspect the terminal screen),
@@ -165,7 +165,7 @@ Loop per goal. Cap at 5 cycles per goal. Cap identical same-criterion failures a
165
165
  4. INTEGRATE + CRITICAL SELF-QA + GIT CHECKPOINT (EVERY WORKER RETURN): do NOT trust the worker's report. Read the diff yourself, re-run its tests, and run LSP diagnostics on the changed files. Treat "done" as a claim to disprove. If the diff drifts, the test is hollow, or evidence is missing, RESPAWN the worker with the specific failure context. Once the work unit is verified, use `git-master` before staging: inspect recent repository commits and touched-path history to infer commit language, Conventional Commit scope, message shape, and unit size. Stage only that unit's files and commit in the observed style; do not carry verified work forward into a later omnibus commit. If no git-tracked files changed or committing is unsafe, record the no-commit reason as evidence. Forward every finding/learning to subsequent workers.
166
166
  5. EXECUTE-AS-SCENARIO: ACTUALLY run the Manual-QA scenario the criterion named (channel table above). Run it yourself for the orchestrator check; for heavier flows dispatch a dedicated QA execution worker (`lazycodex-worker-medium` by default; `lazycodex-worker-high` when the QA flow itself is hard) whose ONLY job is to drive the channel and write the artifact to the named evidence path. If the scenario FAILS, respawn the implementing worker with the captured failure — do not hand-patch around it.
167
167
  6. CAPTURE: collect the observable artifact path: transcript, stdout, screenshot, assertion, status+body, diff, or parsed dump. No artifact written at the evidence path — not done; record BLOCKED and respawn QA.
168
- 7. CLEAN (PAIRED, NEVER SKIP): tear down every runtime artifact step 5 spawned BEFORE recording — server PIDs (`kill`, verify `kill -0` fails), `tmux` sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`), browser / Playwright contexts (`.close()`), containers (`docker rm -f`), bound ports (`lsof -i :<port>` empty), temp sockets / files / dirs (`rm -rf` the `mktemp` paths), QA-only env vars, AND close every finished worker (v1 `close_agent`; on V2 finished workers end on their own — `interrupt_agent` any still running). Register each teardown as its own todo the moment the QA spawns the resource (scripts, tmux assets, browsers / agent-browser sessions, PIDs, ports) so none is forgotten. Embed a one-line cleanup receipt in the evidence string, e.g. `cleanup: killed 12345; tmux kill-session ulw-qa-foo; rm -rf /tmp/ulw.aB12cD; interrupt_agent w-3`. Missing receipt → record BLOCKED, not PASS.
168
+ 7. CLEAN (PAIRED, NEVER SKIP): tear down every runtime artifact step 5 spawned BEFORE recording — server PIDs (`kill`, verify `kill -0` fails), `tmux` sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`), browser / Playwright contexts (`.close()`), containers (`docker rm -f`), bound ports (`lsof -i :<port>` empty), temp sockets / files / dirs (`rm -rf` the `mktemp` paths), QA-only env vars, AND close every finished worker (v1 `close_agent`; on V2 finished workers end on their own — `interrupt_agent` any still running). Register each teardown as its own todo the moment the QA spawns the resource (scripts, tmux assets, browser contexts, PIDs, ports) so none is forgotten. Embed a one-line cleanup receipt in the evidence string, e.g. `cleanup: killed 12345; tmux kill-session ulw-qa-foo; rm -rf /tmp/ulw.aB12cD; interrupt_agent w-3`. Missing receipt → record BLOCKED, not PASS.
169
169
  8. RECORD one result immediately from the artifact you just wrote — never from memory or a later turn — stamping the capture tree `$(git rev-parse --short "HEAD^{tree}")` into the evidence:
170
170
  - PASS: `omo-agent-toolkit ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass --evidence "<observable> @tree:<short-tree> | <cleanup receipt>" --json`
171
171
  - FAIL: `omo-agent-toolkit ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status fail --evidence "<observable> @tree:<short-tree> | <cleanup receipt>" --notes "<diagnosis>" --json`
@@ -177,7 +177,7 @@ Scaling floor — more angles always justify more workers:
177
177
  | Multi-faceted | 4 | 6 | 2 | 2 | 14 |
178
178
  | Full due diligence | 4 | 6 | 3 | 2 | 15 |
179
179
 
180
- The browsing column is BINDING, not advisory: when the brief says `Browsing: yes`, the roster names a browsing-worker angle before the first wave launches, and that worker is spawned in the same turn as the rest of the wave. A run that reaches wave 2 with zero browsing workers on a `Browsing: yes` brief has silently downgraded every source to what plain fetch happened to return.
180
+ The browsing column is BINDING, not advisory: when the brief says `Browsing: yes`, the roster names a browsing-worker angle, armed with the `ultimate-browsing` skill, before the first wave launches, and that worker is spawned in the same turn as the rest of the wave. A run that reaches wave 2 with zero browsing workers on a `Browsing: yes` brief has silently downgraded every source to what plain fetch happened to return.
181
181
 
182
182
  **Disambiguate before you expand.** When the topic names something that could resolve several ways — a product, a person, a codename, a version — the first wave settles WHICH entity before any worker researches its history, benchmarks, or controversies: canonical name, first-party URL or account, whether it exists in the claimed category, and a confidence line. An unresolved entity never becomes a premise in a later wave's spawn message; that is exactly how a run starts inventing facts about something that does not exist.
183
183
 
@@ -185,7 +185,7 @@ Role protocols — embed the relevant one in each spawn message; every worker ge
185
185
 
186
186
  - **Codebase (explore), 2-4 workers.** Grep with 3+ keyword variations; structural/AST search; LSP definitions and references; file-name globs; `git log --all -S '<keyword>'` and `--grep` for history including deleted code. Cross-validate hits across tools. Report absolute file paths, patterns with `file:line`, and how findings connect.
187
187
  - **Web (librarian), 3-6 workers.** At least 10 distinct websearch queries per worker, each with a different operator or angle (see Search craft); fetch the full page for every result that matters — snippets lie. Context7 with 3+ queries per known library. grep.app and `gh search code|repos|issues` for real-world usage. Official docs via sitemap discovery (`<base>/sitemap.xml`), then targeted pages.
188
- - **Browsing, 1-3 workers on a `Browsing: yes` brief (0 otherwise).** This worker RENDERS pages, it does not re-fetch them: it drives a real browser through whatever the harness provides — the Browser plugin, an agent-browser or playwright skill, or a code-cell browser — and loads the `ultimate-browsing` skill to escalate through its tiers (insane-search engine with its Phase-2.5 archive surrogates, platform-native readers, then Chrome stealth) only when that browser is blocked. Its standing deliverable is a full-page screenshot of every top source plus the rendered text plain fetch could not reach; a worker that returns only fetched text has not done its job. JS-rendered, login-gated, WAF-blocked, and screenshot-bearing sources all belong here rather than in the web lane. **Provenance is part of the claim**: when a source came back with `provenance` of `snapshot` (an archive copy), cite it with its `snapshot_timestamp` and never state it as the current live page; content from a `proxy` route is `untrusted` and needs a second independent route before any claim rests on it. When one blocked territory hides many leads, fan out more browsing subagents in parallel for breadth instead of serializing one worker through them.
188
+ - **Browsing, 1-3 workers on a `Browsing: yes` brief (0 otherwise), every one loaded with the `ultimate-browsing` skill.** The skill owns the routing — the harness's own browser first, then its extraction engine with archive surrogates, platform-native readers, and Chrome stealth as each source demands; the worker owns the deliverable. This worker RENDERS pages, it does not re-fetch them: its standing deliverable is a full-page screenshot of every top source plus the rendered text plain fetch could not reach; a worker that returns only fetched text has not done its job. JS-rendered, login-gated, WAF-blocked, and screenshot-bearing sources all belong here rather than in the web lane. **Provenance is part of the claim**: when a source came back with `provenance` of `snapshot` (an archive copy), cite it with its `snapshot_timestamp` and never state it as the current live page; content from a `proxy` route is `untrusted` and needs a second independent route before any claim rests on it. When one blocked territory hides many leads, fan out more browsing subagents in parallel for breadth instead of serializing one worker through them.
189
189
  - **Repo deep-dive (librarian), 0-2 workers.** Shallow-clone the most relevant repos to `${TMPDIR:-/tmp}`, pin the HEAD SHA, read core modules, follow call chains, return SHA-pinned permalinks.
190
190
 
191
191
  Example spawn (codebase axis; librarian, browsing, and repo-dive follow the same contract with their own protocol):
@@ -384,7 +384,7 @@ High-yield combinations: official docs (`site:<docs domain>`), GitHub implementa
384
384
  | Obeying a surrounding "stop exploring" rule mid-research | Authority section — those rules do not bind this mode |
385
385
  | Asking a worker to write journal or session files | Workers are read-only; you journal every return |
386
386
  | Two workers given the same angle | One unique angle per worker, always |
387
- | A `Browsing: yes` run whose roster carries no browsing worker | The browsing column is binding — name the angle in the brief and spawn it with the first wave, before any lead is chased |
387
+ | A `Browsing: yes` run whose roster carries no browsing worker, or a browsing worker spawned without `ultimate-browsing` | The browsing column is binding — name the angle in the brief and spawn it, armed with the skill, in the first wave before any lead is chased |
388
388
  | Contested claim settled by judgment | Phase 3 — run code, capture output, verdict |
389
389
  | Deliverable claims without citations | Every claim cites a source or a verification artifact |
390
390
  | Guessing the deliverable format instead of asking | The format gate is unconditional: propose PDF+DOCX plus the domain-fitting alternatives and the template, then wait before wave 1 |
@@ -11,7 +11,7 @@ The visual-QA skill's executable core: a zero-dependency Node CLI that produces
11
11
  ```
12
12
  visual-qa/
13
13
  ├── SKILL.md # reviewer workflow (dual oracle, evidence gates) — the prose contract
14
- ├── references/agent-browser-setup.md
14
+ ├── references/browser-setup.md
15
15
  └── scripts/
16
16
  ├── visual-qa.mjs # SHIPPED RUNTIME: bun-build bundle of cli.ts (+ embedded modules)
17
17
  ├── cli.ts # development source; dispatches image-diff / tui-check
@@ -73,7 +73,7 @@ Before any reviewer sees an image, verify each capture yourself: the file signat
73
73
  ### Web
74
74
 
75
75
  1. Capture a REFERENCE image: the user's mock/target, generated page snapshot, Figma export, source-site capture, or known-good baseline. Save as PNG. If the user provided overview text or annotations, save them next to the image and treat them as part of the reference packet.
76
- 2. Capture the ACTUAL rendered screenshot at the same viewport size, driving the browser your harness actually has. Where a code cell can reach a browser (`new Bun.WebView()` on a Bun >= 1.4 kernel, otherwise `playwright-core` against the local Chrome), capture in-process: it needs no CLI and returns the PNG path directly. In Codex, `browser:control-in-app-browser` is that in-process surface — use it first unless the page needs an authenticated user browser session. Otherwise use the project's configured browser tooling (the playwright, agent-browser, or dev-browser skill). Save as PNG. If nothing is available, install [agent-browser](https://github.com/vercel-labs/agent-browser) (`bun add -g agent-browser && agent-browser install`) and capture with it — see `$SKILL_DIR/references/agent-browser-setup.md` for the full setup, including how to shoot a fixed-viewport screenshot.
76
+ 2. Capture the ACTUAL rendered screenshot at the reference viewport. Use two browser tiers from js eval: (1) `new Bun.WebView()` on Bun >= 1.4 (macOS default; Linux/Windows need installed Chrome/Chromium/Edge); (2) otherwise, or for Chrome semantics, stealth, trace, or authenticated profiles, WRITE a `playwright-core` script and run it from the kernel against local Chrome (`chromium.launch({ channel: "chrome" })` / `launchPersistentContext` on a CLONED profile, never the live one). In Codex, prefer `browser:control-in-app-browser` for ordinary captures. Save PNG and return its path; close the browser context. See `$SKILL_DIR/references/browser-setup.md` for fixed-viewport examples and prerequisites.
77
77
  3. Run the diff and keep the JSON:
78
78
 
79
79
  ```
@@ -0,0 +1,75 @@
1
+ # Browser setup (Web capture)
2
+
3
+ Use the js-eval kernel for both tiers. In Codex, prefer
4
+ `browser:control-in-app-browser` for ordinary captures.
5
+
6
+ ## Tier 1: Bun.WebView
7
+
8
+ On a Bun >= 1.4 kernel, `new Bun.WebView()` is the macOS default (system
9
+ WebKit, no browser download). Linux/Windows require `backend: "chrome"`
10
+ and installed Chrome/Chromium/Edge. WebView is headless; WebKit has no CDP,
11
+ and `type()` emits no keyboard events. Use tier 2 when these differences matter.
12
+
13
+ ```js
14
+ // js-eval cell; url and pngPath belong to this QA run.
15
+ const view = new Bun.WebView({ width: 1280, height: 720 })
16
+ try {
17
+ await view.navigate(url)
18
+ await Bun.write(pngPath, await view.screenshot())
19
+ console.log(pngPath)
20
+ } finally {
21
+ view[Symbol.dispose]()
22
+ }
23
+ ```
24
+
25
+ ## Tier 2: playwright-core with local Chrome
26
+
27
+ For other kernels, real-Chrome semantics, stealth, traces, or authenticated
28
+ profiles, WRITE a script beside the project's installed `playwright-core`
29
+ dependency and execute it from js eval. The user installs `playwright-core`
30
+ once with `bun add playwright-core` if needed; Chrome must already exist.
31
+ No managed browser download is needed.
32
+
33
+ ```js
34
+ // capture.mjs
35
+ import { chromium } from "playwright-core"
36
+ const [url, pngPath] = process.argv.slice(2)
37
+ const browser = await chromium.launch({ channel: "chrome", headless: true })
38
+ try {
39
+ const page = await browser.newPage({ viewport: { width: 1280, height: 720 }, deviceScaleFactor: 1 })
40
+ await page.goto(url, { waitUntil: "load", timeout: 30000 })
41
+ await page.screenshot({ path: pngPath })
42
+ console.log(pngPath)
43
+ } finally {
44
+ await browser.close()
45
+ }
46
+ ```
47
+
48
+ Run from the js-eval kernel (also works on a Node kernel):
49
+
50
+ ```js
51
+ const { promisify } = await import("node:util")
52
+ const { execFile } = await import("node:child_process")
53
+ const result = await promisify(execFile)("node", [scriptPath, url, pngPath], { timeout: 45000 })
54
+ console.log(result.stdout)
55
+ ```
56
+
57
+ For auth, CLONE the user-data directory to a private task-owned directory
58
+ and use `chromium.launchPersistentContext(clonePath, { channel: "chrome" })`.
59
+ NEVER launch against or clear cookies/cache/site data from the live profile.
60
+ Close the context and remove only the clone after QA. For script-based stealth,
61
+ read the ultimate-browsing skill's `references/chrome-stealth.md`.
62
+
63
+ ## Capture a screenshot at a fixed viewport
64
+
65
+ Match CSS viewport AND PNG dimensions: WebKit follows native display scale
66
+ (a 1280x720 viewport can yield 2560x1440 pixels). Use matching reference
67
+ captures or Chrome's `deviceScaleFactor`, not resizing to force a pass.
68
+ Wait for the specific page state, not a sleep, then compare:
69
+
70
+ ```sh
71
+ node "$SKILL_DIR/scripts/visual-qa.mjs" image-diff reference.png actual.png
72
+ ```
73
+
74
+ Inspect `dimensionsMatch` and `diffRatio`, then inspect the image. Close every
75
+ WebView/browser context and the fixture server, even on a failed capture.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // omo-codex-install:6df5dbbbb7ca9b9dce86fae98a525a9caa7de96caed85a4b77d4e8b4ab4d1501:205e3b91b12b465ff20c412c1ae0f8bf179eb3523234e475875924abeb015bd4
2
+ // omo-codex-install:6df5dbbbb7ca9b9dce86fae98a525a9caa7de96caed85a4b77d4e8b4ab4d1501:fa7a1ec0739eeac0b321eff2ead5f2a5acfafb1bb1f380b740f34e9d64076f21
3
3
  var __esm = (fn, res, err) => () => {
4
4
  if (fn)
5
5
  try {
@@ -7706,7 +7706,7 @@ var package_default;
7706
7706
  var init_package = __esm(() => {
7707
7707
  package_default = {
7708
7708
  name: "@oh-my-opencode/omo-codex",
7709
- version: "5.0.0-beta.62",
7709
+ version: "5.0.0-beta.64",
7710
7710
  type: "module",
7711
7711
  private: true,
7712
7712
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -13004,8 +13004,8 @@ var OmoGitMasterSettingsShape = {
13004
13004
  };
13005
13005
  var OmoGitMasterSettingsLayerSchema = object(OmoGitMasterSettingsShape).partial().strict();
13006
13006
  var OmoGitMasterSettingsSchema = OmoGitMasterSettingsLayerSchema.extend({
13007
- commit_footer: union([boolean2(), string2()]).default(true),
13008
- include_co_authored_by: boolean2().default(true)
13007
+ commit_footer: union([boolean2(), string2()]).default(false),
13008
+ include_co_authored_by: boolean2().default(false)
13009
13009
  }).strict();
13010
13010
 
13011
13011
  // packages/omo-config-core/src/schema/harness.ts
@@ -13271,6 +13271,7 @@ var OmoTaskSettingsSchema = object({
13271
13271
  model_concurrency: record(string2(), number2().int().nonnegative()).optional(),
13272
13272
  max_depth: number2().int().nonnegative().default(1),
13273
13273
  residency_max_children: ResidencyMaxChildrenInputSchema.default(8),
13274
+ resident_idle_timeout_ms: number2().int().positive().max(Number.MAX_SAFE_INTEGER).default(900000),
13274
13275
  ttl_ms: number2().int().positive().default(86400000),
13275
13276
  state_dir: string2().optional(),
13276
13277
  reattach_on_reconcile: boolean2().optional(),
@@ -13315,6 +13316,7 @@ var OmoTaskSettingsLayerSchema = object({
13315
13316
  model_concurrency: record(string2(), number2().int().nonnegative()).optional(),
13316
13317
  max_depth: number2().int().nonnegative().optional(),
13317
13318
  residency_max_children: ResidencyMaxChildrenInputSchema.optional(),
13319
+ resident_idle_timeout_ms: number2().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),
13318
13320
  ttl_ms: number2().int().positive().optional(),
13319
13321
  state_dir: string2().optional(),
13320
13322
  reattach_on_reconcile: boolean2().optional(),
@@ -62,16 +62,17 @@ exercises the surface; capture the artifact.
62
62
  for color / layout / CJK evidence, which degrades truecolor.
63
63
  3. Browser use — in Codex, use `browser:control-in-app-browser`
64
64
  first when available and no authenticated/persistent user browser
65
- profile is required. Otherwise use Chrome to drive the REAL page;
66
- if Chrome is not available, download and use agent-browser
67
- (https://github.com/vercel-labs/agent-browser). Capture action
65
+ profile is required. Otherwise, or for Chrome semantics, stealth,
66
+ or trace, WRITE a `playwright-core` script and run it from js eval
67
+ against local Chrome (`chromium.launch({ channel: "chrome" })` /
68
+ `launchPersistentContext` on a CLONED profile). Capture action
68
69
  log + screenshot path. Never downgrade to a non-browser surface
69
70
  for a browser-facing criterion. NEVER clear cookies, cache, or
70
71
  site data (`Network.clearBrowserCookies`, `Storage.clearCookies`,
71
72
  `chrome.browsingData.remove`, "clear browsing data") on the user's
72
73
  real/main browser profile — it wipes their logged-in state. If you
73
74
  need that profile's login state, clone it first (`rsync -a
74
- <profile>/ <tmp-clone>/`) and launch Chrome / agent-browser against
75
+ <profile>/ <tmp-clone>/`) and launch Chrome against
75
76
  the clone as the user-data-dir; run any clearing there only.
76
77
  4. Computer use — when the surface is a desktop/GUI app rather than a
77
78
  page, drive it via OS-level automation (a computer-use agent,
@@ -11,6 +11,18 @@ This skill ships a Python wrapper at `scripts/ast_grep_helper.py` and platform i
11
11
 
12
12
  ---
13
13
 
14
+ ## OmO native: the ast-grep MCP tools (fastest path, no CLI needed)
15
+
16
+ OmO native also registers a bundled ast-grep MCP server. Its three tools are **deferred**: they are absent from the resident tool list and activate automatically the first time you call them by name — no `tool_search` round trip needed.
17
+
18
+ - `mcp__ast_grep_search({ pattern, language, paths })` — AST-shape search, the MCP equivalent of `sg run -p`. Prefer this over shelling out to `sg` for one-off lookups: no install, no PATH issues.
19
+ - `mcp__ast_grep_rewrite({ pattern, rewrite, language, paths, apply })` — preview matches (`apply: false`, the default) or apply the rewrite (`apply: true`). Same two-pass discipline as `sg run -r`: preview first, then apply.
20
+ - `mcp__ast_grep_scan({ paths })` — run project YAML rules (`sgconfig.yml`, `rules/`), the MCP equivalent of `sg scan`.
21
+
22
+ Same pattern language as the CLI: `$VAR` matches one AST node, `$$$VAR` matches zero or more, and the pattern is code, not regex. `paths` accepts a file or directory list; `language` is required for patterns that are ambiguous across languages.
23
+
24
+ ---
25
+
14
26
  ## When to use this skill
15
27
 
16
28
  Use it whenever the user's question is about **code structure**, not bytes: