Skip to content

Commit 78f9222

Browse files
mq1ndsarnoclaude
authored
Surface editor error context in log reads (#520)
* Surface editor error context in log reads Editor and game logs now preserve structured error details, read visible Debugger Errors rows through logs_read, and clear those rows from clear_logs. Compact responses remain the default; callers opt into rich metadata with include_details. * Address review: gate Errors-tab clear, full stack frames, cheaper polling - clear_logs no longer wipes the Debugger Errors panel by default; the Errors-tab clear sits behind a new clear_debugger_errors opt-in and routes through the panel's own Clear button so the engine resets error_count/warning_count, the "Errors (N)" badge, the errors_cleared signal, and toolbar button states (a raw Tree.clear() left them stale). - details.frames now captures every stack row. The real tree (verified against script_editor_debugger.cpp on 4.3 and 4.6) lays frames out as flat children with only frame 0 labeled "<Stack Trace>", so the old per-child label match collapsed multi-frame stacks to one entry. Detection is run-based, survives translated labels, and the test fixture now mirrors the real layout. - _entries_for_response shallow-copies on the default compact path and reserves the deep copy for include_details=true. - Debugger tree discovery scans only the cached EditorDebuggerNode subtree instead of recursing the whole editor UI on every poll. Live-smoked against a real editor (Godot 4.6.3): a real push_error row returned all 5 stack frames; the opt-in clear reset the "Errors (1)" badge and button states via the engine's own clear path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: David Sarno <david@lighthaus.us> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 6aa009e commit 78f9222

14 files changed

Lines changed: 906 additions & 82 deletions

File tree

docs/TOOLS.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,22 @@ not the MCP tool names.
2929
| `script_create` / `script_attach` / `script_patch` | Create, attach, anchor-edit GDScript files |
3030
| `project_run` | Play the project (autosave persists in-memory MCP edits unless `autosave=False`) |
3131
| `test_run` | Run GDScript test suites in the editor |
32-
| `logs_read` | Read plugin / game / editor / combined log buffers. `source="editor"` surfaces parse errors + @tool/EditorPlugin runtime errors + push_error/push_warning (Godot 4.5+, filtered to user .gd/.cs) — use this when the editor's Output panel shows red lines but `logs_read` returned nothing |
32+
| `logs_read` | Read plugin / game / editor / combined log buffers. `source="editor"` surfaces parse errors, GDScript reload warnings, @tool/EditorPlugin runtime errors, push_error/push_warning, and visible Debugger dock Errors-tab rows — use this when the editor's Output or Debugger Errors panel shows red/yellow rows |
3333
| `editor_screenshot` | Capture editor viewport, cinematic camera, or running game framebuffer |
3434
| `editor_reload_plugin` | Reload the plugin and wait for reconnect (server must be external) |
3535
| `animation_create` | Create an Animation clip (auto-creates AnimationPlayer + library if missing) |
3636

37+
`logs_read` also accepts `include_details=true` for `source="editor"`,
38+
`source="game"`, and `source="all"`. Detailed entries include the original
39+
Godot `_log_error` code/rationale when available, error type, resolved source
40+
location, and stack/error-tree context corresponding to the Debugger dock's
41+
Errors tab.
42+
43+
`editor_manage(op="logs_clear")` accepts `clear_debugger_errors=true` to also
44+
clear the Debugger dock's visible Errors-tab rows (routed through the panel's
45+
own Clear path so the tab badge and counters reset). The Errors panel is
46+
user-facing UI, so the default leaves it untouched.
47+
3748
## Domain rollups (`<domain>_manage`)
3849

3950
Each rollup is a single MCP tool dispatched by `op` name + `params` dict.

plugin/addons/godot_ai/debugger/mcp_debugger_plugin.gd

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,24 @@ func _capture(message: String, data: Array, session_id: int) -> bool:
192192
func _on_log_batch(data: Array) -> void:
193193
if _game_log_buffer == null:
194194
return
195-
## data layout: [[[level, text], [level, text], ...]]
195+
## data layout: [[[level, text, details?], ...]]
196196
if data.is_empty() or not (data[0] is Array):
197197
return
198198
var entries: Array = data[0]
199199
for entry in entries:
200+
if entry is Dictionary:
201+
var dict_details: Dictionary = {}
202+
var raw_dict_details = entry.get("details", {})
203+
if raw_dict_details is Dictionary:
204+
dict_details = raw_dict_details
205+
_game_log_buffer.append(str(entry.get("level", "info")), str(entry.get("text", "")), dict_details)
206+
continue
200207
if not (entry is Array) or entry.size() < 2:
201208
continue
202-
_game_log_buffer.append(str(entry[0]), str(entry[1]))
209+
var details: Dictionary = {}
210+
if entry.size() > 2 and entry[2] is Dictionary:
211+
details = entry[2]
212+
_game_log_buffer.append(str(entry[0]), str(entry[1]), details)
203213

204214

205215
## Request a game-process framebuffer capture over the debugger channel.

0 commit comments

Comments
 (0)