all repos — sz-chrome-remote-cdp @ d54d8e9e2dfbd31358b1f48e17338d74f5d270c0

pi-browser-harness, patched to drive a Chrome on another host over CDP, with castle_cdp_search web search

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
commit

d54d8e9e2dfbd31358b1f48e17338d74f5d270c0

parent

9f2f75dd9281153888776e5d39d4926655c15f2a

3 files changed, 8 insertions(+), 7 deletions(-)

jump to
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);