lazycodex-ai 5.0.0-beta.85 → 5.0.0-beta.87

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 (176) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.js +68 -41
  3. package/dist/cli-node/index.js +68 -41
  4. package/package.json +1 -1
  5. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  6. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2 -0
  7. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  8. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  9. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  10. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  11. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  12. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  13. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  14. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  15. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  16. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  17. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  18. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus/gpt-6.md +1 -1
  19. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  20. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  21. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  22. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  23. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  24. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  25. package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
  26. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -2
  27. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +63 -89
  28. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  31. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +2 -2
  32. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  33. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  34. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +63 -89
  35. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  36. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +2 -3
  38. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -2
  39. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  40. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  41. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  42. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  43. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  44. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  45. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  46. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  47. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  48. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  49. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  50. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  51. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  52. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  53. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  54. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  55. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  56. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  57. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  58. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  59. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  60. package/packages/omo-codex/plugin/package-lock.json +12 -12
  61. package/packages/omo-codex/plugin/package.json +1 -1
  62. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +8 -2
  63. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -2
  64. package/packages/omo-codex/plugin/skills/browser/ATTRIBUTION.md +26 -14
  65. package/packages/omo-codex/plugin/skills/browser/SKILL.md +65 -52
  66. package/packages/omo-codex/plugin/skills/browser/references/commands.md +81 -66
  67. package/packages/omo-codex/plugin/skills/browser/references/install.md +31 -34
  68. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/README.md +41 -21
  69. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  70. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/ladder.md +24 -22
  71. package/packages/omo-codex/plugin/skills/browser/references/owned-engine/network.md +35 -15
  72. package/packages/omo-codex/plugin/skills/browser/references/recipes/1password.md +13 -11
  73. package/packages/omo-codex/plugin/skills/browser/references/remote.md +5 -4
  74. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/index.js +1534 -0
  75. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +9 -0
  76. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  77. package/packages/omo-codex/plugin/skills/browser/scripts/browser-doctor.mjs +37 -32
  78. package/packages/omo-codex/plugin/skills/browser/scripts/browser-install.mjs +31 -44
  79. package/packages/omo-codex/plugin/skills/browser/scripts/omowright.mjs +25 -0
  80. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -2
  81. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +3 -3
  82. package/packages/omo-codex/plugin/skills/debugging/references/methodology/08-qa.md +1 -1
  83. package/packages/omo-codex/plugin/skills/debugging/references/tools/browser-qa.md +104 -0
  84. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +1 -1
  85. package/packages/omo-codex/plugin/skills/frontend/references/design/clone-from-url.md +1 -1
  86. package/packages/omo-codex/plugin/skills/programming/SKILL.md +12 -18
  87. package/packages/omo-codex/plugin/skills/programming/references/rust/README.md +43 -15
  88. package/packages/omo-codex/plugin/skills/programming/references/rust/api-design.md +81 -0
  89. package/packages/omo-codex/plugin/skills/programming/references/rust/async-tokio.md +60 -28
  90. package/packages/omo-codex/plugin/skills/programming/references/rust/axum-stack.md +1 -13
  91. package/packages/omo-codex/plugin/skills/programming/references/rust/cargo-strict.md +44 -8
  92. package/packages/omo-codex/plugin/skills/programming/references/rust/clap-stack.md +8 -3
  93. package/packages/omo-codex/plugin/skills/programming/references/rust/concurrency.md +66 -52
  94. package/packages/omo-codex/plugin/skills/programming/references/rust/libraries.md +35 -25
  95. package/packages/omo-codex/plugin/skills/programming/references/rust/macros.md +63 -0
  96. package/packages/omo-codex/plugin/skills/programming/references/rust/one-liners.md +5 -3
  97. package/packages/omo-codex/plugin/skills/programming/references/rust/proptest-insta.md +8 -0
  98. package/packages/omo-codex/plugin/skills/programming/references/rust/type-state.md +50 -12
  99. package/packages/omo-codex/plugin/skills/programming/references/rust/unsafe-discipline.md +34 -6
  100. package/packages/omo-codex/plugin/skills/programming/references/rust/zero-cost-safety.md +62 -52
  101. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  102. package/packages/omo-codex/plugin/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  103. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  104. package/packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py +31 -28
  105. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +1 -1
  106. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +27 -20
  107. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  108. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  109. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  110. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  111. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +63 -89
  112. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +4 -4
  113. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +2 -3
  114. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -2
  115. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +1 -1
  116. package/packages/omo-codex/plugin/skills/visual-qa/references/browser-setup.md +46 -46
  117. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -2
  118. package/packages/omo-codex/scripts/install-dist/install-local.mjs +4 -2
  119. package/packages/prompts-core/prompts/ultrawork/codex.md +63 -89
  120. package/packages/shared-skills/skills/browser/ATTRIBUTION.md +26 -14
  121. package/packages/shared-skills/skills/browser/SKILL.md +65 -52
  122. package/packages/shared-skills/skills/browser/references/commands.md +81 -66
  123. package/packages/shared-skills/skills/browser/references/install.md +31 -34
  124. package/packages/shared-skills/skills/browser/references/owned-engine/README.md +41 -21
  125. package/packages/shared-skills/skills/browser/references/owned-engine/frames-and-humans.md +33 -20
  126. package/packages/shared-skills/skills/browser/references/owned-engine/ladder.md +24 -22
  127. package/packages/shared-skills/skills/browser/references/owned-engine/network.md +35 -15
  128. package/packages/shared-skills/skills/browser/references/recipes/1password.md +13 -11
  129. package/packages/shared-skills/skills/browser/references/remote.md +5 -4
  130. package/packages/shared-skills/skills/browser/runtime/omowright/index.js +1534 -0
  131. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +9 -0
  132. package/packages/shared-skills/skills/browser/runtime/omowright/page-bundle.js +1395 -0
  133. package/packages/shared-skills/skills/browser/scripts/browser-doctor.mjs +37 -32
  134. package/packages/shared-skills/skills/browser/scripts/browser-install.mjs +31 -44
  135. package/packages/shared-skills/skills/browser/scripts/omowright.mjs +25 -0
  136. package/packages/shared-skills/skills/debugging/SKILL.md +2 -2
  137. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +3 -3
  138. package/packages/shared-skills/skills/debugging/references/methodology/08-qa.md +1 -1
  139. package/packages/shared-skills/skills/debugging/references/tools/browser-qa.md +104 -0
  140. package/packages/shared-skills/skills/frontend/SKILL.md +1 -1
  141. package/packages/shared-skills/skills/frontend/references/design/clone-from-url.md +1 -1
  142. package/packages/shared-skills/skills/programming/SKILL.md +12 -18
  143. package/packages/shared-skills/skills/programming/references/rust/README.md +43 -15
  144. package/packages/shared-skills/skills/programming/references/rust/api-design.md +81 -0
  145. package/packages/shared-skills/skills/programming/references/rust/async-tokio.md +60 -28
  146. package/packages/shared-skills/skills/programming/references/rust/axum-stack.md +1 -13
  147. package/packages/shared-skills/skills/programming/references/rust/cargo-strict.md +44 -8
  148. package/packages/shared-skills/skills/programming/references/rust/clap-stack.md +8 -3
  149. package/packages/shared-skills/skills/programming/references/rust/concurrency.md +66 -52
  150. package/packages/shared-skills/skills/programming/references/rust/libraries.md +35 -25
  151. package/packages/shared-skills/skills/programming/references/rust/macros.md +63 -0
  152. package/packages/shared-skills/skills/programming/references/rust/one-liners.md +5 -3
  153. package/packages/shared-skills/skills/programming/references/rust/proptest-insta.md +8 -0
  154. package/packages/shared-skills/skills/programming/references/rust/type-state.md +50 -12
  155. package/packages/shared-skills/skills/programming/references/rust/unsafe-discipline.md +34 -6
  156. package/packages/shared-skills/skills/programming/references/rust/zero-cost-safety.md +62 -52
  157. package/packages/shared-skills/skills/programming/references/rust-ub/miri-sanitizers-loom.md +1 -1
  158. package/packages/shared-skills/skills/programming/references/rust-ub/ub-taxonomy.md +6 -3
  159. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.sh +86 -75
  160. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.test.ts +83 -0
  161. package/packages/shared-skills/skills/programming/scripts/rust/new-project.py +31 -28
  162. package/packages/shared-skills/skills/review-work/SKILL.md +1 -1
  163. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +27 -20
  164. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +1 -1
  165. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +32 -100
  166. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +5 -11
  167. package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/playwright.md +20 -37
  168. package/packages/shared-skills/skills/ulw-execute/SKILL.md +4 -4
  169. package/packages/shared-skills/skills/visual-qa/SKILL.md +1 -1
  170. package/packages/shared-skills/skills/visual-qa/references/browser-setup.md +46 -46
  171. package/packages/omo-codex/plugin/skills/browser/scripts/browser-env.mjs +0 -41
  172. package/packages/omo-codex/plugin/skills/debugging/references/tools/playwright-cli.md +0 -112
  173. package/packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
  174. package/packages/shared-skills/skills/browser/scripts/browser-env.mjs +0 -41
  175. package/packages/shared-skills/skills/debugging/references/tools/playwright-cli.md +0 -112
  176. package/packages/shared-skills/skills/programming/scripts/rust/check-no-excuse-rules.py +0 -296
@@ -15,8 +15,9 @@
15
15
  # uv run new-project.py myproject --path ./workspace
16
16
  # ──────────────────
17
17
  #
18
- # Creates a new Rust project with strict lints, deny.toml, rustfmt.toml,
19
- # rust-toolchain.toml, and .cargo/config.toml pre-configured.
18
+ # Creates a new Rust project with strict lints, deny.toml, rustfmt.toml, and
19
+ # rust-toolchain.toml pre-configured. The generated project passes its own
20
+ # fmt + clippy gate before any code is written.
20
21
 
21
22
  from __future__ import annotations
22
23
 
@@ -50,6 +51,7 @@ non_ascii_idents = "deny"
50
51
  trivial_numeric_casts = "warn"
51
52
  unused_lifetimes = "warn"
52
53
  single_use_lifetimes = "warn"
54
+ unexpected_cfgs = { level = "deny", check-cfg = ["cfg(loom)"] }
53
55
 
54
56
  [lints.clippy]
55
57
  all = { level = "deny", priority = -1 }
@@ -66,32 +68,22 @@ unimplemented = "deny"
66
68
  dbg_macro = "deny"
67
69
  print_stdout = "warn"
68
70
  print_stderr = "warn"
71
+ allow_attributes = "deny"
72
+ allow_attributes_without_reason = "deny"
73
+ let_underscore_must_use = "deny"
74
+ indexing_slicing = "deny"
75
+ mem_forget = "deny"
76
+ clone_on_ref_ptr = "warn"
69
77
  module_name_repetitions = { level = "allow" }
70
78
  must_use_candidate = { level = "allow" }
71
- missing_errors_doc = { level = "allow" }
72
- missing_panics_doc = { level = "allow" }
73
- """
74
-
75
- CARGO_CONFIG_TOML = """\
76
- [build]
77
- rustflags = ["-C", "link-arg=-fuse-ld=lld"]
78
-
79
- [target.x86_64-unknown-linux-gnu]
80
- linker = "clang"
81
- rustflags = ["-C", "link-arg=-fuse-ld=lld"]
82
-
83
- [target.aarch64-apple-darwin]
84
- rustflags = []
85
79
  """
86
80
 
87
81
  DENY_TOML = """\
88
82
  [advisories]
89
- vulnerability = "deny"
90
- unmaintained = "warn"
91
83
  yanked = "deny"
92
84
 
93
85
  [licenses]
94
- unlicensed = "deny"
86
+ private = { ignore = true } # publish = false crates carry no license field
95
87
  allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "Unicode-3.0", "Zlib"]
96
88
 
97
89
  [bans]
@@ -103,6 +95,16 @@ unknown-registry = "deny"
103
95
  unknown-git = "deny"
104
96
  """
105
97
 
98
+ MAIN_RS = """\
99
+ //! Command-line entry point.
100
+
101
+ use std::io::Write as _;
102
+
103
+ fn main() -> std::io::Result<()> {
104
+ writeln!(std::io::stdout().lock(), "Hello, world!")
105
+ }
106
+ """
107
+
106
108
  RUSTFMT_TOML = """\
107
109
  edition = "2024"
108
110
  max_width = 100
@@ -148,18 +150,19 @@ def main(
148
150
  (project_dir / "rust-toolchain.toml").write_text(RUST_TOOLCHAIN_TOML)
149
151
  console.print(" [dim]wrote[/] rust-toolchain.toml")
150
152
 
151
- # ── Append [lints] to Cargo.toml ─────────────────────────────────
153
+ # ── Declare the MSRV and append [lints] to Cargo.toml ────────────
152
154
  cargo_toml = project_dir / "Cargo.toml"
153
- with cargo_toml.open("a") as f:
154
- f.write(CARGO_TOML_LINTS)
155
+ manifest = cargo_toml.read_text()
156
+ if 'edition = "2024"\n' not in manifest:
157
+ console.print("[bold red]Error:[/] cargo did not create an edition 2024 package; install Rust >= 1.85")
158
+ sys.exit(1)
159
+ manifest = manifest.replace(
160
+ 'edition = "2024"\n', 'edition = "2024"\nrust-version = "1.85"\npublish = false\n', 1
161
+ )
162
+ cargo_toml.write_text(manifest + CARGO_TOML_LINTS)
163
+ (project_dir / "src" / "main.rs").write_text(MAIN_RS)
155
164
  console.print(" [dim]appended[/] [lints] to Cargo.toml")
156
165
 
157
- # ── .cargo/config.toml ───────────────────────────────────────────
158
- cargo_config_dir = project_dir / ".cargo"
159
- cargo_config_dir.mkdir(parents=True, exist_ok=True)
160
- (cargo_config_dir / "config.toml").write_text(CARGO_CONFIG_TOML)
161
- console.print(" [dim]wrote[/] .cargo/config.toml")
162
-
163
166
  # ── deny.toml ────────────────────────────────────────────────────
164
167
  (project_dir / "deny.toml").write_text(DENY_TOML)
165
168
  console.print(" [dim]wrote[/] deny.toml")
@@ -169,7 +169,7 @@ You are the QA lane. Do not delegate hands-on QA to a sub-agent: the orchestrato
169
169
  2. **Pick the channel that faithfully exercises the surface** and capture the artifact:
170
170
  - HTTP: `curl -i` (or an API request context) - status line, headers, body.
171
171
  - CLI / TUI: a real pty - drive the command and keep the transcript; for color or layout evidence render through a browser-based terminal, never a `tmux capture-pane` dump.
172
- - Web: 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`. Capture action log plus screenshot.
172
+ - Web: omowright from js eval (staged in the `browser` skill) — the owned engine (`connectPipe` on a task-owned profile, or `connectCloakProfile` for bot-scored targets) for unauthenticated pages, the attached engine (`connectBrowserSkill()` in the user's signed-in browser) when the page needs their login; never a clone of or a launch against the live profile. Capture action log plus screenshot.
173
173
  - Desktop / GUI: OS-level automation against the running app - action log plus screenshot.
174
174
  - Library / SDK: a script that imports and exercises the public API - transcript.
175
175
  - Data-shaped work (migrations, configs, generated files): the resulting artifact itself, diffed or dumped.
@@ -7,7 +7,7 @@ description: "Renders, drives, and screenshots web pages: JS-rendered sources, c
7
7
 
8
8
  Web access for everything a plain fetch cannot finish: a page that renders in JS, a click or a form, a screenshot, a login that must persist across pages, or a host that blocks generic fetchers (WAF / 403 / Cloudflare). Start at the cheapest tier that can do the job and climb only when it cannot:
9
9
 
10
- **Tier 1 — insane-search** (headless extraction + WAF bypass) -> **Tier 1.5 — agent-reach** (platform-native APIs, esp. Chinese platforms) -> **Tier 2 — a real browser**: 2a Bun.WebView, 2b a local-Chrome `playwright-core` script from js eval for Chrome semantics, stealth, trace, or auth.
10
+ **Tier 1 — insane-search** (headless extraction + WAF bypass) -> **Tier 1.5 — agent-reach** (platform-native APIs, esp. Chinese platforms) -> **Tier 2 — a real browser** through omowright from js eval: 2a the owned engine (a browser your code launches, CloakBrowser for stealth), 2b the attached engine (the user's own signed-in browser).
11
11
 
12
12
  ## PHASE 0 — ROUTE FIRST (MANDATORY)
13
13
 
@@ -23,11 +23,11 @@ User request
23
23
  +- podcast transcript / stock forum ----------------- TIER 1.5 agent-reach
24
24
  +- Twitter feed / LinkedIn profile / GitHub via CLI - TIER 1.5 agent-reach
25
25
  |
26
- +- Tier 1/1.5 returned empty or partial ------------- TIER 2 2a kernel browser -> 2b stealth
27
- +- click / fill form / scroll / interact ------------ TIER 2 2a kernel browser -> 2b stealth
28
- +- screenshot / render / play video ----------------- TIER 2 2a kernel browser -> 2b stealth
29
- +- login session across pages / inject cookies ------ TIER 2 2b Chrome stealth (profile + cookies)
30
- +- test web app / QA / dogfood ---------------------- TIER 2 2a kernel browser -> 2b stealth
26
+ +- Tier 1/1.5 returned empty or partial ------------- TIER 2 2a owned engine -> 2b attached engine
27
+ +- click / fill form / scroll / interact ------------ TIER 2 2a owned engine -> 2b attached engine
28
+ +- screenshot / render / play video ----------------- TIER 2 2a owned engine -> 2b attached engine
29
+ +- login session across pages / the user's account --- TIER 2 2b attached engine (their browser)
30
+ +- test web app / QA / dogfood ---------------------- TIER 2 2a owned engine -> 2b attached engine
31
31
  |
32
32
  +- simple search query ------------------------------ NOT this skill (use web-search)
33
33
  ```
@@ -84,28 +84,35 @@ Routing table, per-platform auth (set `TWITTER_*` env vars, `gh auth login`, a t
84
84
 
85
85
  **When**: real interaction is needed (clicks, forms, screenshots, video, persistent login), or Tier 1/1.5 failed.
86
86
 
87
- ### Tier 2a — kernel browser (default)
87
+ Both tiers are omowright, staged inside the `browser` skill and loaded from js eval:
88
88
 
89
- Use `new Bun.WebView()` from the js-eval kernel on Bun >= 1.4: macOS defaults to system WebKit; Linux/Windows need installed Chrome/Chromium/Edge. WebView is headless, WebKit has no CDP, and `type()` emits no keyboard events. For other kernels or when those differences matter, use 2b.
89
+ ```js
90
+ const { loadOmowright } = await import("<browser-skill-root>/scripts/omowright.mjs")
91
+ const { omowright } = await loadOmowright()
92
+ ```
93
+
94
+ ### Tier 2a — owned engine (default)
95
+
96
+ A browser your code launches with a task-owned profile. `connectPipe` opens no listening port; `connectCloakProfile` launches CloakBrowser with a pinned fingerprint seed and is the path for WAF, Cloudflare and bot-scored pages.
90
97
 
91
98
  ```js
92
- const view = new Bun.WebView({ width: 1280, height: 800 })
99
+ const browser = await omowright.connectPipe({ browserPath, browserArgs: ["--headless", `--user-data-dir=${profile}`], storageRoot: profile })
93
100
  try {
94
- await view.navigate(url)
95
- const title = await view.evaluate("document.title")
96
- await Bun.write(pngPath, await view.screenshot())
101
+ const page = await browser.newTab(url)
102
+ const tree = omowright.compactSnapshot(await page.snapshot()) // the read; refs come from it
103
+ const snoop = omowright.createNetworkSnoop(page) // read the API JSON instead of the DOM when there is one
104
+ await page.locator("e3").click()
105
+ await Bun.write(pngPath, await page.screenshot())
97
106
  } finally {
98
- view[Symbol.dispose]()
107
+ await browser.close() // then rm -rf the profile
99
108
  }
100
109
  ```
101
110
 
102
- Use 2b for real-Chrome semantics, stealth, trace, authenticated profiles, or a page the kernel browser cannot reach.
103
-
104
- ### Tier 2b — Chrome stealth (blocked or logged-in pages)
111
+ The rest of the surface (CUA coordinates, captcha solving, routes, traces, frames, human handoff) is in the `browser` skill's `references/owned-engine/`. A stealth binary is not proof of access: inspect the rendered result and report challenges that remain.
105
112
 
106
- WRITE a `playwright-core` script and run it from js eval against installed local Chrome: `chromium.launch({ channel: "chrome" })`, or `launchPersistentContext` on a task-owned profile. For authenticated state, CLONE the user's profile first (`rsync -a <profile>/ <tmp-clone>/`); NEVER launch against or clear cookies/cache/site data from the live profile. Codex: prefer `browser:control-in-app-browser` for ordinary page control.
113
+ ### Tier 2b — attached engine (logged-in pages)
107
114
 
108
- Keep the engine's Playwright templates for script-based extraction. Stealth is optional: the user installs `playwright-extra` + `puppeteer-extra-plugin-stealth` once in the engine directory and the script wraps the `playwright-core` browser type. Setup, persistent-context arguments, screenshots, and cleanup are in [references/chrome-stealth.md](references/chrome-stealth.md). A stealth flag is not proof of access: inspect the rendered result and report challenges that remain.
115
+ When the page needs the user's account, drive the browser they are already signed into instead of cloning their profile: `connectBrowserSkill()` → `session.navigate` → `bskSnapshot(session)` / `session.observe()` → `session.click` → `session.stop()`. NEVER launch against or clear cookies/cache/site data from the user's live profile, and never fall back to the owned engine for an authenticated criterion: if no extension is connected, run the `browser` skill's onboarding script and relay its one human step. The full loop is the `browser` skill.
109
116
 
110
117
  ### Cookie login (cross-platform)
111
118
 
@@ -119,7 +126,7 @@ python3 scripts/extract_cookies.py --browser chrome --domain youtube.com --outpu
119
126
  python3 scripts/extract_cookies.py --browser chrome --domain youtube.com --inject --cdp 9242
120
127
  ```
121
128
 
122
- Cookie export files are written with owner-only `0600` permissions. Do not place live auth cookies in shared temp directories or commit them to a repo. Cookie injection sends values to CDP over stdin rather than argv. Cookies apply on next navigation — reload after injecting. Google services use fingerprint-bound tokens that may not transfer across browser profiles. Full detail in [references/chrome-stealth.md](references/chrome-stealth.md).
129
+ Cookie export files are written with owner-only `0600` permissions. Do not place live auth cookies in shared temp directories or commit them to a repo. Cookie injection sends values to CDP over stdin rather than argv. Cookies apply on next navigation — reload after injecting. Google services use fingerprint-bound tokens that may not transfer across browser profiles. Limits in [references/chrome-stealth.md](references/chrome-stealth.md).
123
130
 
124
131
  ## Reference docs
125
132
 
@@ -127,7 +134,7 @@ Cookie export files are written with owner-only `0600` permissions. Do not place
127
134
  |------|-------------|
128
135
  | [references/insane-search/README.md](references/insane-search/README.md) | Tier-1 engine harness (R1-R7, Phase 0 API index, no-site-name rule) + its `*.md` deep-dives |
129
136
  | [references/agent-reach/README.md](references/agent-reach/README.md) | Tier-1.5 routing table, platform auth, per-category `*.md` |
130
- | [references/chrome-stealth.md](references/chrome-stealth.md) | Tier-2 playwright-core scripts, optional stealth setup, cloned profiles, cookie login |
137
+ | [references/chrome-stealth.md](references/chrome-stealth.md) | Tier-2 stealth through omowright + CloakBrowser, cookie login limits |
131
138
 
132
139
  ## Environment variables
133
140
 
@@ -65,7 +65,7 @@ is a regression, not an upgrade:
65
65
  - **De-personalization** — no personal absolute paths, no personal auth token literals,
66
66
  no personal browser choice; enforced by `depersonalization-gate.test.ts`.
67
67
  - **Skill-level layering** — the engine is Tier 1 under a router that also owns Tier 1.5
68
- (agent-reach) and Tier 2 (Bun.WebView / local-Chrome playwright-core scripts from js eval).
68
+ (agent-reach) and Tier 2 (omowright from js eval: owned and attached engines via the `browser` skill).
69
69
  Upstream has no such tiering.
70
70
 
71
71
  ### WANT — upstream improvements worth porting forward
@@ -1,113 +1,45 @@
1
- # Tier 2 — Chrome stealth through playwright-core scripts
1
+ # Tier 2 — stealth through omowright and CloakBrowser
2
2
 
3
- For real-Chrome semantics, stealth, traces, or authenticated sessions, WRITE a
4
- script and run it from the js-eval kernel. Use installed local Chrome, not a
5
- managed browser download. Ordinary macOS captures on a Bun >= 1.4 kernel use
6
- `new Bun.WebView()`; Linux/Windows WebView needs installed Chrome/Chromium/Edge.
7
- Codex's ordinary browser surface is `browser:control-in-app-browser`.
3
+ For real-Chrome semantics, stealth, traces, or authenticated sessions, drive omowright from the
4
+ js-eval kernel. The library is staged inside the `browser` skill; load it with
5
+ `loadOmowright()` from that skill's `scripts/omowright.mjs`.
8
6
 
9
- ## Install (one-time)
7
+ ## Stealth is the engine, not a plugin
10
8
 
11
- Only the user installs these script dependencies, once in the skill's engine
12
- directory. Stealth plugins run inside scripts, never inside WebView:
13
-
14
- ```sh
15
- cd "$SKILL_DIR/engine"
16
- test -f package.json || cp templates/package.json package.json
17
- bun add playwright-core@1.62.1 playwright-extra@4.3.6 puppeteer-extra-plugin-stealth@2.11.2
18
- ```
19
-
20
- Chrome must already be installed. The bundled `templates/playwright_real_chrome.js`
21
- and `templates/playwright_mobile_chrome.js` resolve these dependencies from their
22
- parent engine directory. Without optional plugins, templates report the fallback
23
- and use plain `playwright-core`; do not call that fallback stealth.
24
-
25
- ## Launch + drive
26
-
27
- Close the source browser before cloning its user-data directory for a consistent
28
- copy. Preserve its `Local State` alongside the selected profile. Use a private,
29
- task-owned clone, never the live user-data-dir. NEVER clear the live profile's
30
- cookies, cache, or site data. For unauthenticated QA, use a fresh task-owned profile.
31
-
32
- Write `capture.cjs` in the engine directory. `clonePath`, URL, and output path are
33
- arguments owned by this QA run; keep cookie values out of argv and logs:
9
+ Bot-scored pages (Cloudflare Turnstile, FingerprintJS, DataDome) are handled by launching
10
+ **CloakBrowser** — a Chromium build with source-level fingerprint patches — through
11
+ `connectCloakProfile({ profileDir })`. The profile pins a fingerprint seed on first use and
12
+ refuses to change identity silently, so the same site sees the same browser on every run.
34
13
 
35
14
  ```js
36
- const { chromium: core } = require('playwright-core');
37
- const { addExtra } = require('playwright-extra');
38
- const stealth = require('puppeteer-extra-plugin-stealth');
39
- const [clonePath, url, pngPath] = process.argv.slice(2);
40
- const chromium = addExtra(core);
41
- chromium.use(stealth());
42
-
43
- async function capture() {
44
- const context = await chromium.launchPersistentContext(clonePath, {
45
- channel: 'chrome',
46
- headless: true,
47
- args: ['--disable-blink-features=AutomationControlled'],
48
- ignoreDefaultArgs: ['--enable-automation'],
49
- viewport: { width: 1280, height: 720 },
50
- });
51
- try {
52
- const page = await context.newPage();
53
- await page.goto(url, { waitUntil: 'load', timeout: 30000 });
54
- await page.screenshot({ path: pngPath });
55
- console.log(JSON.stringify({ pngPath, webdriver: await page.evaluate(() => navigator.webdriver) }));
56
- } finally {
57
- await context.close();
58
- }
15
+ const browser = await omowright.connectCloakProfile({ profileDir })
16
+ try {
17
+ const page = await browser.newTab(url)
18
+ console.log(await page.evaluate("navigator.webdriver")) // must be false
19
+ await Bun.write(pngPath, await page.screenshot())
20
+ } finally {
21
+ await browser.close()
59
22
  }
60
- capture().catch((error) => { console.error(error); process.exitCode = 1; });
61
- ```
62
-
63
- Run the script from js eval with a bounded process lifetime:
64
-
65
- ```js
66
- const { promisify } = await import('node:util')
67
- const { execFile } = await import('node:child_process')
68
- const result = await promisify(execFile)('node', [scriptPath, clonePath, url, pngPath], { timeout: 45000 })
69
- console.log(result.stdout)
70
23
  ```
71
24
 
72
- For extraction, run a bundled template the same way, supplying its JSON input on
73
- stdin (`url`, `profileDir: clonePath`, `waitSelector`, `headless`). The template
74
- returns HTML on stdout. For traces, use `context.tracing.start()` before navigation
75
- and `context.tracing.stop({ path: tracePath })` before closing. Use `headless: false`
76
- only with an available display when headed behavior is the criterion.
77
-
78
- ## Verify stealth
79
-
80
- Inspect the page, screenshot, and requested content. `navigator.webdriver === false`
81
- checks one browser property, NOT a promise to pass a detector or challenge.
82
- Persistent challenge pages or missing content are failures, even if the script
83
- exits zero. Do not keep retrying or silently swap browser tooling.
84
-
85
- ## Cookie login (cross-platform)
86
-
87
- `scripts/extract_cookies.py` exports local-browser cookies with owner-only `0600`
88
- permissions. Keep exports private and never commit them. For a persistent context,
89
- load the exported cookies with `context.addCookies(...)`, then navigate/reload.
90
- Browser- or device-bound login tokens may not transfer to a clone.
91
-
92
- The helper's `--inject --cdp <port>` targets a task-owned local Chrome CDP endpoint,
93
- which a script can also use via `chromium.connectOverCDP(...)`. Expose CDP on
94
- loopback only, never against the live profile. Values travel on stdin, not argv.
25
+ Do not pass an init-script for `navigator.webdriver` and do not add stealth plugins: CloakBrowser
26
+ patches the engine itself. A launch that still meets a challenge is handled by the `browser`
27
+ skill's ladder (`references/owned-engine/ladder.md`: layers, coordinates, `createCaptcha`), and a
28
+ page that only a signed-in user can reach belongs to the attached engine, not to a cloned profile.
95
29
 
96
- ## Anti-patterns
30
+ ## Cookie login limits
97
31
 
98
- - Plain text extraction does not need a stealth browser: use the extraction lane.
99
- - Never launch against, clear, or delete the user's live profile.
100
- - Never claim stealth from successful startup alone; validate rendered content.
101
- - Never run plugins without explicit user-installed script dependencies.
32
+ `scripts/extract_cookies.py` still exports cookies from a local browser; inject them with
33
+ `injectCookies(page, cookies)` into an **owned** profile. It sanitizes the set (drops expired
34
+ entries, keeps host-prefixed cookies secure and root-scoped). Limits that do not change:
102
35
 
103
- ## Troubleshooting
36
+ - Accounts whose risk engines bind a session to a device (Google, password managers) invalidate a
37
+ session reused from a new fingerprint; use the attached engine for those.
38
+ - Cookies apply on the next navigation — reload after injecting.
39
+ - NEVER copy a session out of, or clear cookies/cache/site data in, the user's live profile.
104
40
 
105
- A missing Chrome executable is a prerequisite failure: report it, do not download
106
- a replacement. Missing plugins require the one-time setup above; module errors
107
- inside installed plugins are real failures, not optional-dependency misses.
108
- A locked profile usually means the source was not cloned or another run owns the
109
- clone. Use a new task-owned clone instead of killing unrelated browsers.
41
+ ## The extraction engine's own Playwright fallback
110
42
 
111
- Always close contexts in `finally`, stop the fixture server, and remove only this
112
- run's clone and temporary scripts. Preserve requested PNG/trace evidence and record
113
- the cleanup receipt, including failures.
43
+ The Tier-1 Python engine (`engine/`) keeps its own script-based Chrome fallback for headless
44
+ extraction; that is an engine internal, not an agent-facing browser path. Interactive work, QA and
45
+ screenshots go through omowright as above.
@@ -223,17 +223,11 @@ result = fetch(
223
223
  python3 -c "import curl_cffi, bs4, yaml" 2>/dev/null || pip install curl_cffi beautifulsoup4 pyyaml -q
224
224
  ```
225
225
 
226
- 브라우저를 직접 제어할 때는 js eval에서 Bun >= 1.4의 `new Bun.WebView()`를
227
- 사용한다(macOS 기본; Linux/Windows는 설치된 Chrome/Chromium/Edge 필요).
228
- 그 외 또는 Chrome 동작·stealth·trace·인증이 필요하면 `playwright-core` 스크립트를
229
- 작성해 js eval에서 로컬 Chrome(`channel: "chrome"`)으로 실행한다.
230
- 사용자가 엔진 디렉터리에서 한 번 설치할 스크립트 의존성:
231
- ```bash
232
- cd "$SKILL_DIR/engine"
233
- test -f package.json || cp templates/package.json package.json
234
- bun add playwright-core@1.62.1 playwright-extra@4.3.6 puppeteer-extra-plugin-stealth@2.11.2
235
- ```
236
- Chrome은 이미 설치되어 있어야 한다. 인증 프로필은 먼저 복제하고 복제본만 사용한다.
226
+ 브라우저를 직접 제어할 때는 js eval에서 omowright를 쓴다(`browser` 스킬에 스테이징됨):
227
+ 직접 띄우는 브라우저는 `connectPipe` / 스텔스는 `connectCloakProfile`(CloakBrowser),
228
+ 사용자가 로그인해 둔 브라우저는 `connectBrowserSkill`. 이 엔진의 Playwright 템플릿은
229
+ Tier 1 추출 폴백 전용이며 에이전트가 직접 브라우저를 다루는 경로가 아니다.
230
+ 인증이 필요한 페이지는 사용자 프로필을 복제하지 말고 attached 엔진으로 간다.
237
231
 
238
232
  ## 빠른 참조 — Phase 0 명령어
239
233
 
@@ -17,9 +17,9 @@
17
17
  ### 의존성
18
18
 
19
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를 새로 설치하지 않는다.
20
+ 에이전트가 직접 여는 브라우저 세션은 js eval의 omowright(`browser` 스킬에 스테이징)로
21
+ 띄운다: 직접 소유 브라우저는 `connectPipe`, 스텔스는 `connectCloakProfile`, 사용자 로그인이
22
+ 필요하면 `connectBrowserSkill`. MCP를 새로 설치하지 않는다.
23
23
 
24
24
  ### 기본 워크플로
25
25
 
@@ -52,15 +52,14 @@ Linux/Windows는 설치된 Chrome/Chromium/Edge 필요), 그 외 또는 Chrome
52
52
 
53
53
  ### 의존성 (최초 1회)
54
54
 
55
- ```bash
56
- # Node (시스템 설치)
57
- node -v # v18+ 권장
55
+ 엔진 템플릿의 스크립트 의존성은 `engine/templates/package.json`에 고정되어 있다.
56
+ 엔진 디렉터리에서 한 번만 설치한다. Chrome은 이미 시스템에 설치되어 있어야 하며,
57
+ 브라우저 다운로드 명령은 없다.
58
58
 
59
- # 사용자가 엔진 디렉터리에서 한 번 설치하는 스크립트 의존성
59
+ ```bash
60
60
  cd "$SKILL_DIR/engine"
61
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은 이미 시스템에 설치되어 있어야 한다. 브라우저 다운로드 명령은 없다.
62
+ bun install
64
63
  ```
65
64
 
66
65
  ### 호출 (engine 내부)
@@ -76,39 +75,23 @@ attempt, html = run_playwright_fallback(
76
75
  )
77
76
  ```
78
77
 
79
- 내부에서 `engine/templates/playwright_real_chrome.js` 또는 `playwright_mobile_chrome.js`를 Node로 실행하고 HTML을 받아온다. 템플릿은 **URL과 셀렉터 파라미터만** 받으며 사이트별 분기가 없다.
78
+ 내부에서 `engine/templates/playwright_real_chrome.js` 또는 `playwright_mobile_chrome.js`를 Node로 실행하고 HTML을 받아온다. 템플릿은 **URL과 셀렉터 파라미터만** 받으며 사이트별 분기가 없다. 템플릿은 엔진이 실행하는 프로그램이다. 에이전트가 이 템플릿을 본떠 브라우저 스크립트를 새로 쓰지 않는다.
80
79
 
81
80
  ### 데스크톱 템플릿 (`playwright_real_chrome.js`)
82
81
 
83
- ```js
84
- const { addExtra } = require('playwright-extra');
85
- const chromium = addExtra(require('playwright-core').chromium);
86
- const stealth = require('puppeteer-extra-plugin-stealth')();
87
- chromium.use(stealth);
88
-
89
- const ctx = await chromium.launchPersistentContext(profileDir, {
90
- channel: 'chrome', // ← 핵심: 번들 Chromium 아닌 실제 Chrome
91
- headless: false, // Akamai는 headless 탐지. headful 필요.
92
- viewport: { width: 1366, height: 900 },
93
- });
94
- ```
82
+ - 번들 Chromium이 아니라 **시스템에 설치된 실제 Chrome**을 띄운다. TLS 지문이 실제 Chrome이 되는 것이 핵심이다.
83
+ - stealth 플러그인을 적용하고, 작업 전용 영속 프로필 디렉터리를 쓴다.
84
+ - Akamai는 headless를 탐지하므로 **headful**로 실행하고, 뷰포트는 1366×900이다.
95
85
 
96
86
  ### 모바일 템플릿 (`playwright_mobile_chrome.js`)
97
87
 
98
- ```js
99
- const { devices } = require('playwright-core');
100
- const { addExtra } = require('playwright-extra');
101
- const chromium = addExtra(require('playwright-core').chromium);
102
- const iPhone = devices['iPhone 13 Pro'];
103
-
104
- const ctx = await chromium.launchPersistentContext(profileDir, {
105
- channel: 'chrome', // TLS는 실제 Chrome
106
- ...iPhone, // UA/viewport/isMobile/hasTouch 자동 주입
107
- headless: false,
108
- });
109
- ```
88
+ - TLS는 데스크톱과 같은 실제 Chrome이고, iPhone 13 Pro 디바이스 기술자(UA/viewport/isMobile/hasTouch)만 주입한다. headful로 실행한다.
89
+
90
+ **주의**: 실제 Chrome + 모바일 디바이스 기술자 조합은 TLS 핑거프린트를 Chrome으로 유지하면서 HTTP 레이어(UA/viewport)만 모바일로 바꾼다. WAF가 실제 Chrome으로 인식해서 관대한 경우가 많다.
91
+
92
+ ### 엔진 밖에서 같은 효과가 필요할 때
110
93
 
111
- **주의**: `channel:'chrome'` + `devices[...]` 조합은 TLS 핑거프린트를 Chrome으로 유지하면서 HTTP 레이어(UA/viewport)만 모바일로 바꾼다. WAF가 실제 Chrome으로 인식해서 관대한 경우가 많다.
94
+ 엔진 폴백이 아니라 에이전트가 직접 페이지를 조작해야 한다면 js eval에서 omowright(`browser` 스킬에 스테이징)를 쓴다. 지문이 고정된 스텔스 브라우저는 `connectCloakProfile({ profileDir })`, 모바일 뷰는 `emulate(page, "iphone-14")`, 사용자 로그인이 필요하면 `connectBrowserSkill()`이다.
112
95
 
113
96
  ## 선택 규칙 (자동)
114
97
 
@@ -129,8 +112,8 @@ const ctx = await chromium.launchPersistentContext(profileDir, {
129
112
 
130
113
  ## 디버깅 팁
131
114
 
132
- - 템플릿은 js eval에서 스크립트로 실행한다. `profileDir`는 작업 전용 경로나 사용자 프로필의 복제본만 사용한다.
133
- - 사용자의 실제 프로필을 실행·초기화·삭제하지 않는다. 작업 종료 시 컨텍스트를 닫고 작업 전용 복제본만 정리한다.
115
+ - 템플릿의 `profileDir`는 작업 전용 경로만 사용한다. 사용자의 실제 프로필을 실행·복제·초기화·삭제하지 않는다.
116
+ - 작업 종료 시 브라우저를 닫고 작업 전용 프로필만 정리한다.
134
117
  - 실패 시 `result.trace`의 `error` 필드에 Node stderr 200자가 포함됨
135
118
 
136
119
  ## 사이트 예시 (독자 이해용, 코드 분기 근거 아님)