fix(domains): restore fail-closed focus check in browser_type
Adopting isFocusProbe inverted the safety default: the guard was ANDed into
the condition gating the check, so a probe result the guard rejected skipped
the check and fell through to Input.insertText — text typed into nothing,
silently, which is the exact failure the block exists to prevent. The guard
now feeds a value that defaults to { ok: false }, so a rejected shape
produces the error instead of bypassing it.
The other four guard adoptions (isFillResult, isFocusResult, isSelectResult,
isPageResult) were already fail-closed: each feeds a value whose rejection
lands on a pre-existing error branch.
Also assert x/y in the box centre test — the fields snapshot's off-viewport
filter reads — and wrap the zero-size message to the surrounding width.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
amankumarsingh77 amankumarsingh7702@gmail.com
Mon, 27 Jul 2026 23:37:04 +0530
3 files changed,
8 insertions(+),
7 deletions(-)
M
src/domains/box.ts
→
src/domains/box.ts
@@ -41,7 +41,10 @@ if (model.content.length < 8) {
return err({ kind: "invalid_state", message: "DOM.getBoxModel returned an incomplete content quad" }); } if (model.width <= 0 || model.height <= 0) { - return err({ kind: "invalid_state", message: "element has a zero-size box and cannot be clicked" }); + return err({ + kind: "invalid_state", + message: "element has a zero-size box and cannot be clicked", + }); } return ok(centreOf(model)); };
M
src/domains/keyboard.ts
→
src/domains/keyboard.ts
@@ -27,10 +27,6 @@ "For special keys (Enter, Tab, Escape, arrows), use browser_press_key instead.",
], parameters: TypeArgs, async handler(args, { client }): Promise<Result<ToolOk, ToolErr>> { - // Guard against silent text loss: Input.insertText succeeds regardless of - // whether an editable element is focused, so without this check typed text - // can vanish into the void with no error. Fail loudly with an actionable - // message instead. IIFE starts with "(" so evaluateJs returns it directly. const focused = await client.evaluateJs(safeJs` (() => { const el = document.activeElement;@@ -39,8 +35,8 @@ (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable);
return { ok, tag: el ? el.tagName : null }; })() `); - if (focused.success && isFocusProbe(focused.data)) { - const f = focused.data; + if (focused.success) { + const f: FocusProbe = isFocusProbe(focused.data) ? focused.data : { ok: false, tag: null }; if (!f.ok) { return err({ kind: "invalid_state",
M
test/domains/box-test.ts
→
test/domains/box-test.ts
@@ -5,6 +5,8 @@
describe("box centre", () => { test("computes the centre from a content quad", () => { const b = centreOf({ content: [10, 20, 110, 20, 110, 70, 10, 70], width: 100, height: 50 }); + assert.equal(b.x, 10); + assert.equal(b.y, 20); assert.equal(b.cx, 60); assert.equal(b.cy, 45); assert.equal(b.width, 100);