MCP: Text Path Options ▸ Path lists the layer's masks as its options, like the Timeline

This commit is contained in:
Marco Arnulfo
2026-10-30 00:44:58 +01:00
parent 701d9df8a5
commit 86268fc4cc
10 changed files with 40 additions and 24 deletions
+2 -2
View File
@@ -999,8 +999,8 @@ fn list(_: &mut Session, p: &Value) -> Result<Value> {
json!({"id": e.id, "name": e.name, "category": e.category, "gpu": e.gpu, "float": e.float, "params": e.params.iter().map(|p| {
let mut out = json!({"id": p.id, "name": p.name, "type": p.default.kind_name(), "default": p.default.to_json()});
match &p.ui {
effectcraft_project::ParamUi::Popup { .. } => {
out["options"] = super::popup_options(&p.ui).unwrap_or_default();
effectcraft_project::ParamUi::Popup { options } => {
out["options"] = super::popup_options(options);
}
effectcraft_project::ParamUi::Slider { min, max, slider_min, slider_max, decimals } => {
out["min"] = json!(min);
+3 -4
View File
@@ -58,11 +58,10 @@ pub(crate) fn selected_leaf_props(s: &Session) -> Vec<(LayerId, effectcraft_proj
out
}
/// A popup property's `[{value, label}]`, as `effect.list`, `prop.get` and `layer.tree` report it.
/// A popup's `[{value, label}]`, as `effect.list`, `prop.get` and `layer.tree` report it.
/// Engine/MCP popup values are zero-based; JSX exposes one-based values.
pub(crate) fn popup_options(ui: &effectcraft_project::ParamUi) -> Option<Value> {
let effectcraft_project::ParamUi::Popup { options } = ui else { return None };
Some(serde_json::json!(options.iter().enumerate().map(|(value, label)| serde_json::json!({"value": value, "label": label})).collect::<Vec<_>>()))
pub(crate) fn popup_options(options: &[String]) -> Value {
serde_json::json!(options.iter().enumerate().map(|(value, label)| serde_json::json!({"value": value, "label": label})).collect::<Vec<_>>())
}
// ---------- params ----------
+2 -2
View File
@@ -491,8 +491,8 @@ fn get(s: &mut Session, p: &Value) -> Result<Value> {
"time": t.seconds(), "value": raw.to_json(), "animated": !pr.keys.is_empty(),
"keys": keys, "expression": pr.expr.as_ref().map(|e| e.text.clone()),
});
if let Some(o) = super::popup_options(&pr.ui) {
out["options"] = o;
if let Some(o) = l.popup_options(pr) {
out["options"] = super::popup_options(&o);
}
// With an expression, `value` is the keyframed (pre-expression) value; also report what the
// expression makes of it (what renders), or why it fails. A disabled one renders `value`; one
+2 -2
View File
@@ -129,8 +129,8 @@ fn group_json(g: &PropGroup, path: &str, l: &Layer, t: effectcraft_time::Tick, d
if let Some(e) = &p.expr {
o["expression"] = json!(e.text);
}
if let Some(opts) = super::popup_options(&p.ui) {
o["options"] = opts;
if let Some(opts) = l.popup_options(p) {
o["options"] = super::popup_options(&opts);
}
o
}