29dfd245 by Ean Schuessler

Add compact/ARIA render modes, fix framework transitions

- Add compact render mode (now default): LLM-optimized ~75% smaller output
  - Shows forms with fields, grids with sample rows, actions with services
  - Truncates dropdown options with fetch hints

- Add ARIA render mode: W3C accessibility tree format
  - Maps Moqui fields to ARIA roles (textbox, combobox, checkbox, etc.)

- Fix action execution to use framework transitions
  - Actions now append to screen path for proper transition handling
  - Framework handles inheritance, pre/post actions, response handling

- Fix CSRF bypass for MCP requests
  - Set moqui.request.authenticated=true in MockHttpServletRequest attributes
1 parent 03e420e8
...@@ -324,6 +324,7 @@ class WebFacadeStub implements WebFacade { ...@@ -324,6 +324,7 @@ class WebFacadeStub implements WebFacade {
324 private String screenPath 324 private String screenPath
325 private String remoteUser = null 325 private String remoteUser = null
326 private java.security.Principal userPrincipal = null 326 private java.security.Principal userPrincipal = null
327 private Map<String, Object> attributes = [:]
327 328
328 MockHttpServletRequest(Map<String, Object> parameters, String method, HttpSession session = null, String screenPath = null) { 329 MockHttpServletRequest(Map<String, Object> parameters, String method, HttpSession session = null, String screenPath = null) {
329 this.parameters = parameters ?: [:] 330 this.parameters = parameters ?: [:]
...@@ -331,6 +332,10 @@ class WebFacadeStub implements WebFacade { ...@@ -331,6 +332,10 @@ class WebFacadeStub implements WebFacade {
331 this.session = session 332 this.session = session
332 this.screenPath = screenPath 333 this.screenPath = screenPath
333 334
335 // Mark request as authenticated for MCP - bypasses CSRF token check for transitions
336 // This is safe because MCP requests are already authenticated via the MCP session
337 this.attributes["moqui.request.authenticated"] = "true"
338
334 // Extract user information from session attributes for authentication 339 // Extract user information from session attributes for authentication
335 if (session) { 340 if (session) {
336 def username = session.getAttribute("username") 341 def username = session.getAttribute("username")
...@@ -385,9 +390,9 @@ class WebFacadeStub implements WebFacade { ...@@ -385,9 +390,9 @@ class WebFacadeStub implements WebFacade {
385 @Override String getProtocol() { return "HTTP/1.1" } 390 @Override String getProtocol() { return "HTTP/1.1" }
386 391
387 // Other required methods with minimal implementations 392 // Other required methods with minimal implementations
388 @Override Object getAttribute(String name) { return null } 393 @Override Object getAttribute(String name) { return attributes.get(name) }
389 @Override void setAttribute(String name, Object value) {} 394 @Override void setAttribute(String name, Object value) { attributes[name] = value }
390 @Override void removeAttribute(String name) {} 395 @Override void removeAttribute(String name) { attributes.remove(name) }
391 @Override java.util.Enumeration<String> getAttributeNames() { return Collections.enumeration([]) } 396 @Override java.util.Enumeration<String> getAttributeNames() { return Collections.enumeration([]) }
392 @Override String getAuthType() { return null } 397 @Override String getAuthType() { return null }
393 @Override String getRemoteUser() { return remoteUser } 398 @Override String getRemoteUser() { return remoteUser }
......