Expand description
Cross-target instrumentation for AI-assisted egui development.
eguidev captures widget state at frame boundaries and injects input
through an egui plugin registered on the first instrumented frame, keeping
automation aligned with the app’s real event loop. This crate is the
instrumentation half of the automation stack: it is valid for native and
wasm32 builds, and it intentionally does not ship the embedded script
runtime, MCP server, or screenshot machinery.
§Quick start
Add a DevMcp handle to your app state and wrap each frame with
FrameGuard. Input injection is automatic from there: the first
FrameGuard registers an egui plugin that drains queued input into
every pass of every viewport, so apps do not need any raw-input wiring.
The handle stays inert until a native app opts into eguidev_runtime and
attaches the embedded runtime in one bootstrap location.
use eframe::{App, egui};
use eguidev::{DevMcp, DevUiExt, FrameGuard};
struct MyApp {
devmcp: DevMcp,
name: String,
}
impl MyApp {
fn new() -> Self {
Self {
devmcp: DevMcp::new(),
name: String::new(),
}
}
}
impl App for MyApp {
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
let ctx = ui.ctx().clone();
let _guard = FrameGuard::new(&self.devmcp, &ctx);
egui::Frame::central_panel(ui.style()).show(ui, |ui| {
ui.dev_text_edit("app.name", &mut self.name);
if ui.dev_button("app.submit", "Submit").clicked() {
// ...
}
});
}
}§Build modes
- Cross-target instrumentation: depend on
eguidevonly.DevMcp,FrameGuard, widget tagging, and fixtures all compile for native andwasm32targets. - Native embedded runtime: add an app-local feature that enables the
optional
eguidev_runtimedependency, then calleguidev_runtime::attach(devmcp)in one bootstrap location. Keep that branch local to startup code instead of pushing#[cfg]into widget code.
§Instrumenting widgets
Use the DevUiExt trait for standard widgets. Each dev_* method takes
an explicit string id and auto-populates role, label, and value metadata:
ui.dev_button("settings.save", "Save");
ui.dev_text_edit("settings.name", &mut name);
ui.dev_checkbox("settings.enabled", &mut enabled, "Enabled");
ui.dev_slider("settings.level", &mut level, 0.0..=100.0);For custom widgets, use id (geometry only) or id_with_meta (explicit
role/value/label). If you already have an egui::Response, use
track_response_full to register it after the fact. Use container to
annotate hierarchy so scripts can traverse parent/child relationships.
Custom widgets that should accept scripted set_value(...) calls must also
consume queued overrides before rendering:
let id = "settings.mode";
if let Some(crate::WidgetValue::Int(index)) = take_widget_value_override(ui, id) {
*selected = index as usize;
}
let response = render_custom_mode_picker(ui, selected);
track_response_full(
id,
&response,
WidgetMeta {
role: WidgetRole::ComboBox,
value: Some(WidgetValue::Int(*selected as i64)),
role_state: Some(RoleState::ComboBox {
options: mode_labels.clone(),
}),
..Default::default()
},
);Widget ids are the one canonical selector in the scripting API. Explicit ids must be unique within a captured frame; duplicates are treated as a hard automation fault.
§Fixtures
Apps register fixtures with DevMcp::fixtures and exactly one handler:
DevMcp::on_fixture_runtime for automation-thread setup or
DevMcp::on_fixture_ui for setup that must run on the egui UI thread.
Each fixture must be independently invokable from any prior state and must
leave the app in a baseline that can be described with readiness anchors.
Use typed fixture params for controlled variants, preconditions for state
that must already be true before the handler runs, and handler-returned
values or anchors for dynamic fixture outcomes. Scripts call
fixture("name", params?) to apply the named baseline, wait for fresh
captures, verify static plus returned anchors, and receive the returned
values. Widget and viewport handles resolve fresh across fixture boundaries,
so rebinding root() after each fixture is usually unnecessary. Use
fixture_raw("name", params?) only when you explicitly want the
fire-and-forget behavior for debugging or manual setup flows.
§Scripting reference
The canonical Luau API, direct script evaluation helpers, and the smoketest
runner all live in eguidev_runtime. edev serves those checked-in
definitions through script_api and edev docs.
Structs§
- Anchor
- A single readiness anchor for a fixture baseline.
- Automation
Options - Button
Options - Options for selected-aware buttons.
- Checkbox
Options - Options for third-state checkboxes.
- Container
Guard - RAII guard that pops a container scope when dropped.
- DevMcp
- DevMCP handle stored in app state.
- DevMcp
Config Error - Configuration error returned while building a
crate::DevMcphandle. - Diagnostic
Error - Structured failure returned by an app diagnostic provider.
- Fixture
Call - Fixture call passed to a registered handler.
- Fixture
Error - Structured fixture handler failure.
- Fixture
Param - One typed fixture parameter in a fixture catalog entry.
- Fixture
Params - Validated fixture params passed to a handler.
- Fixture
Response - Successful fixture handler response.
- Fixture
Spec - Fixture metadata advertised by an app.
- Frame
Guard - RAII guard that calls
begin_frameandend_frameautomatically. - Progress
BarOptions - Options for progress bars.
- Script
Prelude - App Luau helpers evaluated before every script under an app namespace.
- Scroll
Area Meta - Scroll metadata captured for a scroll area.
- Scroll
Area State - Scroll area state tracker with one-shot offset jumps.
- Text
Edit Options - Options for text-edit widgets.
- Viewport
Name Error - Error returned when a semantic viewport name is reserved or invalid.
- Viewport
Sel - Explicit selector for a viewport.
- Viewport
SelParse Error - Error returned when parsing a viewport selector string fails.
- Widget
Data Error - Error returned by strict widget data attachment.
- Widget
Layout - Layout metadata captured for a widget when available.
- Widget
Meta - Metadata for a widget used during tracking and layout analysis.
- Widget
Range - Min/max bounds for a numeric widget.
- Widget
State - Live widget snapshot exposed to scripting surfaces.
Enums§
- Anchor
Check - Declarative readiness checks for fixture anchors.
- Param
Kind - Supported scalar kinds for fixture parameters.
- Role
State - Role-specific widget metadata kept on internal registry entries.
- Widget
Role - Widget role taxonomy for automation and scripting filters.
- Widget
Value - Captured widget value for stateful controls.
Traits§
- DevScroll
Area Ext - Helper extensions for recording scroll areas with explicit ids.
- DevUi
Ext - Helper extensions for recording common widgets with explicit ids.
Functions§
- capture_
layout - Capture layout metadata for an already-rendered custom widget response.
- clear_
viewport - Clear script-visible widgets for a viewport that is no longer rendered.
- container
- Run a closure within a container scope with an explicit id.
- frame_
scope - Wrap one viewport frame and register
container_idas its root container. - id
- Record a widget with an explicit id and geometry only.
- id_
with_ meta - Record a widget with an explicit id and explicit metadata.
- name_
viewport - Register a semantic name for the viewport currently rendering in
ctx. - publish_
rect_ meta - Publish metadata for a painter-drawn rect that has no
egui::Response. - take_
widget_ value_ override - Consume a queued widget value override for a custom instrumented widget.
- track_
response_ full - Track an already-created widget response with explicit metadata.
Type Aliases§
- Diagnostic
Result - Result returned by an app diagnostic provider.
- Fixture
Result - Result returned by a fixture handler.