forked from 1b-agent/opencadstudio-upstream
feat(automation): entity, block, publishing and REST operations from the fork
The operations docs/automation/API-SPEC.md (PR #1383) describes, brought over from huaninstratech/OpenCADStudio so the specification no longer runs ahead of the code: - entity CRUD: entities_create, entities_delete, entities_transform, entities_copy_to, and `where` filters on query - blocks and export: block_define, block_delete, a normalised wblock - publishing: layout_create, page_setup_set, plot (per_page included) - metadata: sysvar, xdata_set / xdata_get, file_identity - collections: group_create, selection_set_save / load - control plane: batch, events, view_focus, close - the REST transport: `--http <port>`, the /api/v1 routes and their OpenAPI 3 description - person-in-the-loop picks: user_select and getpoint, hosted by the GUI over the same REST routes, with on-screen pending signals Taken from the fork's commits b7a7ed80, 69396b42, 64f1cf6a, c3aafc8e, bb5a7bfa, 52317a5c, 50d293ba, b90e194f, 517c6397, 53a5c4c9, a49ac045, 37de5a46, a78b1822, 6d9aed2a, 33f522da, 5b5cafe2, 02a7e78d, 94df40dc, fd5bc14d, 485fac61 and 2c5fc994. Left out on purpose: 37de5a46 also removed the donation surface (the Patreon fetch, the donation prompt, the Start-page supporters rail, the DONATE command and its locale strings) and replaced the About dialog's call to action; that is the fork's own product decision and stays out. The fork's version bump and its unrelated IFC/BIM work are not part of this. Adapted while porting: the REST server and the GUI bridge are desktop-only and a template start is refused in the web build, so the wasm target still compiles; the two plot tests read the PDF through the shared stream helper, because exported streams are Flate-compressed; the benches set the new crosshair field; comments and docs describe each operation in its own terms rather than by another product's API names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
531ba44faa
commit
279a87418e
37 files changed
+8795
-82
No files matched your search
+34
-2
@@ -97,7 +97,7 @@ mod dynamic;
|
||||
mod file;
|
||||
mod page_setup_import;
|
||||
mod style;
|
||||
mod util;
|
||||
pub(in crate::app) mod util;
|
||||
mod viewport;
|
||||
mod viewport_snap;
|
||||
|
||||
@@ -404,10 +404,13 @@ impl OpenCADStudio {
|
||||
self.finish_all_pending_history();
|
||||
// After every message, mirror the active command step's prompt so
|
||||
// its history line stays pinned (non-fading) until the step changes.
|
||||
// A pending client pick (`user_select` / `getpoint`) pins its labeled
|
||||
// request line the same way while no command owns the prompt.
|
||||
let prompt = self.tabs[self.active_tab]
|
||||
.active_cmd
|
||||
.as_ref()
|
||||
.map(|c| c.prompt());
|
||||
.map(|c| c.prompt())
|
||||
.or_else(|| self.pending_pick_label());
|
||||
self.command_line.set_step_prompt(prompt);
|
||||
// Mirror the step's clickable options so they render as buttons (#304).
|
||||
let opts = self.tabs[self.active_tab]
|
||||
@@ -528,7 +531,36 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
Message::ControlRequest(envelope) => {
|
||||
// Mirror the automation trail into the message list so the
|
||||
// person at the screen can review what clients asked and
|
||||
// where it failed — the JSON reply alone reaches only the
|
||||
// caller. High-frequency polls are traffic, not activity.
|
||||
let op = envelope.request["op"].as_str().unwrap_or("").to_owned();
|
||||
let (response, task) = self.control_request(envelope.request);
|
||||
if !matches!(
|
||||
op.as_str(),
|
||||
"" | "state" | "hello" | "operation" | "events" | "capabilities"
|
||||
) {
|
||||
if response["ok"] == false {
|
||||
let code = response["code"].as_str().unwrap_or("failed");
|
||||
let detail = response["error"].as_str().unwrap_or("");
|
||||
self.command_line.push_error(&format!(
|
||||
"automation {op}: {code} — {detail}"
|
||||
));
|
||||
} else if matches!(
|
||||
response["status"].as_str(),
|
||||
Some("completed" | "cancelled" | "waiting_input")
|
||||
) && !matches!(
|
||||
op.as_str(),
|
||||
// These already narrate themselves in richer lines.
|
||||
"user_select" | "getpoint" | "cancel"
|
||||
) {
|
||||
self.command_line.push_info(&format!(
|
||||
"automation {op}: {}",
|
||||
response["status"].as_str().unwrap_or("")
|
||||
));
|
||||
}
|
||||
}
|
||||
envelope.reply.send(response);
|
||||
task
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user