diff options
| author | Jay V <[email protected]> | 2025-07-15 17:12:09 -0400 |
|---|---|---|
| committer | Jay V <[email protected]> | 2025-07-15 17:47:22 -0400 |
| commit | 749e7838a444d6f2f846bd7e6e008edae25b0c69 (patch) | |
| tree | 2600d24c2bf539893da6d9977e44293e835d9294 /packages/web/src/components/share | |
| parent | 73b46c2bf9090094a5e31db62ef16fe1b08bb01e (diff) | |
| download | opencode-749e7838a444d6f2f846bd7e6e008edae25b0c69.tar.gz opencode-749e7838a444d6f2f846bd7e6e008edae25b0c69.zip | |
docs: share page task tool
Diffstat (limited to 'packages/web/src/components/share')
4 files changed, 76 insertions, 38 deletions
diff --git a/packages/web/src/components/share/content-markdown.module.css b/packages/web/src/components/share/content-markdown.module.css index 0e6b83620..3e38ddf02 100644 --- a/packages/web/src/components/share/content-markdown.module.css +++ b/packages/web/src/components/share/content-markdown.module.css @@ -1,21 +1,13 @@ .root { - border: 1px solid var(--sl-color-blue-high); - padding: 0.5rem calc(0.5rem + 3px); - border-radius: 0.25rem; display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; - align-self: flex-start; - - &[data-highlight="true"] { - background-color: var(--sl-color-blue-low); - } [data-slot="expand-button"] { flex: 0 0 auto; padding: 2px 0; - font-size: 0.75rem; + font-size: 0.857em; } [data-slot="markdown"] { @@ -29,7 +21,7 @@ display: block; } - font-size: 0.875rem; + font-size: 1em; line-height: 1.5; p, @@ -61,7 +53,7 @@ h4, h5, h6 { - font-size: 0.875rem; + font-size: 1em; font-weight: 600; margin-bottom: 0.5rem; } @@ -75,7 +67,7 @@ background-color: var(--sl-color-bg-surface) !important; padding: 0.5rem 0.75rem; line-height: 1.6; - font-size: 0.75rem; + font-size: 0.857em; white-space: pre-wrap; word-break: break-word; diff --git a/packages/web/src/components/share/content-markdown.tsx b/packages/web/src/components/share/content-markdown.tsx index f79271296..a083872e7 100644 --- a/packages/web/src/components/share/content-markdown.tsx +++ b/packages/web/src/components/share/content-markdown.tsx @@ -1,10 +1,10 @@ -import style from "./content-markdown.module.css" -import { createResource, createSignal } from "solid-js" -import { createOverflow } from "./common" -import { transformerNotationDiff } from "@shikijs/transformers" import { marked } from "marked" -import markedShiki from "marked-shiki" import { codeToHtml } from "shiki" +import markedShiki from "marked-shiki" +import { createOverflow } from "./common" +import { createResource, createSignal } from "solid-js" +import { transformerNotationDiff } from "@shikijs/transformers" +import style from "./content-markdown.module.css" const markedWithShiki = marked.use( markedShiki({ diff --git a/packages/web/src/components/share/part.module.css b/packages/web/src/components/share/part.module.css index 5ffb83f6b..17018fa02 100644 --- a/packages/web/src/components/share/part.module.css +++ b/packages/web/src/components/share/part.module.css @@ -103,7 +103,7 @@ [data-component="content"] { flex: 1 1 auto; min-width: 0; - padding: 0 0 0.375rem; + padding: 0 0 1rem; display: flex; flex-direction: column; gap: 1rem; @@ -135,6 +135,14 @@ gap: 1rem; flex-grow: 1; max-width: var(--md-tool-width); + + & > [data-component="assistant-text-markdown"] { + align-self: flex-start; + font-size: 0.875rem; + border: 1px solid var(--sl-color-blue-high); + padding: 0.5rem calc(0.5rem + 3px); + border-radius: 0.25rem; + } } [data-component="step-start"] { @@ -239,6 +247,24 @@ max-width: var(--lg-tool-width); } } + &[data-tool="task"] { + [data-component="tool-input"] { + font-size: 0.75rem; + line-height: 1.5; + max-width: var(--sm-tool-width); + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; + } + [data-component="tool-output"] { + max-width: var(--sm-tool-width); + font-size: 0.75rem; + border: 1px solid var(--sl-color-divider); + padding: 0.5rem calc(0.5rem + 3px); + border-radius: 0.25rem; + } + } } [data-component="tool-title"] { diff --git a/packages/web/src/components/share/part.tsx b/packages/web/src/components/share/part.tsx index fcfa8bec4..4a9320e6d 100644 --- a/packages/web/src/components/share/part.tsx +++ b/packages/web/src/components/share/part.tsx @@ -19,25 +19,25 @@ import { IconMagnifyingGlass, IconDocumentMagnifyingGlass, } from "../icons" -import { IconMeta, IconOpenAI, IconGemini, IconAnthropic } from "../icons/custom" -import { formatDuration } from "../share/common" +import { IconMeta, IconRobot, IconOpenAI, IconGemini, IconAnthropic } from "../icons/custom" import { ContentCode } from "./content-code" import { ContentDiff } from "./content-diff" import { ContentText } from "./content-text" +import { ContentBash } from "./content-bash" import { ContentError } from "./content-error" +import { formatDuration } from "../share/common" import { ContentMarkdown } from "./content-markdown" -import { ContentBash } from "./content-bash" import type { MessageV2 } from "opencode/session/message-v2" import type { Diagnostic } from "vscode-languageserver-types" import styles from "./part.module.css" -const MIN_DURATION = 2 +const MIN_DURATION = 2000 export interface PartProps { index: number message: MessageV2.Info - part: MessageV2.AssistantPart | MessageV2.UserPart + part: MessageV2.Part last: boolean } @@ -114,7 +114,7 @@ export function Part(props: PartProps) { <IconGlobeAlt width={18} height={18} /> </Match> <Match when={props.part.type === "tool" && props.part.tool === "task"}> - <IconRectangleStack width={18} height={18} /> + <IconRobot width={18} height={18} /> </Match> <Match when={true}> <IconSparkles width={18} height={18} /> @@ -131,12 +131,13 @@ export function Part(props: PartProps) { {props.message.role === "user" && props.part.type === "text" && ( <div data-component="user-text"> <ContentText text={props.part.text} expand={props.last} /> - <Spacer /> </div> )} {props.message.role === "assistant" && props.part.type === "text" && ( <div data-component="assistant-text"> - <ContentMarkdown expand={props.last} text={props.part.text} /> + <div data-component="assistant-text-markdown"> + <ContentMarkdown expand={props.last} text={props.part.text} /> + </div> {props.last && props.message.role === "assistant" && props.message.time.completed && ( <Footer title={DateTime.fromMillis(props.message.time.completed).toLocaleString( @@ -146,7 +147,6 @@ export function Part(props: PartProps) { {DateTime.fromMillis(props.message.time.completed).toLocaleString(DateTime.DATETIME_MED)} </Footer> )} - <Spacer /> </div> )} {props.message.role === "user" && props.part.type === "file" && ( @@ -245,6 +245,14 @@ export function Part(props: PartProps) { state={props.part.state} /> </Match> + <Match when={props.part.tool === "task"}> + <TaskTool + id={props.part.id} + tool={props.part.tool} + message={props.message} + state={props.part.state} + /> + </Match> <Match when={true}> <FallbackTool message={props.message} @@ -256,11 +264,10 @@ export function Part(props: PartProps) { </Switch> </div> <ToolFooter - time={ - DateTime.fromMillis(props.part.state.time.start) - .diff(DateTime.fromMillis(props.part.state.time.end)) - .toMillis() - } /> + time={DateTime.fromMillis(props.part.state.time.end) + .diff(DateTime.fromMillis(props.part.state.time.start)) + .toMillis()} + /> </> )} </div> @@ -636,12 +643,25 @@ function Footer(props: ParentProps<{ title: string }>) { } function ToolFooter(props: { time: number }) { - return props.time > MIN_DURATION ? ( - <Footer title={`${props.time}ms`}> - {formatDuration(props.time)} - </Footer> - ) : ( - <Spacer /> + return props.time > MIN_DURATION && <Footer title={`${props.time}ms`}>{formatDuration(props.time)}</Footer> +} + +function TaskTool(props: ToolProps) { + return ( + <> + <div data-component="tool-title"> + <span data-slot="name">Task</span> + <span data-slot="target">{props.state.input.description}</span> + </div> + <div data-component="tool-input"> + “{props.state.input.prompt}” + </div> + <ResultsButton showCopy="Show output" hideCopy="Hide output"> + <div data-component="tool-output"> + <ContentMarkdown expand text={props.state.output} /> + </div> + </ResultsButton> + </> ) } |
