tweak(ui): bump button heights and align permission prompt layout
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import { For, Show, createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
import { For, Show, createEffect, createMemo, createSignal, on, onCleanup } from "solid-js"
|
||||||
import type { QuestionRequest, Todo } from "@opencode-ai/sdk/v2"
|
import type { QuestionRequest, Todo } from "@opencode-ai/sdk/v2"
|
||||||
import { Button } from "@opencode-ai/ui/button"
|
import { Button } from "@opencode-ai/ui/button"
|
||||||
import { BasicTool } from "@opencode-ai/ui/basic-tool"
|
|
||||||
import { PromptInput } from "@/components/prompt-input"
|
import { PromptInput } from "@/components/prompt-input"
|
||||||
import { QuestionDock } from "@/components/question-dock"
|
import { QuestionDock } from "@/components/question-dock"
|
||||||
import { SessionTodoDock } from "@/components/session-todo-dock"
|
import { SessionTodoDock } from "@/components/session-todo-dock"
|
||||||
@@ -123,63 +122,84 @@ export function SessionPromptDock(props: {
|
|||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={props.permissionRequest()} keyed>
|
<Show when={props.permissionRequest()} keyed>
|
||||||
{(perm) => (
|
{(perm) => {
|
||||||
<div data-component="tool-part-wrapper" data-permission="true" class="mb-3">
|
const toolTitle = () => {
|
||||||
<BasicTool
|
const key = `settings.permissions.tool.${perm.permission}.title`
|
||||||
icon="checklist"
|
const value = props.t(key)
|
||||||
locked
|
if (value === key) return perm.permission
|
||||||
defaultOpen
|
return value
|
||||||
trigger={{
|
}
|
||||||
title: props.t("notification.permission.title"),
|
|
||||||
subtitle:
|
const toolDescription = () => {
|
||||||
perm.permission === "doom_loop"
|
const key = `settings.permissions.tool.${perm.permission}.description`
|
||||||
? props.t("settings.permissions.tool.doom_loop.title")
|
const value = props.t(key)
|
||||||
: perm.permission,
|
if (value === key) return ""
|
||||||
}}
|
return value
|
||||||
>
|
}
|
||||||
<Show when={perm.patterns.length > 0}>
|
|
||||||
<div class="flex flex-col gap-1 py-2 px-3 max-h-40 overflow-y-auto no-scrollbar">
|
return (
|
||||||
<For each={perm.patterns}>
|
<div>
|
||||||
{(pattern) => <code class="text-12-regular text-text-base break-all">{pattern}</code>}
|
<div data-component="question-prompt" data-permission="true">
|
||||||
</For>
|
<div data-slot="question-body">
|
||||||
|
<div data-slot="question-header">
|
||||||
|
<div data-slot="question-header-title">
|
||||||
|
{props.t("notification.permission.title")}{" "}
|
||||||
|
<span class="text-13-regular text-text-weak">{toolTitle()}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-slot="question-content">
|
||||||
|
<Show when={toolDescription()}>
|
||||||
|
<div data-slot="question-hint">{toolDescription()}</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={perm.patterns.length > 0}>
|
||||||
|
<div data-slot="question-options">
|
||||||
|
<For each={perm.patterns}>
|
||||||
|
{(pattern) => (
|
||||||
|
<div class="px-[10px]">
|
||||||
|
<code class="text-12-regular text-text-base break-all">{pattern}</code>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
|
||||||
<Show when={perm.permission === "doom_loop"}>
|
<div data-slot="question-footer">
|
||||||
<div class="text-12-regular text-text-weak pb-2 px-3">
|
<div />
|
||||||
{props.t("settings.permissions.tool.doom_loop.description")}
|
<div data-slot="question-footer-actions">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="normal"
|
||||||
|
onClick={() => props.onDecide("reject")}
|
||||||
|
disabled={props.responding}
|
||||||
|
>
|
||||||
|
{props.t("ui.permission.deny")}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="normal"
|
||||||
|
onClick={() => props.onDecide("always")}
|
||||||
|
disabled={props.responding}
|
||||||
|
>
|
||||||
|
{props.t("ui.permission.allowAlways")}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
size="normal"
|
||||||
|
onClick={() => props.onDecide("once")}
|
||||||
|
disabled={props.responding}
|
||||||
|
>
|
||||||
|
{props.t("ui.permission.allowOnce")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
|
||||||
</BasicTool>
|
|
||||||
<div data-component="permission-prompt">
|
|
||||||
<div data-slot="permission-actions">
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="small"
|
|
||||||
onClick={() => props.onDecide("reject")}
|
|
||||||
disabled={props.responding}
|
|
||||||
>
|
|
||||||
{props.t("ui.permission.deny")}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
size="small"
|
|
||||||
onClick={() => props.onDecide("always")}
|
|
||||||
disabled={props.responding}
|
|
||||||
>
|
|
||||||
{props.t("ui.permission.allowAlways")}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="primary"
|
|
||||||
size="small"
|
|
||||||
onClick={() => props.onDecide("once")}
|
|
||||||
disabled={props.responding}
|
|
||||||
>
|
|
||||||
{props.t("ui.permission.allowOnce")}
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)}
|
}}
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={!props.blocked}>
|
<Show when={!props.blocked}>
|
||||||
|
|||||||
@@ -64,10 +64,6 @@ function EditBody(props: { request: PermissionRequest }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<box flexDirection="column" gap={1}>
|
<box flexDirection="column" gap={1}>
|
||||||
<box flexDirection="row" gap={1} paddingLeft={1}>
|
|
||||||
<text fg={theme.textMuted}>{"→"}</text>
|
|
||||||
<text fg={theme.textMuted}>Edit {normalizePath(filepath())}</text>
|
|
||||||
</box>
|
|
||||||
<Show when={diff()}>
|
<Show when={diff()}>
|
||||||
<scrollbox height="100%">
|
<scrollbox height="100%">
|
||||||
<diff
|
<diff
|
||||||
@@ -91,6 +87,11 @@ function EditBody(props: { request: PermissionRequest }) {
|
|||||||
/>
|
/>
|
||||||
</scrollbox>
|
</scrollbox>
|
||||||
</Show>
|
</Show>
|
||||||
|
<Show when={!diff()}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>No diff provided</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
</box>
|
</box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -194,76 +195,233 @@ export function PermissionPrompt(props: { request: PermissionRequest }) {
|
|||||||
</Match>
|
</Match>
|
||||||
<Match when={store.stage === "permission"}>
|
<Match when={store.stage === "permission"}>
|
||||||
{(() => {
|
{(() => {
|
||||||
|
const info = () => {
|
||||||
|
const permission = props.request.permission
|
||||||
|
const data = input()
|
||||||
|
|
||||||
|
if (permission === "edit") {
|
||||||
|
const raw = props.request.metadata?.filepath
|
||||||
|
const filepath = typeof raw === "string" ? raw : ""
|
||||||
|
return {
|
||||||
|
icon: "→",
|
||||||
|
title: `Edit ${normalizePath(filepath)}`,
|
||||||
|
body: <EditBody request={props.request} />,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "read") {
|
||||||
|
const raw = data.filePath
|
||||||
|
const filePath = typeof raw === "string" ? raw : ""
|
||||||
|
return {
|
||||||
|
icon: "→",
|
||||||
|
title: `Read ${normalizePath(filePath)}`,
|
||||||
|
body: (
|
||||||
|
<Show when={filePath}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Path: " + normalizePath(filePath)}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "glob") {
|
||||||
|
const pattern = typeof data.pattern === "string" ? data.pattern : ""
|
||||||
|
return {
|
||||||
|
icon: "✱",
|
||||||
|
title: `Glob "${pattern}"`,
|
||||||
|
body: (
|
||||||
|
<Show when={pattern}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Pattern: " + pattern}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "grep") {
|
||||||
|
const pattern = typeof data.pattern === "string" ? data.pattern : ""
|
||||||
|
return {
|
||||||
|
icon: "✱",
|
||||||
|
title: `Grep "${pattern}"`,
|
||||||
|
body: (
|
||||||
|
<Show when={pattern}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Pattern: " + pattern}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "list") {
|
||||||
|
const raw = data.path
|
||||||
|
const dir = typeof raw === "string" ? raw : ""
|
||||||
|
return {
|
||||||
|
icon: "→",
|
||||||
|
title: `List ${normalizePath(dir)}`,
|
||||||
|
body: (
|
||||||
|
<Show when={dir}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Path: " + normalizePath(dir)}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "bash") {
|
||||||
|
const title =
|
||||||
|
typeof data.description === "string" && data.description ? data.description : "Shell command"
|
||||||
|
const command = typeof data.command === "string" ? data.command : ""
|
||||||
|
return {
|
||||||
|
icon: "#",
|
||||||
|
title,
|
||||||
|
body: (
|
||||||
|
<Show when={command}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.text}>{"$ " + command}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "task") {
|
||||||
|
const type = typeof data.subagent_type === "string" ? data.subagent_type : "Unknown"
|
||||||
|
const desc = typeof data.description === "string" ? data.description : ""
|
||||||
|
return {
|
||||||
|
icon: "#",
|
||||||
|
title: `${Locale.titlecase(type)} Task`,
|
||||||
|
body: (
|
||||||
|
<Show when={desc}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.text}>{"◉ " + desc}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "webfetch") {
|
||||||
|
const url = typeof data.url === "string" ? data.url : ""
|
||||||
|
return {
|
||||||
|
icon: "%",
|
||||||
|
title: `WebFetch ${url}`,
|
||||||
|
body: (
|
||||||
|
<Show when={url}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"URL: " + url}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "websearch") {
|
||||||
|
const query = typeof data.query === "string" ? data.query : ""
|
||||||
|
return {
|
||||||
|
icon: "◈",
|
||||||
|
title: `Exa Web Search "${query}"`,
|
||||||
|
body: (
|
||||||
|
<Show when={query}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Query: " + query}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "codesearch") {
|
||||||
|
const query = typeof data.query === "string" ? data.query : ""
|
||||||
|
return {
|
||||||
|
icon: "◇",
|
||||||
|
title: `Exa Code Search "${query}"`,
|
||||||
|
body: (
|
||||||
|
<Show when={query}>
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Query: " + query}</text>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "external_directory") {
|
||||||
|
const meta = props.request.metadata ?? {}
|
||||||
|
const parent = typeof meta["parentDir"] === "string" ? meta["parentDir"] : undefined
|
||||||
|
const filepath = typeof meta["filepath"] === "string" ? meta["filepath"] : undefined
|
||||||
|
const pattern = props.request.patterns?.[0]
|
||||||
|
const derived =
|
||||||
|
typeof pattern === "string" ? (pattern.includes("*") ? path.dirname(pattern) : pattern) : undefined
|
||||||
|
|
||||||
|
const raw = parent ?? filepath ?? derived
|
||||||
|
const dir = normalizePath(raw)
|
||||||
|
const patterns = (props.request.patterns ?? []).filter((p): p is string => typeof p === "string")
|
||||||
|
|
||||||
|
return {
|
||||||
|
icon: "←",
|
||||||
|
title: `Access external directory ${dir}`,
|
||||||
|
body: (
|
||||||
|
<Show when={patterns.length > 0}>
|
||||||
|
<box paddingLeft={1} gap={1}>
|
||||||
|
<text fg={theme.textMuted}>Patterns</text>
|
||||||
|
<box>
|
||||||
|
<For each={patterns}>{(p) => <text fg={theme.text}>{"- " + p}</text>}</For>
|
||||||
|
</box>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permission === "doom_loop") {
|
||||||
|
return {
|
||||||
|
icon: "⟳",
|
||||||
|
title: "Continue after repeated failures",
|
||||||
|
body: (
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>This keeps the session running despite repeated failures.</text>
|
||||||
|
</box>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
icon: "⚙",
|
||||||
|
title: `Call tool ${permission}`,
|
||||||
|
body: (
|
||||||
|
<box paddingLeft={1}>
|
||||||
|
<text fg={theme.textMuted}>{"Tool: " + permission}</text>
|
||||||
|
</box>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const current = info()
|
||||||
|
|
||||||
|
const header = () => (
|
||||||
|
<box flexDirection="column" gap={0}>
|
||||||
|
<box flexDirection="row" gap={1} flexShrink={0}>
|
||||||
|
<text fg={theme.warning}>{"△"}</text>
|
||||||
|
<text fg={theme.text}>Permission required</text>
|
||||||
|
</box>
|
||||||
|
<box flexDirection="row" gap={1} paddingLeft={2} flexShrink={0}>
|
||||||
|
<text fg={theme.textMuted} flexShrink={0}>
|
||||||
|
{current.icon}
|
||||||
|
</text>
|
||||||
|
<text fg={theme.text}>{current.title}</text>
|
||||||
|
</box>
|
||||||
|
</box>
|
||||||
|
)
|
||||||
|
|
||||||
const body = (
|
const body = (
|
||||||
<Prompt
|
<Prompt
|
||||||
title="Permission required"
|
title="Permission required"
|
||||||
body={
|
header={header()}
|
||||||
<Switch>
|
body={current.body}
|
||||||
<Match when={props.request.permission === "edit"}>
|
|
||||||
<EditBody request={props.request} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "read"}>
|
|
||||||
<TextBody icon="→" title={`Read ` + normalizePath(input().filePath as string)} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "glob"}>
|
|
||||||
<TextBody icon="✱" title={`Glob "` + (input().pattern ?? "") + `"`} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "grep"}>
|
|
||||||
<TextBody icon="✱" title={`Grep "` + (input().pattern ?? "") + `"`} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "list"}>
|
|
||||||
<TextBody icon="→" title={`List ` + normalizePath(input().path as string)} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "bash"}>
|
|
||||||
<TextBody
|
|
||||||
icon="#"
|
|
||||||
title={(input().description as string) ?? ""}
|
|
||||||
description={("$ " + input().command) as string}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "task"}>
|
|
||||||
<TextBody
|
|
||||||
icon="#"
|
|
||||||
title={`${Locale.titlecase((input().subagent_type as string) ?? "Unknown")} Task`}
|
|
||||||
description={"◉ " + input().description}
|
|
||||||
/>
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "webfetch"}>
|
|
||||||
<TextBody icon="%" title={`WebFetch ` + (input().url ?? "")} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "websearch"}>
|
|
||||||
<TextBody icon="◈" title={`Exa Web Search "` + (input().query ?? "") + `"`} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "codesearch"}>
|
|
||||||
<TextBody icon="◇" title={`Exa Code Search "` + (input().query ?? "") + `"`} />
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "external_directory"}>
|
|
||||||
{(() => {
|
|
||||||
const meta = props.request.metadata ?? {}
|
|
||||||
const parent = typeof meta["parentDir"] === "string" ? meta["parentDir"] : undefined
|
|
||||||
const filepath = typeof meta["filepath"] === "string" ? meta["filepath"] : undefined
|
|
||||||
const pattern = props.request.patterns?.[0]
|
|
||||||
const derived =
|
|
||||||
typeof pattern === "string"
|
|
||||||
? pattern.includes("*")
|
|
||||||
? path.dirname(pattern)
|
|
||||||
: pattern
|
|
||||||
: undefined
|
|
||||||
|
|
||||||
const raw = parent ?? filepath ?? derived
|
|
||||||
const dir = normalizePath(raw)
|
|
||||||
|
|
||||||
return <TextBody icon="←" title={`Access external directory ` + dir} />
|
|
||||||
})()}
|
|
||||||
</Match>
|
|
||||||
<Match when={props.request.permission === "doom_loop"}>
|
|
||||||
<TextBody icon="⟳" title="Continue after repeated failures" />
|
|
||||||
</Match>
|
|
||||||
<Match when={true}>
|
|
||||||
<TextBody icon="⚙" title={`Call tool ` + props.request.permission} />
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
}
|
|
||||||
options={{ once: "Allow once", always: "Allow always", reject: "Reject" }}
|
options={{ once: "Allow once", always: "Allow always", reject: "Reject" }}
|
||||||
escapeKey="reject"
|
escapeKey="reject"
|
||||||
fullscreen
|
fullscreen
|
||||||
@@ -372,6 +530,7 @@ function RejectPrompt(props: { onConfirm: (message: string) => void; onCancel: (
|
|||||||
|
|
||||||
function Prompt<const T extends Record<string, string>>(props: {
|
function Prompt<const T extends Record<string, string>>(props: {
|
||||||
title: string
|
title: string
|
||||||
|
header?: JSX.Element
|
||||||
body: JSX.Element
|
body: JSX.Element
|
||||||
options: T
|
options: T
|
||||||
escapeKey?: keyof T
|
escapeKey?: keyof T
|
||||||
@@ -445,10 +604,19 @@ function Prompt<const T extends Record<string, string>>(props: {
|
|||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<box gap={1} paddingLeft={1} paddingRight={3} paddingTop={1} paddingBottom={1} flexGrow={1}>
|
<box gap={1} paddingLeft={1} paddingRight={3} paddingTop={1} paddingBottom={1} flexGrow={1}>
|
||||||
<box flexDirection="row" gap={1} paddingLeft={1} flexShrink={0}>
|
<Show
|
||||||
<text fg={theme.warning}>{"△"}</text>
|
when={props.header}
|
||||||
<text fg={theme.text}>{props.title}</text>
|
fallback={
|
||||||
</box>
|
<box flexDirection="row" gap={1} paddingLeft={1} flexShrink={0}>
|
||||||
|
<text fg={theme.warning}>{"△"}</text>
|
||||||
|
<text fg={theme.text}>{props.title}</text>
|
||||||
|
</box>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<box paddingLeft={1} flexShrink={0}>
|
||||||
|
{props.header}
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
{props.body}
|
{props.body}
|
||||||
</box>
|
</box>
|
||||||
<box
|
<box
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&[data-size="small"] {
|
&[data-size="small"] {
|
||||||
height: 22px;
|
height: 24px;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
&[data-icon] {
|
&[data-icon] {
|
||||||
padding: 0 12px 0 4px;
|
padding: 0 12px 0 4px;
|
||||||
@@ -129,8 +129,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&[data-size="normal"] {
|
&[data-size="normal"] {
|
||||||
height: 24px;
|
height: 28px;
|
||||||
line-height: 24px;
|
line-height: 28px;
|
||||||
padding: 0 6px;
|
padding: 0 6px;
|
||||||
&[data-icon] {
|
&[data-icon] {
|
||||||
padding: 0 12px 0 4px;
|
padding: 0 12px 0 4px;
|
||||||
|
|||||||
@@ -745,6 +745,11 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
[data-component="button"] {
|
||||||
|
padding-left: 12px;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,6 +761,22 @@
|
|||||||
min-height: 0;
|
min-height: 0;
|
||||||
max-height: var(--question-prompt-max-height, 100dvh);
|
max-height: var(--question-prompt-max-height, 100dvh);
|
||||||
|
|
||||||
|
&[data-permission="true"] {
|
||||||
|
[data-slot="question-options"] {
|
||||||
|
code {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: var(--line-height-large);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="question-footer-actions"] {
|
||||||
|
[data-component="button"] {
|
||||||
|
padding-left: 12px;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[data-slot="question-body"] {
|
[data-slot="question-body"] {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -891,13 +891,13 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
|
|||||||
<Show when={showPermission() && permission()}>
|
<Show when={showPermission() && permission()}>
|
||||||
<div data-component="permission-prompt">
|
<div data-component="permission-prompt">
|
||||||
<div data-slot="permission-actions">
|
<div data-slot="permission-actions">
|
||||||
<Button variant="ghost" size="small" onClick={() => respond("reject")}>
|
<Button variant="ghost" size="normal" onClick={() => respond("reject")}>
|
||||||
{i18n.t("ui.permission.deny")}
|
{i18n.t("ui.permission.deny")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="secondary" size="small" onClick={() => respond("always")}>
|
<Button variant="secondary" size="normal" onClick={() => respond("always")}>
|
||||||
{i18n.t("ui.permission.allowAlways")}
|
{i18n.t("ui.permission.allowAlways")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="primary" size="small" onClick={() => respond("once")}>
|
<Button variant="primary" size="normal" onClick={() => respond("once")}>
|
||||||
{i18n.t("ui.permission.allowOnce")}
|
{i18n.t("ui.permission.allowOnce")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user