refactor: make browser actions ref-only

This commit is contained in:
Peter Steinberger
2025-12-26 19:02:19 +00:00
parent f50f18f65a
commit 1236c4dafb
15 changed files with 131 additions and 183 deletions

View File

@@ -114,9 +114,8 @@ export function registerBrowserActionInputCommands(
browser
.command("click")
.description("Click an element by ai ref or CSS selector")
.argument("[ref]", "Ref id from ai snapshot")
.option("--selector <css>", "CSS selector (instead of ref)")
.description("Click an element by ref from snapshot")
.argument("<ref>", "Ref id from ai snapshot")
.option("--target-id <id>", "CDP target id (or unique prefix)")
.option("--double", "Double click", false)
.option("--button <left|right|middle>", "Mouse button to use")
@@ -124,11 +123,9 @@ export function registerBrowserActionInputCommands(
.action(async (ref: string | undefined, opts, cmd) => {
const parent = parentOpts(cmd);
const baseUrl = resolveBrowserControlUrl(parent?.url);
const selector =
typeof opts.selector === "string" ? opts.selector.trim() : "";
const refValue = typeof ref === "string" ? ref.trim() : "";
if (!selector && !refValue) {
defaultRuntime.error(danger("ref or --selector is required"));
if (!refValue) {
defaultRuntime.error(danger("ref is required"));
defaultRuntime.exit(1);
return;
}
@@ -141,8 +138,7 @@ export function registerBrowserActionInputCommands(
try {
const result = await browserAct(baseUrl, {
kind: "click",
ref: refValue || undefined,
selector: selector || undefined,
ref: refValue,
targetId: opts.targetId?.trim() || undefined,
doubleClick: Boolean(opts.double),
button: opts.button?.trim() || undefined,
@@ -153,11 +149,7 @@ export function registerBrowserActionInputCommands(
return;
}
const suffix = result.url ? ` on ${result.url}` : "";
if (selector) {
defaultRuntime.log(`clicked ${selector}${suffix}`);
} else {
defaultRuntime.log(`clicked ref ${refValue}${suffix}`);
}
defaultRuntime.log(`clicked ref ${refValue}${suffix}`);
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);
@@ -166,29 +158,25 @@ export function registerBrowserActionInputCommands(
browser
.command("type")
.description("Type into an element by ai ref or CSS selector")
.argument("[ref]", "Ref id from ai snapshot")
.description("Type into an element by ref from snapshot")
.argument("<ref>", "Ref id from ai snapshot")
.argument("<text>", "Text to type")
.option("--selector <css>", "CSS selector (instead of ref)")
.option("--submit", "Press Enter after typing", false)
.option("--slowly", "Type slowly (human-like)", false)
.option("--target-id <id>", "CDP target id (or unique prefix)")
.action(async (ref: string | undefined, text: string, opts, cmd) => {
const parent = parentOpts(cmd);
const baseUrl = resolveBrowserControlUrl(parent?.url);
const selector =
typeof opts.selector === "string" ? opts.selector.trim() : "";
const refValue = typeof ref === "string" ? ref.trim() : "";
if (!selector && !refValue) {
defaultRuntime.error(danger("ref or --selector is required"));
if (!refValue) {
defaultRuntime.error(danger("ref is required"));
defaultRuntime.exit(1);
return;
}
try {
const result = await browserAct(baseUrl, {
kind: "type",
ref: refValue || undefined,
selector: selector || undefined,
ref: refValue,
text,
submit: Boolean(opts.submit),
slowly: Boolean(opts.slowly),
@@ -198,11 +186,7 @@ export function registerBrowserActionInputCommands(
defaultRuntime.log(JSON.stringify(result, null, 2));
return;
}
if (selector) {
defaultRuntime.log(`typed into ${selector}`);
} else {
defaultRuntime.log(`typed into ref ${refValue}`);
}
defaultRuntime.log(`typed into ref ${refValue}`);
} catch (err) {
defaultRuntime.error(danger(String(err)));
defaultRuntime.exit(1);

View File

@@ -9,17 +9,15 @@ export const browserCoreExamples = [
"clawdis browser screenshot",
"clawdis browser screenshot --full-page",
"clawdis browser screenshot --ref 12",
"clawdis browser snapshot",
"clawdis browser snapshot --format aria --limit 200",
"clawdis browser snapshot --format ai",
];
export const browserActionExamples = [
"clawdis browser navigate https://example.com",
"clawdis browser resize 1280 720",
"clawdis browser click 12 --double",
"clawdis browser click --selector 'button.save'",
'clawdis browser type 23 "hello" --submit',
'clawdis browser type --selector "input[name=q]" "hello"',
"clawdis browser press Enter",
"clawdis browser hover 44",
"clawdis browser drag 10 11",

View File

@@ -45,8 +45,8 @@ export function registerBrowserInspectCommands(
browser
.command("snapshot")
.description("Capture an AI-friendly snapshot (aria or ai)")
.option("--format <aria|ai>", "Snapshot format (default: aria)", "aria")
.description("Capture a snapshot (default: ai; aria is the accessibility tree)")
.option("--format <aria|ai>", "Snapshot format (default: ai)", "ai")
.option("--target-id <id>", "CDP target id (or unique prefix)")
.option("--limit <n>", "Max nodes (default: 500/800)", (v: string) =>
Number(v),
@@ -55,7 +55,7 @@ export function registerBrowserInspectCommands(
.action(async (opts, cmd) => {
const parent = parentOpts(cmd);
const baseUrl = resolveBrowserControlUrl(parent?.url);
const format = opts.format === "ai" ? "ai" : "aria";
const format = opts.format === "aria" ? "aria" : "ai";
try {
const result = await browserSnapshot(baseUrl, {
format,