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 (
{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),
}
}