chromeflow 0.1.35 → 0.1.37
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 +3 -2
- package/README.md +37 -3
- package/dist/setup.js +3 -1
- package/dist/tools/browser.js +19 -0
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -43,6 +43,7 @@ Do NOT ask "should I open the browser?" — just do it. The user expects seamles
|
|
|
43
43
|
get_page_text() or wait_for_selector(".success") — ALWAYS confirm after click; click_element returns after 600ms regardless of outcome
|
|
44
44
|
fill_form([{label, value}, ...]) — fill multiple fields in one call; prefer over repeated fill_input
|
|
45
45
|
fill_input("Product name", "Pro") — fill a single field (works on React, CodeMirror, and contenteditable)
|
|
46
|
+
set_file_input("Upload", "/abs/path/to/file.zip") — upload a file to a file input (even hidden inputs)
|
|
46
47
|
clear_overlays() — call this immediately after fill_input/fill_form succeeds
|
|
47
48
|
scroll_to_element("label text") — jump directly to a known field; prefer this over scroll_page when the target is known
|
|
48
49
|
scroll_page("down") — reveal off-screen content when target location is unknown
|
|
@@ -102,8 +103,8 @@ use `take_and_copy_screenshot()` — it saves a PNG to ~/Downloads and copies it
|
|
|
102
103
|
`get_elements()` when you need pixel coordinates of visible elements; use `get_form_fields()`
|
|
103
104
|
when you need to understand the full structure of a form including fields below the fold.
|
|
104
105
|
- `get_form_fields()` includes `[type=file]` fields even when they are visually hidden behind
|
|
105
|
-
custom drag-and-drop zones.
|
|
106
|
-
the
|
|
106
|
+
custom drag-and-drop zones. Use `set_file_input(hint, filePath)` to upload a file — provide
|
|
107
|
+
the label/hint text and the absolute path to the file on disk.
|
|
107
108
|
- For forms with multiple fields, use `fill_form([{label, value}, ...])` to fill them all
|
|
108
109
|
in a single call. It returns a per-field success/failure report so you can immediately see
|
|
109
110
|
which fields weren't found. Use `fill_input` only for a single field.
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Chromeflow
|
|
2
2
|
|
|
3
|
-
Browser guidance for Claude Code. When Claude needs you to set up Stripe, grab API keys, configure a third-party service, or do anything in a browser — Chromeflow takes over. It highlights what to click, fills in fields it knows, clicks buttons automatically, and writes captured values straight to your `.env`.
|
|
3
|
+
Browser guidance for Claude Code. When Claude needs you to set up Stripe, grab API keys, configure a third-party service, or do anything in a browser — Chromeflow takes over. It highlights what to click, fills in fields it knows, clicks buttons automatically, uploads files, and writes captured values straight to your `.env`.
|
|
4
4
|
|
|
5
5
|
## How it works
|
|
6
6
|
|
|
7
7
|
Chromeflow is two things that work together:
|
|
8
8
|
|
|
9
|
-
- **MCP server** — gives Claude Code a set of browser tools (`open_page`, `click_element`, `
|
|
10
|
-
- **Chrome extension** — receives those commands and acts on the active tab (highlights, clicks, fills, captures screenshots)
|
|
9
|
+
- **MCP server** — gives Claude Code a set of browser tools (`open_page`, `click_element`, `fill_form`, `set_file_input`, `read_element`, `write_to_env`, etc.)
|
|
10
|
+
- **Chrome extension** — receives those commands and acts on the active tab (highlights, clicks, fills, uploads files, captures screenshots)
|
|
11
11
|
|
|
12
12
|
Claude drives the flow. You only touch the browser for things that genuinely need you — login, passwords, payment details, personal choices.
|
|
13
13
|
|
|
@@ -49,6 +49,40 @@ Just ask Claude normally:
|
|
|
49
49
|
|
|
50
50
|
Claude will navigate, highlight steps, click what it can, pause for anything sensitive, and write values to your `.env` automatically.
|
|
51
51
|
|
|
52
|
+
## What Claude can do
|
|
53
|
+
|
|
54
|
+
| Capability | Tools |
|
|
55
|
+
|------------|-------|
|
|
56
|
+
| Navigate pages, open new tabs | `open_page`, `list_tabs`, `switch_to_tab` |
|
|
57
|
+
| Click buttons and links | `click_element` |
|
|
58
|
+
| Fill single fields | `fill_input` |
|
|
59
|
+
| Fill multiple fields in one call | `fill_form` |
|
|
60
|
+
| Upload files (even hidden inputs) | `set_file_input` |
|
|
61
|
+
| Read page content as text | `get_page_text` |
|
|
62
|
+
| Inspect all form fields | `get_form_fields` |
|
|
63
|
+
| Scroll to a known element | `scroll_to_element` |
|
|
64
|
+
| Highlight elements for the user | `highlight_region`, `find_and_highlight` |
|
|
65
|
+
| Wait for the user to click | `wait_for_click` |
|
|
66
|
+
| Wait for async changes | `wait_for_selector` |
|
|
67
|
+
| Run arbitrary JS | `execute_script` |
|
|
68
|
+
| Capture credentials to `.env` | `read_element`, `write_to_env` |
|
|
69
|
+
| Screenshot (element location only) | `take_screenshot` |
|
|
70
|
+
| Screenshot + save + copy to clipboard | `take_and_copy_screenshot` |
|
|
71
|
+
| Save/restore form state across tabs | `save_page_state`, `restore_page_state` |
|
|
72
|
+
| Show a step-by-step guide panel | `show_guide_panel`, `mark_step_done` |
|
|
73
|
+
|
|
74
|
+
### File uploads
|
|
75
|
+
|
|
76
|
+
`set_file_input` uses Chrome DevTools Protocol to bypass the browser's file-input script restriction — the same mechanism used by Playwright and Puppeteer. It works even when the `<input type=file>` is hidden behind a custom drag-and-drop zone.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
set_file_input("Upload", "/Users/you/Downloads/task.zip")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Dedicated Claude window
|
|
83
|
+
|
|
84
|
+
Click the Chromeflow extension icon and use **"Use this window for Claude"** to lock Claude's browser operations to a specific Chrome window. This lets you freely use other Chrome windows without Claude interfering.
|
|
85
|
+
|
|
52
86
|
## Adding to another project
|
|
53
87
|
|
|
54
88
|
Run setup from the new project's directory — the MCP server is already registered globally, this just drops `CLAUDE.md` and tool permissions into the project:
|
package/dist/setup.js
CHANGED
|
@@ -167,7 +167,9 @@ const CHROMEFLOW_TOOLS = [
|
|
|
167
167
|
// v0.1.25+
|
|
168
168
|
"take_and_copy_screenshot",
|
|
169
169
|
// v0.1.32+
|
|
170
|
-
"fill_form"
|
|
170
|
+
"fill_form",
|
|
171
|
+
// v0.1.36+
|
|
172
|
+
"set_file_input"
|
|
171
173
|
].map((t) => `mcp__chromeflow__${t}`);
|
|
172
174
|
function patchSettingsLocalJson(cwd) {
|
|
173
175
|
const claudeDir = join(cwd, ".claude");
|
package/dist/tools/browser.js
CHANGED
|
@@ -169,6 +169,25 @@ ${lines.join("\n")}${r.warning ?? ""}` }]
|
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
);
|
|
172
|
+
server.tool(
|
|
173
|
+
"set_file_input",
|
|
174
|
+
`Upload a file to a file input field. Works even when the input is visually hidden behind a custom drag-and-drop zone.
|
|
175
|
+
Uses Chrome DevTools Protocol to set the file \u2014 the only way to bypass the browser's file-input script restriction.
|
|
176
|
+
hint: label text or name of the file input (or empty string to target the first file input on the page).
|
|
177
|
+
file_path: absolute path to the file on the local filesystem (e.g. /Users/you/Downloads/task.zip).
|
|
178
|
+
After calling this, call get_page_text to confirm the file was accepted.`,
|
|
179
|
+
{
|
|
180
|
+
hint: z.string().describe("Label text, name, or surrounding text of the file input. Use empty string to target the first file input on the page."),
|
|
181
|
+
file_path: z.string().describe("Absolute path to the file to upload (e.g. /Users/you/Downloads/task.zip)")
|
|
182
|
+
},
|
|
183
|
+
async ({ hint, file_path }) => {
|
|
184
|
+
const response = await bridge.request({ type: "set_file_input", hint, filePath: file_path });
|
|
185
|
+
const r = response;
|
|
186
|
+
return {
|
|
187
|
+
content: [{ type: "text", text: r.message ?? (r.success ? "File set successfully" : "Failed to set file") }]
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
);
|
|
172
191
|
server.tool(
|
|
173
192
|
"execute_script",
|
|
174
193
|
`Execute JavaScript in the current page's context and return the result as a string.
|
package/package.json
CHANGED