diff --git a/chat.el b/chat.el index 913259d..6813b64 100644 --- a/chat.el +++ b/chat.el @@ -631,6 +631,17 @@ fn handle_chat_agentic(body: String) -> String { return "{\"error\":\"message required\",\"reply\":\"\"}" } + // Workspace scope (#23): the desktop UI sends the user-chosen Agent Workspace root + // on every agentic request. Persist it to state so agent_workspace_root() — and the + // path/command tool guards that read it — confine this turn's file/command tools to + // that subtree. The UI is the source of truth per request: empty means unscoped (the + // backward-compatible default), and it also lets agent_workspace_root() fall through + // to the NEURON_AGENT_ROOT env when no root is sent. FLAGGED FOR REVIEW: setting + // state from the body each turn (vs. only-when-nonempty) so clearing the folder in + // the UI un-scopes — confirm this is the intended ownership model. + let ws_root: String = json_get(body, "agent_workspace_root") + state_set("agent_workspace_root", ws_root) + let req_model: String = json_get(body, "model") let model: String = if str_eq(req_model, "") { chat_default_model() } else { req_model }