Grid / Table Cell Addressing
anchor_locator does pairwise spatial relations (target near / below an
anchor) but nothing addresses a 2-D grid — “the cell at row 3, column 2” of a
table. Given the bounding boxes of the cells (from an image or OCR enumeration,
e.g. locate_all_image / find_text_matches), this clusters them into rows
and columns and returns the requested cell’s centre.
The clustering and lookup are pure (boxes in, grid / cell out) and fully
unit-testable; the box enumeration stays the caller’s job, so nothing here needs a
real screen. Imports no PySide6.
Headless API
from je_auto_control import cluster_grid, locate_cell
boxes = [(10, 100, 20, 10), (110, 100, 20, 10), (210, 100, 20, 10),
(10, 200, 20, 10), (110, 200, 20, 10), (210, 200, 20, 10)]
locate_cell(boxes, row=1, col=2)
# {'found': True, 'center': [220, 205], 'box': [210, 200, 20, 10],
# 'row': 1, 'col': 2, 'rows': 2, 'cols': 3}
cluster_grid(boxes) # rows top-to-bottom, cells left-to-right
cluster_grid sorts the boxes by centre-y, starts a new row when the gap
exceeds row_tolerance, and orders each row’s cells by centre-x.
locate_cell returns the centre (ready to click) of the 0-based (row, col)
cell, or {found: False, reason} when the index is out of range.
Executor commands
AC_grid_cell takes boxes (a JSON [[x, y, w, h], ...] list, e.g. from a
prior AC_locate_all_image step) plus row / col / row_tolerance and
returns the cell dict. It is exposed as the MCP tool ac_grid_cell and as a
Script Builder command under Mouse.