From aaf8317c8290c838212042c96bd0f88c5a2540d9 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:36:00 -0600 Subject: feat(app): feed customization options --- packages/ui/src/components/message-part.css | 28 +-- packages/ui/src/components/message-part.tsx | 322 ++++++++++++++++++---------- packages/ui/src/components/session-turn.tsx | 4 + 3 files changed, 221 insertions(+), 133 deletions(-) (limited to 'packages/ui/src') diff --git a/packages/ui/src/components/message-part.css b/packages/ui/src/components/message-part.css index 07a718141..ce76d8e18 100644 --- a/packages/ui/src/components/message-part.css +++ b/packages/ui/src/components/message-part.css @@ -332,14 +332,6 @@ } } -[data-slot="collapsible-content"]:has([data-component="edit-content"]), -[data-slot="collapsible-content"]:has([data-component="write-content"]) { - border: 1px solid var(--border-weak-base); - border-radius: 6px; - background: transparent; - overflow: hidden; -} - [data-component="bash-output"] { width: 100%; border: 1px solid var(--border-weak-base); @@ -399,11 +391,6 @@ } } -[data-slot="collapsible-content"]:has([data-component="edit-content"]) [data-component="edit-content"], -[data-slot="collapsible-content"]:has([data-component="write-content"]) [data-component="write-content"] { - border-top: none; -} - [data-component="edit-trigger"], [data-component="write-trigger"] { display: flex; @@ -492,9 +479,8 @@ [data-component="edit-content"] { border-radius: inherit; border-top: 1px solid var(--border-weaker-base); - max-height: 420px; overflow-x: hidden; - overflow-y: auto; + overflow-y: visible; scrollbar-width: none; -ms-overflow-style: none; @@ -512,9 +498,8 @@ [data-component="write-content"] { border-radius: inherit; border-top: 1px solid var(--border-weaker-base); - max-height: 240px; overflow-x: hidden; - overflow-y: auto; + overflow-y: visible; [data-component="code"] { padding-bottom: 0 !important; @@ -1212,11 +1197,18 @@ } } +[data-component="edit-tool"], +[data-component="write-tool"], [data-component="apply-patch-tool"] { > [data-component="collapsible"].tool-collapsible { gap: 0px; } + > [data-component="collapsible"] > [data-slot="collapsible-content"] { + border: none; + background: transparent; + } + > [data-component="collapsible"] > [data-slot="collapsible-trigger"][aria-expanded="true"] { position: sticky; top: var(--sticky-accordion-top, 0px); @@ -1298,7 +1290,7 @@ [data-component="apply-patch-file-diff"] { border-radius: inherit; overflow-x: hidden; - overflow-y: auto; + overflow-y: visible; scrollbar-width: none; -ms-overflow-style: none; diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index 828ddbe87..adba42ce9 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -276,12 +276,24 @@ function renderable(part: PartType, showReasoningSummaries = true) { return !!PART_MAPPING[part.type] } +function toolDefaultOpen(tool: string, shell = false, edit = false) { + if (tool === "bash") return shell + if (tool === "edit" || tool === "write" || tool === "apply_patch") return edit +} + +function partDefaultOpen(part: PartType, shell = false, edit = false) { + if (part.type !== "tool") return + return toolDefaultOpen(part.tool, shell, edit) +} + export function AssistantParts(props: { messages: AssistantMessage[] showAssistantCopyPartID?: string | null turnDurationMs?: number working?: boolean showReasoningSummaries?: boolean + shellToolDefaultOpen?: boolean + editToolDefaultOpen?: boolean }) { const data = useData() const emptyParts: PartType[] = [] @@ -372,6 +384,7 @@ export function AssistantParts(props: { message={entry().message} showAssistantCopyPartID={props.showAssistantCopyPartID} turnDurationMs={props.turnDurationMs} + defaultOpen={partDefaultOpen(entry().part, props.shellToolDefaultOpen, props.editToolDefaultOpen)} /> )} @@ -900,6 +913,42 @@ export const ToolRegistry = { render: getTool, } +function ToolFileAccordion(props: { path: string; actions?: JSX.Element; children: JSX.Element }) { + const value = createMemo(() => props.path || "tool-file") + + return ( + + + + +
+
+ +
+ + {`\u202A${getDirectory(props.path)}\u202C`} + + {getFilename(props.path)} +
+
+
+ {props.actions} + +
+
+
+
+ {props.children} +
+
+ ) +} + PART_MAPPING["tool"] = function ToolPartDisplay(props) { const data = useData() const i18n = useI18n() @@ -1479,57 +1528,67 @@ ToolRegistry.register({ const i18n = useI18n() const diffComponent = useDiffComponent() const diagnostics = createMemo(() => getDiagnostics(props.metadata.diagnostics, props.input.filePath)) + const path = createMemo(() => props.metadata?.filediff?.file || props.input.filePath || "") const filename = () => getFilename(props.input.filePath ?? "") const pending = () => props.status === "pending" || props.status === "running" return ( - -
-
- - - +
+ +
+
+ + + + + + + {filename()} - - - {filename()} +
+ +
+ {getDirectory(props.input.filePath!)} +
+
+
+
+ +
- -
- {getDirectory(props.input.filePath!)} -
-
-
-
- - -
-
- } - > - -
- -
-
- - + } + > + + {(diff) => } + } + > +
+ +
+ + + + +
) }, }) @@ -1540,51 +1599,56 @@ ToolRegistry.register({ const i18n = useI18n() const codeComponent = useCodeComponent() const diagnostics = createMemo(() => getDiagnostics(props.metadata.diagnostics, props.input.filePath)) + const path = createMemo(() => props.input.filePath || "") const filename = () => getFilename(props.input.filePath ?? "") const pending = () => props.status === "pending" || props.status === "running" return ( - -
-
- - - +
+ +
+
+ + + + + + + {filename()} - - - {filename()} +
+ +
+ {getDirectory(props.input.filePath!)} +
- -
- {getDirectory(props.input.filePath!)} -
-
+
{/* */}
-
{/* */}
-
- } - > - -
- -
-
- - + } + > + + +
+ +
+
+
+ + +
) }, }) @@ -1731,45 +1795,73 @@ ToolRegistry.register({ } > {(file) => ( - -
-
- - - +
+ +
+
+ + + + + + + {getFilename(file().relativePath)} - +
+ +
+ {getDirectory(file().relativePath)} +
+
+
+
- {getFilename(file().relativePath)} +
- -
- {getDirectory(file().relativePath)} -
-
-
- - - + } + > + + + + {i18n.t("ui.patch.action.created")} + + + + + {i18n.t("ui.patch.action.deleted")} + + + + + {i18n.t("ui.patch.action.moved")} + + + + + + + } + > +
+
-
- } - > -
- -
- + + +
)} ) diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index 8e8a3f387..0eceb754c 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -140,6 +140,8 @@ export function SessionTurn( messageID: string lastUserMessageID?: string showReasoningSummaries?: boolean + shellToolDefaultOpen?: boolean + editToolDefaultOpen?: boolean onUserInteracted?: () => void classes?: { root?: string @@ -369,6 +371,8 @@ export function SessionTurn( turnDurationMs={turnDurationMs()} working={working()} showReasoningSummaries={showReasoningSummaries()} + shellToolDefaultOpen={props.shellToolDefaultOpen} + editToolDefaultOpen={props.editToolDefaultOpen} />
-- cgit v1.2.3