diff options
Diffstat (limited to 'packages/web/src')
| -rw-r--r-- | packages/web/src/components/Share.tsx | 97 | ||||
| -rw-r--r-- | packages/web/src/components/share.module.css | 17 |
2 files changed, 113 insertions, 1 deletions
diff --git a/packages/web/src/components/Share.tsx b/packages/web/src/components/Share.tsx index a1b49a8de..b6bd7fd0d 100644 --- a/packages/web/src/components/Share.tsx +++ b/packages/web/src/components/Share.tsx @@ -25,6 +25,7 @@ import { IconMagnifyingGlass, IconWrenchScrewdriver, IconDocumentArrowDown, + IconDocumentMagnifyingGlass, } from "./icons" import DiffView from "./DiffView" import CodeBlock from "./CodeBlock" @@ -735,6 +736,100 @@ export default function Share(props: { api: string }) { </div> )} </Match> + {/* Grep tool */} + <Match + when={ + msg.role === "assistant" && + part.type === "tool-invocation" && + part.toolInvocation.toolName === "opencode_grep" && + part + } + > + {(part) => { + const metadata = createMemo(() => + msg.metadata?.tool[part().toolInvocation.toolCallId] + ) + const args = part().toolInvocation.args + const result = part().toolInvocation.state === "result" && part().toolInvocation.result + const matches = metadata()?.matches + + const { pattern, ...rest } = args + + const duration = createMemo(() => + DateTime.fromMillis(metadata()?.time.end || 0).diff( + DateTime.fromMillis(metadata()?.time.start || 0), + ).toMillis(), + ) + + return ( + <div data-section="part" data-part-type="tool-grep"> + <div data-section="decoration"> + <div title="Grep files"> + <IconDocumentMagnifyingGlass + width={18} height={18} + /> + </div> + <div></div> + </div> + <div data-section="content"> + <div data-part-tool-body> + <span data-part-title data-size="md"> + <span data-element-label>Grep</span> + <b>“{pattern}”</b> + </span> + <Show when={Object.keys(rest).length > 0}> + <div data-part-tool-args> + <For each={flattenToolArgs(rest)}> + {([name, value]) => ( + <> + <div></div> + <div>{name}</div> + <div>{value}</div> + </> + )} + </For> + </div> + </Show> + <Switch> + <Match when={matches > 0}> + <div data-part-tool-result> + <ResultsButton + showCopy={matches === 1 + ? "1 match" + : `${matches} matches` + } + hideCopy="Hide matches" + results={results()} + onClick={() => showResults((e) => !e)} + /> + <Show when={results()}> + <TextPart + expand + text={result} + data-size="sm" + data-color="dimmed" + /> + </Show> + </div> + </Match> + <Match when={result}> + <div data-part-tool-result> + <TextPart + expand + text={result} + data-size="sm" + data-color="dimmed" + /> + </div> + </Match> + </Switch> + </div> + <ToolFooter time={duration()} /> + </div> + </div> + ) + }} + </Match> {/* Glob tool */} <Match when={ @@ -762,7 +857,7 @@ export default function Share(props: { api: string }) { return ( <div data-section="part" data-part-type="tool-glob"> <div data-section="decoration"> - <div title="List files"> + <div title="Glob files"> <IconMagnifyingGlass width={18} height={18} /> </div> <div></div> diff --git a/packages/web/src/components/share.module.css b/packages/web/src/components/share.module.css index 6d7f25197..ef4507340 100644 --- a/packages/web/src/components/share.module.css +++ b/packages/web/src/components/share.module.css @@ -332,6 +332,23 @@ } } + [data-part-type="tool-grep"] { + &:not(:has([data-part-tool-args])) + > [data-section="content"] > [data-part-tool-body] { + gap: 0.5rem; + } + [data-part-title] { + display: flex; + align-items: flex-start; + gap: 0.5rem; + + b { + color: var(--sl-color-text); + word-break: break-all; + } + } + } + [data-part-type="tool-read"] { [data-part-tool-result] { [data-part-tool-code] { |
