diff --git a/src/components/chat/permission-dialog.tsx b/src/components/chat/permission-dialog.tsx index a3934ba..8dd3bdc 100644 --- a/src/components/chat/permission-dialog.tsx +++ b/src/components/chat/permission-dialog.tsx @@ -9,6 +9,8 @@ import { ListTodo, Compass, FileText, + Globe, + Search, } from "lucide-react" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" @@ -43,13 +45,15 @@ export function PermissionDialog({ parsed.planEntries.length > 0 || Boolean(parsed.planExplanation) const hasPlanMarkdown = Boolean(parsed.planMarkdown) const hasAllowedPrompts = parsed.allowedPrompts.length > 0 + const hasWeb = Boolean(parsed.url) || Boolean(parsed.query) const hasStructured = Boolean(parsed.command) || hasFileChanges || hasPlan || hasPlanMarkdown || hasAllowedPrompts || - Boolean(parsed.modeTarget) + Boolean(parsed.modeTarget) || + hasWeb return (
@@ -189,6 +193,32 @@ export function PermissionDialog({
)} + {hasWeb && ( +
+ {parsed.url && ( +
+ + + {parsed.url} + +
+ )} + {parsed.query && ( +
+ + + {parsed.query} + +
+ )} + {parsed.prompt && ( +
+ {parsed.prompt} +
+ )} +
+ )} + {!hasStructured && (
             {parsed.jsonPreview}
diff --git a/src/contexts/acp-connections-context.tsx b/src/contexts/acp-connections-context.tsx
index 8ee0010..d45dae1 100644
--- a/src/contexts/acp-connections-context.tsx
+++ b/src/contexts/acp-connections-context.tsx
@@ -242,7 +242,34 @@ function serializePermissionToolCall(toolCall: unknown): string | null {
   const record = asRecord(toolCall)
   if (!record) return null
   try {
-    return JSON.stringify(record)
+    // Extract the actual tool input from the nested rawInput/raw_input field
+    // rather than serializing the entire permission wrapper (which includes
+    // internal fields like content, kind, title, toolCallId).
+    const nestedInput = record.rawInput ?? record.raw_input
+    if (nestedInput !== undefined && nestedInput !== null) {
+      if (typeof nestedInput === "string") return nestedInput
+      return JSON.stringify(nestedInput)
+    }
+    // Fallback: strip wrapper-only fields to avoid rendering internal
+    // permission structure as raw text.
+    const wrapperKeys = new Set([
+      "content",
+      "kind",
+      "title",
+      "toolCallId",
+      "tool_call_id",
+      "callId",
+      "call_id",
+      "rawInput",
+      "raw_input",
+    ])
+    const rest: Record = {}
+    for (const [k, v] of Object.entries(record)) {
+      if (!wrapperKeys.has(k)) rest[k] = v
+    }
+    return Object.keys(rest).length > 0
+      ? JSON.stringify(rest)
+      : JSON.stringify(record)
   } catch {
     return null
   }
diff --git a/src/lib/permission-request.ts b/src/lib/permission-request.ts
index 57403b9..d98f055 100644
--- a/src/lib/permission-request.ts
+++ b/src/lib/permission-request.ts
@@ -38,6 +38,9 @@ export interface ParsedPermissionToolCall {
   planMarkdown: string | null
   allowedPrompts: PermissionAllowedPrompt[]
   modeTarget: string | null
+  url: string | null
+  query: string | null
+  prompt: string | null
   jsonPreview: string
 }
 
@@ -675,6 +678,13 @@ export function parsePermissionToolCall(
       "targetMode",
     ]) ?? null
 
+  const url =
+    pickString(rawInputObj, ["url"]) ?? pickString(toolCallObj, ["url"])
+  const query =
+    pickString(rawInputObj, ["query"]) ?? pickString(toolCallObj, ["query"])
+  const prompt =
+    pickString(rawInputObj, ["prompt"]) ?? pickString(toolCallObj, ["prompt"])
+
   const title =
     pickString(toolCallObj, ["title", "tool_name", "toolName", "name"]) ??
     formatFallbackTitle(normalizedKind)
@@ -693,6 +703,9 @@ export function parsePermissionToolCall(
     planMarkdown,
     allowedPrompts,
     modeTarget,
+    url,
+    query,
+    prompt,
     jsonPreview: stringifyJson(toolCallObj ?? toolCall),
   }
 }