New Features (2026-06-19) — Authoring & Debugging
Two authoring-time tools, pure standard library and wired through the
full stack (facade, AC_* executor commands, MCP tools, Script
Builder): a native-UI element repository (object repository) and a
step debugger / tracer for action lists.
Element repository
Save native-UI locators under friendly names once, reuse them everywhere
— the classic RPA object repository. A flow references
"login.submit" instead of repeating name="Submit", role="button"
at every call site, and a UI change is fixed in one place:
from je_auto_control import ElementRepository
repo = ElementRepository("app.objects.json")
repo.save("login.submit", name="Submit", role="button")
repo.save("login.user", role="edit", app_name="MyApp")
repo.click("login.submit") # resolve + click the live element
info = repo.find_info("login.user") # {found, name, role, center}
A locator is a small set of accessibility filters (name / role /
app_name); resolving finds the live element through the accessibility
backend. Storage is a JSON file and works on any platform; resolution
needs a platform accessibility backend.
Executor / MCP commands: AC_element_save / AC_element_find /
AC_element_click / AC_element_remove / AC_element_list (and
the matching ac_element_* MCP tools).
Step debugger and tracer
Run an action list one command at a time with breakpoints, single-step,
and live variable inspection. Stepping reuses one executor instance, so
script variables (${name} interpolation, AC_set_var …) persist
across steps exactly as in a normal run:
from je_auto_control import FlowDebugger
dbg = FlowDebugger(actions, breakpoints=[3])
dbg.continue_() # run until the breakpoint
dbg.variables() # inspect live variables
dbg.step() # one command at a time
dbg.run_to_end()
The stateless one-shot form, trace_actions(), runs a list (or
dry_run to only plan it) and returns a per-step trace of
{index, command, result} — exposed as AC_debug_trace /
ac_debug_trace:
from je_auto_control import trace_actions
plan = trace_actions(actions, dry_run=True) # plan without running
trace = trace_actions(actions) # run and trace