chromeflow 0.1.55 → 0.1.57

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.
package/CLAUDE.md CHANGED
@@ -34,10 +34,8 @@ Do NOT ask "should I open the browser?" — just do it. The user expects seamles
34
34
  ## Guided flow pattern
35
35
 
36
36
  ```
37
- 1. show_guide_panel(title, steps[]) show the full plan upfront
38
- 2. open_page(url) — navigate to the right page (add new_tab=true to keep current tab open)
39
- mark_step_done(0) — ALWAYS mark step 0 done right after open_page succeeds
40
- 3. For each step:
37
+ 1. open_page(url) navigate to the right page (add new_tab=true to keep current tab open)
38
+ 2. For each step:
41
39
  a. Claude acts directly:
42
40
  click_element("Save") — press buttons/links Claude can press
43
41
  get_page_text() or wait_for_selector(".success") — ALWAYS confirm after click; click_element returns after 600ms regardless of outcome
@@ -62,8 +60,7 @@ Do NOT ask "should I open the browser?" — just do it. The user expects seamles
62
60
  find_and_highlight(text, msg) — show the user what to do
63
61
  wait_for_click() — wait for user interaction
64
62
  [after fill_input] clear_overlays() — always clear after filling
65
- e. mark_step_done(i) check off the step after it is complete
66
- 4. clear_overlays() — clean up when done
63
+ 3. clear_overlays() clean up when done
67
64
  ```
68
65
 
69
66
  **Default to automation.** Only pause for human input when the step genuinely requires
@@ -238,4 +235,30 @@ document.body.style.zoom = '1';
238
235
  1. Retry the exact same `execute_script` call
239
236
  2. If still failing, use `find_and_highlight` to show the user a download button to click manually
240
237
 
238
+ **Shadow DOM `[role=radio]` / custom radios silently no-op**: On sites like Outlier,
239
+ `element.click()` on a shadow-DOM radio often doesn't flip `aria-checked`. Two things
240
+ must be true: (a) the element must be scrolled into view FIRST (`scrollIntoView({block:'center'})`),
241
+ and (b) the full pointer-event chain must fire — not just `click()`:
242
+ ```js
243
+ ['pointerdown','mousedown','pointerup','mouseup','click'].forEach(t =>
244
+ el.dispatchEvent(new MouseEvent(t, {bubbles: true, cancelable: true}))
245
+ );
246
+ ```
247
+ After scroll, re-query the radio list — its length may change as more content becomes
248
+ visible. Then verify `aria-checked === "true"` before moving on.
249
+
250
+ **Visibility-detection overlays** (e.g. Multimango's "Content Hidden" black overlay):
251
+ Some sites render a full-screen overlay when the tab loses focus, triggered by
252
+ `document.visibilityState` / `document.hidden`. Chromeflow tab-switching triggers it.
253
+ Workaround — remove the overlay and patch the APIs:
254
+ ```js
255
+ document.querySelectorAll('[style*="z-index: 99999"]').forEach(el => el.remove());
256
+ Object.defineProperty(document, 'hidden', { get: () => false, configurable: true });
257
+ Object.defineProperty(document, 'visibilityState', { get: () => 'visible', configurable: true });
258
+ ['visibilitychange','blur'].forEach(t =>
259
+ document.addEventListener(t, e => e.stopImmediatePropagation(), true)
260
+ );
261
+ ```
262
+ Re-apply after every navigation.
263
+
241
264
  **Never use Bash to work around a stuck browser interaction.**
package/README.md CHANGED
@@ -17,7 +17,7 @@ Chromeflow works in **your actual Chrome browser**, where you're already logged
17
17
  | **Browser** | Your real Chrome (sessions intact) | Fresh instance, logged out of everything |
18
18
  | **Auth / 2FA** | Already handled — pauses when needed | Can't handle — blocks completely |
19
19
  | **Page understanding** | DOM queries (fast, cheap, reliable) | Screenshots + vision model (slow, expensive) |
20
- | **Human-in-the-loop** | Built-in guide panel, highlights, pauses | Fully autonomous, no interaction |
20
+ | **Human-in-the-loop** | Highlights, pauses on sensitive input | Fully autonomous, no interaction |
21
21
  | **Integration** | MCP server for Claude Code | Standalone, not Claude Code aware |
22
22
  | **Credential capture** | Reads API keys → writes to `.env` | Not designed for this |
23
23
 
@@ -90,7 +90,6 @@ Claude will navigate, highlight steps, click what it can, pause for anything sen
90
90
  | Screenshot + save + copy to clipboard | `take_and_copy_screenshot` |
91
91
  | Screenshot the terminal window | `capture_terminal` |
92
92
  | Save/restore form state across tabs | `save_page_state`, `restore_page_state` |
93
- | Show a step-by-step guide panel | `show_guide_panel`, `mark_step_done` |
94
93
 
95
94
  ### File uploads
96
95
 
package/dist/setup.js CHANGED
@@ -53,9 +53,8 @@ Do NOT ask "should I open the browser?" \u2014 just do it. The user expects seam
53
53
  ## Guided flow pattern
54
54
 
55
55
  \`\`\`
56
- 1. show_guide_panel(title, steps[]) \u2014 show the full plan upfront
57
- 2. open_page(url) \u2014 navigate to the right page
58
- 3. For each step:
56
+ 1. open_page(url) \u2014 navigate to the right page
57
+ 2. For each step:
59
58
  a. [if needed] take_screenshot() \u2014 only when you need to locate something
60
59
  b. Claude acts directly:
61
60
  click_element("Save") \u2014 press buttons/links Claude can press
@@ -64,8 +63,7 @@ Do NOT ask "should I open the browser?" \u2014 just do it. The user expects seam
64
63
  Or pause for the user:
65
64
  find_and_highlight(text, msg) \u2014 show the user what to do
66
65
  wait_for_click() \u2014 wait for user interaction
67
- c. mark_step_done(i) \u2014 check off the step
68
- 4. clear_overlays() \u2014 clean up when done
66
+ 3. clear_overlays() \u2014 clean up when done
69
67
  \`\`\`
70
68
 
71
69
  **Default to automation.** Only pause for human input when the step genuinely requires
@@ -153,10 +151,8 @@ const CHROMEFLOW_TOOLS = [
153
151
  "click_element",
154
152
  "wait_for_click",
155
153
  "wait_for_selector",
156
- "mark_step_done",
157
154
  "find_and_highlight",
158
155
  "highlight_region",
159
- "show_guide_panel",
160
156
  // v0.1.23+
161
157
  "switch_to_tab",
162
158
  "list_tabs",
@@ -177,7 +173,9 @@ const CHROMEFLOW_TOOLS = [
177
173
  // v0.1.42+
178
174
  "set_dialog_response",
179
175
  // v0.1.46+
180
- "type_text"
176
+ "type_text",
177
+ // v0.1.57+
178
+ "inspect_request_headers"
181
179
  ].map((t) => `mcp__chromeflow__${t}`);
182
180
  function patchSettingsLocalJson(cwd) {
183
181
  const claudeDir = join(cwd, ".claude");
@@ -190,7 +190,7 @@ For prompt: the value string is returned to the page. For confirm: true/false is
190
190
  );
191
191
  server.tool(
192
192
  "clear_overlays",
193
- "Remove all highlights and callout annotations from the current page. Does NOT remove the guide panel \u2014 the guide panel persists until the next flow starts.",
193
+ "Remove all highlights and callout annotations from the current page.",
194
194
  {},
195
195
  async () => {
196
196
  await bridge.request({ type: "clear" });
@@ -321,6 +321,23 @@ PAGE ALERT: "${alert}" \u2014 the page showed a dialog with this message. Read i
321
321
  };
322
322
  }
323
323
  );
324
+ server.tool(
325
+ "inspect_request_headers",
326
+ `Navigate to a URL and capture the exact HTTP request headers Chrome sends for the main document request.
327
+ Use this to diagnose server-side bot detection \u2014 e.g. when a site returns a "mobile" or "switch devices" page despite the client reporting desktop.
328
+ Returns the request method, URL, and all headers including Sec-CH-UA-* client hints.
329
+ This tool DOES navigate the active tab to the URL.`,
330
+ {
331
+ url: z.string().url().describe("URL to navigate to and capture headers for")
332
+ },
333
+ async ({ url }) => {
334
+ const response = await bridge.request({ type: "inspect_request_headers", url }, 2e4);
335
+ const r = response;
336
+ return {
337
+ content: [{ type: "text", text: r.message ?? "(no headers captured)" }]
338
+ };
339
+ }
340
+ );
324
341
  }
325
342
  export {
326
343
  registerBrowserTools
@@ -138,19 +138,6 @@ ${lines.join("\n")}`
138
138
  };
139
139
  }
140
140
  );
141
- server.tool(
142
- "mark_step_done",
143
- "Mark a step in the guide panel as completed (shows a green check). Call this after any step finishes \u2014 whether Claude acted autonomously or the user completed a highlighted step via wait_for_click.",
144
- {
145
- stepIndex: z.number().int().describe("0-based index of the step to mark done")
146
- },
147
- async ({ stepIndex }) => {
148
- await bridge.request({ type: "mark_step_done", stepIndex });
149
- return {
150
- content: [{ type: "text", text: `Step ${stepIndex + 1} marked as done.` }]
151
- };
152
- }
153
- );
154
141
  }
155
142
  export {
156
143
  registerFlowTools
@@ -64,30 +64,6 @@ Only pass x/y/width/height when you have no selector and already have fresh coor
64
64
  };
65
65
  }
66
66
  );
67
- server.tool(
68
- "show_guide_panel",
69
- "Show a floating step-by-step guide panel on the page to help the user understand what they need to do",
70
- {
71
- title: z.string().describe("Title of the guide (e.g. 'Set up Stripe API keys')"),
72
- steps: z.array(
73
- z.object({
74
- text: z.string().describe("Step instruction text"),
75
- done: z.boolean().optional().describe("Whether this step is already completed")
76
- })
77
- ).describe("Ordered list of steps")
78
- },
79
- async ({ title, steps }) => {
80
- await bridge.request({ type: "show_panel", title, steps });
81
- return {
82
- content: [
83
- {
84
- type: "text",
85
- text: `Guide panel shown: "${title}" with ${steps.length} steps.`
86
- }
87
- ]
88
- };
89
- }
90
- );
91
67
  }
92
68
  export {
93
69
  registerHighlightTools
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chromeflow",
3
- "version": "0.1.55",
3
+ "version": "0.1.57",
4
4
  "description": "Browser guidance MCP server for Claude Code — highlights, clicks, fills, and captures from the web so you don't have to.",
5
5
  "type": "module",
6
6
  "bin": {