From 9f2f75dd9281153888776e5d39d4926655c15f2a Mon Sep 17 00:00:00 2001 From: amankumarsingh77 Date: Mon, 27 Jul 2026 23:26:50 +0530 Subject: refactor(domains): drop CDP casts, share the box-model unwrap ref-resolve.ts and snapshot.ts had the same box-model unwrap, both using data.model! to work around an untyped response. Extracted to domains/box.ts; the typed schema makes the assertions unnecessary. Both derived the centre identically (quad corner + half the model width/height), so centreOf keeps that derivation; the shared zero-size rejection moved into boxOf, and snapshot keeps its own off-viewport (x/y < 0) filter. evalInIsolatedTab now goes through evaluateJson with the tab's own sessionId and a caller-supplied guard; both callers evaluate expressions ending in JSON.stringify, so they pass isJsonText rather than a check that checks nothing. Runtime.evaluate/callFunctionOn result casts in form.ts, forms.ts and keyboard.ts are replaced by named guards over the in-page result shapes. Runtime.callFunctionOn's params schema gained arguments/returnByValue/ awaitPromise/userGesture: four domain call sites legitimately pass them and typebox's additionalProperties:true does not widen the static type, so the params type was rejecting valid CDP fields. Params schemas are type-only (only results are compiled), so this is a compile-time widening with no runtime effect. tsc is green again for both tsconfigs. Co-Authored-By: Claude Opus 5 (1M context) --- src/domains/ref-resolve.ts | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'src/domains/ref-resolve.ts') diff --git a/src/domains/ref-resolve.ts b/src/domains/ref-resolve.ts index 3f636df..de83521 100644 --- a/src/domains/ref-resolve.ts +++ b/src/domains/ref-resolve.ts @@ -1,10 +1,9 @@ import type { BrowserClient } from "../client"; import { type Result, err, ok } from "../util/result"; import type { ToolErr } from "../util/tool"; +import { type Box, boxOf } from "./box"; import { buildTree, collectInteractiveTargets, type RawAxNode, type SlimNode } from "./snapshot"; -type Box = { x: number; y: number; width: number; height: number; cx: number; cy: number }; - const staleErr = (ref: string): ToolErr => ({ kind: "invalid_state", message: `Ref ${ref} is unknown or stale — re-run browser_snapshot to get fresh refs.`, @@ -29,7 +28,7 @@ export const resolveRefToObjectId = async ( // a stale ref rather than a raw CDP error so the agent knows to re-snapshot. return err(staleErr(ref)); } - const objectId = (resolved.data as { object?: { objectId?: string } }).object?.objectId; + const objectId = resolved.data.object.objectId; if (!objectId) return err(staleErr(ref)); return ok(objectId); }; @@ -52,24 +51,9 @@ export const resolveRefToBox = async ( ): Promise> => { const backendId = client.session().resolveRef(ref); if (backendId === undefined) return err(staleErr(ref)); - const r = await client.session().call("DOM.getBoxModel", { backendNodeId: backendId }); - if (!r.success) return err(staleErr(ref)); - const data = r.data as { model?: { content?: ReadonlyArray; width?: number; height?: number } }; - const content = data.model?.content; - if (!content || content.length < 8) return err(staleErr(ref)); - const x = content[0]!; - const y = content[1]!; - const width = data.model!.width ?? 0; - const height = data.model!.height ?? 0; - if (width <= 0 || height <= 0) return err(staleErr(ref)); - return ok({ - x: Math.round(x), - y: Math.round(y), - width: Math.round(width), - height: Math.round(height), - cx: Math.round(x + width / 2), - cy: Math.round(y + height / 2), - }); + const box = await boxOf(client, backendId); + if (!box.success) return err(staleErr(ref)); + return ok(box.data); }; const sigOf = (n: SlimNode): string => `${n.role}|${n.name ?? ""}|${n.value ?? ""}|${n.state ?? ""}`; -- cgit v1.2.3