Agent cursor: a violet pointer labelled Agent acts out control-channel and MCP commands. It glides to the command's toolbar button (or its panel) and clicks with a ripple, then to each pick (faces, edges and points projected to the screen, sketch points, a new sketch's plane, the profiles an extrude takes), then the command runs; the reply waits for it and later requests queue behind. Speed instant/normal/slow; follow camera turns to a new sketch and back on finish. View settings on the navigation bar (Show Agent Cursor, speed, follow camera; remembered, off by default); ui.agent_cursor {show, speed, follow_camera}; "animate": false per call. Tests: pick to screen mapping; scenario with the cursor on (replies wait for the animation) matching the cursor-off result

Fixes #35

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-09 18:21:47 +00:00
1 parent 9c0632b07c
commit 50a74ac66d
7 files changed
+472 -4

No files matched your search

+19
View File
@@ -27,6 +27,9 @@
//! - `ui.prefs {...}`: the preferences (default_units, nav, zoom_reverse, orbit_cursor, msaa,
//! length_decimals, angle_decimals); returns them all
//! - `ui.capture {action?: capture|revert|cancel}`: the Capture Position question
//! - `ui.agent_cursor {show?, speed?: instant|normal|slow, follow_camera?}`: the agent cursor
//! (#35); while it is shown, `engine.execute` first glides to the command's button and picks
//! and replies once the command has run (`"animate": false` skips that one call)
//! - `ui.resize {width, height}`, `app.quit`
use std::sync::mpsc::Sender;
@@ -95,6 +98,22 @@ pub fn handle(app: &mut SolveApp, ctx: &egui::Context, req: &ControlRequest) ->
}
wrap(r)
}
"ui.agent_cursor" => {
let s = &mut app.ui.agent_cursor;
if let Some(v) = p.get("show").and_then(Value::as_bool) {
s.show = v;
}
if let Some(v) = p.get("follow_camera").and_then(Value::as_bool) {
s.follow_camera = v;
}
if let Some(v) = p.get("speed") {
match serde_json::from_value(v.clone()) {
Ok(sp) => s.speed = sp,
Err(_) => return err("speed must be instant, normal or slow"),
}
}
ok(json!(app.ui.agent_cursor))
}
"engine.script" => wrap(app.session.run_script(p).map(|v| json!(v)).map_err(|e| e.to_string())),
"engine.commands" => wrap(app.session.execute("engine.commands", &json!({})).map_err(|e| e.to_string())),
"document.inspect" => wrap(app.session.execute("document.inspect", p).map_err(|e| e.to_string())),