| 401 | r.UI.ClearModal() |
| 402 | } |
| 403 | r.Flush(true) |
| 404 | return answer |
| 405 | } |
| 406 | |
| 407 | func (r *UiRuntime) BuildPermissionModalState(event UiEvent) map[string]any { |
| 408 | backendRisk := stringFromAny(event.Metadata["risk"]) |
| 409 | if backendRisk == "" { |
| 410 | if truthy(event.Metadata["dangerous"]) { |
| 411 | backendRisk = "high" |
| 412 | } else { |
| 413 | backendRisk = "normal" |
| 414 | } |
| 415 | } |
| 416 | displayRisk := luminacli.TranslateBackendRiskLevel(backendRisk) |
| 417 | toolName := "" |
| 418 | targetSummary := "" |
| 419 | summaryLines := []string{} |
| 420 | kind := "permission_request" |
| 421 | if truthy(event.Metadata["sandbox_unavailable"]) { |
| 422 | toolName = "run_shell" |
| 423 | targetSummary = firstNonEmpty(stringFromAny(event.Metadata["sandbox_backend"]), "OS sandbox") |
| 424 | summaryLines = nonEmptyStrings([]string{ |
| 425 | stringFromAny(event.Metadata["reason"]), |
| 426 | truncateString(stringFromAny(event.Metadata["command"]), 200), |
| 427 | }) |
| 428 | kind = "sandbox_unavailable_permission" |
| 429 | } else if tc, ok := event.Metadata["tool_call"].(coretools.ToolCall); ok { |
| 430 | toolName = tc.Name |
| 431 | targetSummary = firstNonEmpty(stringFromAny(tc.Input["file_path"]), stringFromAny(tc.Input["command"]), stringFromAny(tc.Input["pattern"])) |
| 432 | switch toolName { |
| 433 | case "run_shell": |
| 434 | summaryLines = []string{truncateString(stringFromAny(tc.Input["command"]), 200)} |
| 435 | case "write_file", "edit_file": |
| 436 | summaryLines = []string{truncateString(stringFromAny(tc.Input["content"]), 200)} |
| 437 | } |
| 438 | kind = "tool_permission" |
| 439 | } else if tcPtr, ok := event.Metadata["tool_call"].(*coretools.ToolCall); ok && tcPtr != nil { |
| 440 | copied := *tcPtr |
| 441 | event.Metadata["tool_call"] = copied |
| 442 | return r.BuildPermissionModalState(event) |
| 443 | } else if command, ok := skillShellCommand(event.Metadata["skill_shell_request"]); ok { |
| 444 | toolName = "skill-shell" |
| 445 | targetSummary = command |
| 446 | summaryLines = []string{truncateString(targetSummary, 200)} |
| 447 | kind = "skill_shell_permission" |
| 448 | } else if req, ok := normalizeMCPTrustRequest(event.Metadata["mcp_trust_request"]); ok { |
| 449 | toolName = "mcp-project-trust" |
| 450 | targetSummary = FormatMCPTrustTarget(req) |
| 451 | summaryLines = []string{truncateString(targetSummary, 200)} |
| 452 | kind = "mcp_trust_permission" |
| 453 | } else if req, ok := normalizeSandboxSetupRequest(event.Metadata["sandbox_setup_request"]); ok { |
| 454 | toolName = "wsl-sandbox-setup" |
| 455 | targetSummary = sandboxSetupTarget(req, event.Metadata["tool_call"]) |