summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ui/src')
-rw-r--r--packages/ui/src/components/message-part.tsx32
-rw-r--r--packages/ui/src/components/message-progress.tsx21
-rw-r--r--packages/ui/src/components/session-review.tsx7
-rw-r--r--packages/ui/src/components/session-turn.tsx36
-rw-r--r--packages/ui/src/context/diff.tsx13
-rw-r--r--packages/ui/src/context/index.ts1
6 files changed, 34 insertions, 76 deletions
diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx
index a0e6e91b6..2da4387fd 100644
--- a/packages/ui/src/components/message-part.tsx
+++ b/packages/ui/src/components/message-part.tsx
@@ -1,4 +1,4 @@
-import { Component, createMemo, For, Match, Show, Switch, ValidComponent } from "solid-js"
+import { Component, createMemo, For, Match, Show, Switch } from "solid-js"
import { Dynamic } from "solid-js/web"
import {
AssistantMessage,
@@ -8,6 +8,7 @@ import {
ToolPart,
UserMessage,
} from "@opencode-ai/sdk"
+import { useDiffComponent } from "../context/diff"
import { BasicTool } from "./basic-tool"
import { GenericTool } from "./basic-tool"
import { Card } from "./card"
@@ -22,14 +23,12 @@ import { unwrap } from "solid-js/store"
export interface MessageProps {
message: MessageType
parts: PartType[]
- diffComponent: ValidComponent
sanitize?: RegExp
}
export interface MessagePartProps {
part: PartType
message: MessageType
- diffComponent: ValidComponent
hideDetails?: boolean
sanitize?: RegExp
}
@@ -54,7 +53,6 @@ export function Message(props: MessageProps) {
message={assistantMessage() as AssistantMessage}
parts={props.parts}
sanitize={props.sanitize}
- diffComponent={props.diffComponent}
/>
)}
</Match>
@@ -62,12 +60,7 @@ export function Message(props: MessageProps) {
)
}
-export function AssistantMessageDisplay(props: {
- message: AssistantMessage
- parts: PartType[]
- sanitize?: RegExp
- diffComponent: ValidComponent
-}) {
+export function AssistantMessageDisplay(props: { message: AssistantMessage; parts: PartType[]; sanitize?: RegExp }) {
const filteredParts = createMemo(() => {
return props.parts?.filter((x) => {
if (x.type === "reasoning") return false
@@ -75,11 +68,7 @@ export function AssistantMessageDisplay(props: {
})
})
return (
- <For each={filteredParts()}>
- {(part) => (
- <Part part={part} message={props.message} sanitize={props.sanitize} diffComponent={props.diffComponent} />
- )}
- </For>
+ <For each={filteredParts()}>{(part) => <Part part={part} message={props.message} sanitize={props.sanitize} />}</For>
)
}
@@ -98,13 +87,7 @@ export function Part(props: MessagePartProps) {
const part = createMemo(() => sanitizePart(unwrap(props.part), props.sanitize))
return (
<Show when={component()}>
- <Dynamic
- component={component()}
- part={part()}
- message={props.message}
- diffComponent={props.diffComponent}
- hideDetails={props.hideDetails}
- />
+ <Dynamic component={component()} part={part()} message={props.message} hideDetails={props.hideDetails} />
</Show>
)
}
@@ -113,7 +96,6 @@ export interface ToolProps {
input: Record<string, any>
metadata: Record<string, any>
tool: string
- diffComponent: ValidComponent
output?: string
hideDetails?: boolean
}
@@ -180,7 +162,6 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
component={render}
input={input}
tool={part.tool}
- diffComponent={props.diffComponent}
metadata={metadata}
output={part.state.status === "completed" ? part.state.output : undefined}
hideDetails={props.hideDetails}
@@ -356,6 +337,7 @@ ToolRegistry.register({
ToolRegistry.register({
name: "edit",
render(props) {
+ const diffComponent = useDiffComponent()
return (
<BasicTool
icon="code-lines"
@@ -381,7 +363,7 @@ ToolRegistry.register({
<Show when={props.metadata.filediff}>
<div data-component="edit-content">
<Dynamic
- component={props.diffComponent}
+ component={diffComponent}
before={{
name: getFilename(props.metadata.filediff.path),
contents: props.metadata.filediff.before,
diff --git a/packages/ui/src/components/message-progress.tsx b/packages/ui/src/components/message-progress.tsx
index afd7f754a..bbcdd3096 100644
--- a/packages/ui/src/components/message-progress.tsx
+++ b/packages/ui/src/components/message-progress.tsx
@@ -1,15 +1,4 @@
-import {
- For,
- JSXElement,
- Match,
- Show,
- Switch,
- ValidComponent,
- createEffect,
- createMemo,
- createSignal,
- onCleanup,
-} from "solid-js"
+import { For, JSXElement, Match, Show, Switch, createEffect, createMemo, createSignal, onCleanup } from "solid-js"
import { Part } from "./message-part"
import { Spinner } from "./spinner"
import { useData } from "../context/data"
@@ -17,7 +6,6 @@ import type { AssistantMessage as AssistantMessageType, ToolPart } from "@openco
export interface MessageProgressProps {
assistantMessages: () => AssistantMessageType[]
- diffComponent: ValidComponent
done?: boolean
}
@@ -172,12 +160,7 @@ export function MessageProgress(props: MessageProgressProps) {
)
return (
<div data-slot="message-progress-item">
- <Part
- message={message()!}
- part={part}
- sanitize={sanitizer()}
- diffComponent={props.diffComponent}
- />
+ <Part message={message()!} part={part} sanitize={sanitizer()} />
</div>
)
}}
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index ea5871b95..6dbaaec18 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -4,8 +4,9 @@ import { DiffChanges } from "./diff-changes"
import { FileIcon } from "./file-icon"
import { Icon } from "./icon"
import { StickyAccordionHeader } from "./sticky-accordion-header"
+import { useDiffComponent } from "../context/diff"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
-import { For, Match, Show, Switch, ValidComponent, type JSX } from "solid-js"
+import { For, Match, Show, Switch, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
import { type FileDiff } from "@opencode-ai/sdk"
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
@@ -18,10 +19,10 @@ export interface SessionReviewProps {
classes?: { root?: string; header?: string; container?: string }
actions?: JSX.Element
diffs: (FileDiff & { preloaded?: PreloadMultiFileDiffResult<any> })[]
- diffComponent: ValidComponent
}
export const SessionReview = (props: SessionReviewProps) => {
+ const diffComponent = useDiffComponent()
const [store, setStore] = createStore({
open: props.diffs.map((d) => d.file),
})
@@ -98,7 +99,7 @@ export const SessionReview = (props: SessionReviewProps) => {
</StickyAccordionHeader>
<Accordion.Content data-slot="session-review-accordion-content">
<Dynamic
- component={props.diffComponent}
+ component={diffComponent}
preloadedDiff={diff.preloaded}
diffStyle={props.split ? "split" : "unified"}
before={{
diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx
index 963713a22..44ecc3a14 100644
--- a/packages/ui/src/components/session-turn.tsx
+++ b/packages/ui/src/components/session-turn.tsx
@@ -1,19 +1,9 @@
import { AssistantMessage } from "@opencode-ai/sdk"
import { useData } from "../context"
+import { useDiffComponent } from "../context/diff"
import { Binary } from "@opencode-ai/util/binary"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
-import {
- createEffect,
- createMemo,
- createSignal,
- For,
- Match,
- onMount,
- ParentProps,
- Show,
- Switch,
- ValidComponent,
-} from "solid-js"
+import { createEffect, createMemo, createSignal, For, Match, onMount, ParentProps, Show, Switch } from "solid-js"
import { DiffChanges } from "./diff-changes"
import { Typewriter } from "./typewriter"
import { Message } from "./message-part"
@@ -36,10 +26,10 @@ export function SessionTurn(
content?: string
container?: string
}
- diffComponent: ValidComponent
}>,
) {
const data = useData()
+ const diffComponent = useDiffComponent()
const match = Binary.search(data.store.session, props.sessionID, (s) => s.id)
if (!match.found) throw new Error(`Session ${props.sessionID} not found`)
@@ -129,7 +119,7 @@ export function SessionTurn(
</div>
</div>
<div data-slot="session-turn-message-content">
- <Message message={msg()} parts={parts()} sanitize={sanitizer()} diffComponent={props.diffComponent} />
+ <Message message={msg()} parts={parts()} sanitize={sanitizer()} />
</div>
{/* Summary */}
<Show when={completed()}>
@@ -180,7 +170,7 @@ export function SessionTurn(
</StickyAccordionHeader>
<Accordion.Content data-slot="session-turn-accordion-content">
<Dynamic
- component={props.diffComponent}
+ component={diffComponent}
before={{
name: diff.file!,
contents: diff.before!,
@@ -206,11 +196,7 @@ export function SessionTurn(
<div data-slot="session-turn-response-section">
<Switch>
<Match when={!completed()}>
- <MessageProgress
- assistantMessages={assistantMessages}
- done={!messageWorking()}
- diffComponent={props.diffComponent}
- />
+ <MessageProgress assistantMessages={assistantMessages} done={!messageWorking()} />
</Match>
<Match when={completed() && hasToolPart()}>
<Collapsible variant="ghost" open={detailsExpanded()} onOpenChange={setDetailsExpanded}>
@@ -241,18 +227,10 @@ export function SessionTurn(
message={assistantMessage}
parts={parts().filter((p) => p?.id !== last()?.id)}
sanitize={sanitizer()}
- diffComponent={props.diffComponent}
/>
)
}
- return (
- <Message
- message={assistantMessage}
- parts={parts()}
- sanitize={sanitizer()}
- diffComponent={props.diffComponent}
- />
- )
+ return <Message message={assistantMessage} parts={parts()} sanitize={sanitizer()} />
}}
</For>
<Show when={error()}>
diff --git a/packages/ui/src/context/diff.tsx b/packages/ui/src/context/diff.tsx
new file mode 100644
index 000000000..630437de6
--- /dev/null
+++ b/packages/ui/src/context/diff.tsx
@@ -0,0 +1,13 @@
+import { createContext, useContext, type ParentProps, type ValidComponent } from "solid-js"
+
+const DiffComponentContext = createContext<ValidComponent>()
+
+export function DiffComponentProvider(props: ParentProps<{ component: ValidComponent }>) {
+ return <DiffComponentContext.Provider value={props.component}>{props.children}</DiffComponentContext.Provider>
+}
+
+export function useDiffComponent() {
+ const component = useContext(DiffComponentContext)
+ if (!component) throw new Error("DiffComponentProvider must be used to provide a diff component")
+ return component
+}
diff --git a/packages/ui/src/context/index.ts b/packages/ui/src/context/index.ts
index fdff32bf2..3e0f5de74 100644
--- a/packages/ui/src/context/index.ts
+++ b/packages/ui/src/context/index.ts
@@ -1,2 +1,3 @@
export * from "./helper"
export * from "./data"
+export * from "./diff"