driving-the-editor-ui is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Drive the editor UI by name: run actions, clear blocking dialogs, switch screens, read a dock.
When your agent uses it
- An editor-workflow step a human would do with the mouse — open the Import dock, switch the 2D/3D/Script main screen, toggle a bottom panel, open an editor dialog by name
- A dialog or popup is blocking the editor and tool calls come back modal_open — see it (summer_ui_tree root dialogs) and clear it (summer_ui_activate action dismiss_dialog)
- Reading what a dock or dialog currently shows as structure (summer_ui_tree) instead of guessing from a screenshot
- Deciding whether a request is UI work (summer_ui_*) or scene work (summer_run_script, scene tools, perception tools)
Install
summer setup installs every skill for your agent. To add only this one:
claude-code for your agent, such as codex or cursor. See Skills for every option.
The skill
UI work vs scene work — decide first
The editor UI is not where scene work happens. Nodes, properties, placement, lighting, materials:scene-scripting (summer_run_script), the scene tools, summer_world_snapshot / summer_snapshot_diff / summer_screenshot (verifying-scenes). The Scene dock and the Inspector are views of that data; clicking through them to change a property is slower, less reliable, and unverifiable compared with summer_set_prop.
UI ops are for the steps a human does with the mouse that have no scene-level equivalent:
The ladder
- Dedicated tool (
summer_project_setting,summer_open_scene,summer_select_node,summer_save_scene, …). If one exists, the UI ops are the wrong layer. - Named action —
summer_ui_actions mode:"list" filter:"<word>"to find the exactname, thenmode:"invoke" action_name:"<name>". The event takes the same path the shortcut key would, so the editor’s own handlers run. - Tree + activate —
summer_ui_treeto find a control’spath,summer_ui_activateto press / toggle / select a tab / set text / set a value through the control’s own input path. - Pixels —
summer_ui_screenshot, only to look. There is no coordinate click anywhere in this surface: if a thing is visible it is in the tree, and the tree is what activation takes.
The blocking-dialog pattern
An exclusive dialog (Project Settings, a confirmation, an unsaved-changes prompt) makes the root window drop input; every mutating UI op then answersmodal_open with the blocking_dialog, and other editor operations may stall as still_queued.
summer_ui_tree root:"dialogs"→ readblocking,blocking_dialog {title, path, class}, and the dialog’stextandbuttons(kind: ok | cancel | custom,enabled).- Decide with the user in view.
button:"cancel"is the safe close and the default;"ok"or a custom button text confirms whatever the dialog asks — only when that is what the user wants. summer_ui_activate action:"dismiss_dialog" path:"<blocking_dialog.path>"(ortitle:"<title>").- Read back: the result’s
visible_aftermust befalse, andsummer_ui_tree root:"dialogs"must showblocking:false.visible_after:truemeans the dialog re-validated and stayed up — read it again withroot:"dialog:<title>"instead of retrying blindly.
Main-screen switching
spatial_editor/* actions need the 3D screen; canvas_item_editor/* need 2D; the script editor’s actions need Script. A not_handled result (invoked:true, handled:false) usually means the wrong screen is up.
value is the editor name (2D, 3D, Script, Game, AssetLib, case-insensitive) or index. not_selected means the switch was refused (scene change in progress, hidden editor button) — wait, retry, read back.
Reading a dock’s state
summer_ui_tree root:"dock:<title|id>" (file_system, scene_tree, inspector, or any dock title) returns the dock’s controls with text, tooltip (icon-only buttons are named by it), checked, enabled, tabs + current_tab, value/min/max, item_count/selected. Go deeper on one subtree with root:"path:<path>" and a larger depth/limit; children_truncated:true plus the real child_count tells you where a cut happened.
Paths and auto-names (@Panel@123) are stable within a session only. Re-read the tree before activating; never persist a path across sessions.
The deny-list
The engine refuses, withdenied_action, anything that ends or replaces the session or deletes without the human’s confirmation: editor/file_quit, editor/quit_to_project_list, editor/reload_current_project, scene_tree/delete_no_confirm, every project_manager/* name — and buttons or menu items whose label quits, reloads the project, or closes the editor. summer_ui_actions mode:"list" marks them denied:true. Do not attempt them and do not route around them by path; tell the user what was asked and leave that click to them. File-dialog paths that leave the project (.., user://, ~, absolute paths outside res://) are refused as denied_path.
Verification — read back, never assume
- An invoke succeeded when its effect is observable: a dialog appears in
root:"dialogs", a dock’ssummer_ui_treechanges, or — for anything scene-level —summer_snapshot_diff/summer_get_scene_treeshow it.invoked:truealone proves the event was dispatched, not that anything happened. summer_ui_activatereturnsstateafter the action from the same node (checked,current_tab,text,value,freed:trueif the action freed it). Cite it.- A screenshot proves appearance only. A control’s exact state is in the tree.
engine_lacks_opmeans the build predates these ops: nothing was sent. Use the dedicated tools for the outcome, or ask the user to click, and say so.
Failure taxonomy — what to do
Related skills:
scene-scripting and verifying-scenes own the scene loop this skill deliberately stays out of; verification-before-completion carries the done-claiming rules; headless-scripting is the route when there is no editor UI at all.
From a shell
No Summer MCP tools in this session? Run each one as a command; whensummer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.
Related skills
scene-scripting: Build scenes, levels, HUDs and wiring with one editor GDScript (summer_run_script) instead of call chains.verifying-scenes: Prove scene work landed: snapshot, diff, screenshots, runtime reads, 3D audits, shot sheets and zooms.verification-before-completion: Run verification and read its output before claiming work done, fixed or passing: evidence first.headless-scripting: Run a GDScript file against Summer Engine from the shell for what no MCP tool does: navmesh, TileSets.
Source:
library/skills/driving-the-editor-ui/SKILL.md, rendered from summer-engine@4.3.0 on npm.
