Parcourir la source

wip: desktop work

Adam il y a 3 mois
Parent
commit
dce287a42d

+ 2 - 2
bun.lock

@@ -347,7 +347,7 @@
     "@hono/zod-validator": "0.4.2",
     "@hono/zod-validator": "0.4.2",
     "@kobalte/core": "0.13.11",
     "@kobalte/core": "0.13.11",
     "@openauthjs/openauth": "0.0.0-20250322224806",
     "@openauthjs/openauth": "0.0.0-20250322224806",
-    "@pierre/precision-diffs": "0.3.6",
+    "@pierre/precision-diffs": "0.4.1",
     "@solidjs/meta": "0.29.4",
     "@solidjs/meta": "0.29.4",
     "@tailwindcss/vite": "4.1.11",
     "@tailwindcss/vite": "4.1.11",
     "@tsconfig/bun": "1.0.9",
     "@tsconfig/bun": "1.0.9",
@@ -941,7 +941,7 @@
 
 
     "@petamoriken/float16": ["@petamoriken/[email protected]", "", {}, "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog=="],
     "@petamoriken/float16": ["@petamoriken/[email protected]", "", {}, "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog=="],
 
 
-    "@pierre/precision-diffs": ["@pierre/precision-diffs@0.3.6", "", { "dependencies": { "@shikijs/core": "3.13.0", "@shikijs/transformers": "3.13.0", "diff": "8.0.2", "fast-deep-equal": "3.1.3", "hast-util-to-html": "9.0.5", "shiki": "3.13.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-cKM3HcMmyr5wPFll0bHYcgHplcHgMlL6Dw4Pi4giL0jVt7ySlGwwVyXTRFW5Fva43stOL+EWB+9U5VBDSktBJA=="],
+    "@pierre/precision-diffs": ["@pierre/precision-diffs@0.4.1", "", { "dependencies": { "@shikijs/core": "3.13.0", "@shikijs/transformers": "3.13.0", "diff": "8.0.2", "fast-deep-equal": "3.1.3", "hast-util-to-html": "9.0.5", "shiki": "3.13.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-AoozHakINGyNJFgbYc/1PlDK0yunrAxbtXEMBe9fdu8RLkNjVtYRTLw7EF2mM/YuVoVRjj2HT/2VJ4a2rMyDOA=="],
 
 
     "@pkgjs/parseargs": ["@pkgjs/[email protected]", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
     "@pkgjs/parseargs": ["@pkgjs/[email protected]", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
 
 

+ 1 - 1
package.json

@@ -25,7 +25,7 @@
       "@tsconfig/bun": "1.0.9",
       "@tsconfig/bun": "1.0.9",
       "@cloudflare/workers-types": "4.20251008.0",
       "@cloudflare/workers-types": "4.20251008.0",
       "@openauthjs/openauth": "0.0.0-20250322224806",
       "@openauthjs/openauth": "0.0.0-20250322224806",
-      "@pierre/precision-diffs": "0.3.6",
+      "@pierre/precision-diffs": "0.4.1",
       "@solidjs/meta": "0.29.4",
       "@solidjs/meta": "0.29.4",
       "@tailwindcss/vite": "4.1.11",
       "@tailwindcss/vite": "4.1.11",
       "diff": "8.0.2",
       "diff": "8.0.2",

+ 34 - 29
packages/desktop/src/components/message.tsx

@@ -15,7 +15,7 @@ registerPartComponent("text", function TextPartDisplay(props) {
   const part = props.part as TextPart
   const part = props.part as TextPart
   return (
   return (
     <Show when={part.text.trim()}>
     <Show when={part.text.trim()}>
-      <Markdown text={part.text.trim()} />
+      <Markdown text={part.text.trim()} class="mt-8" />
     </Show>
     </Show>
   )
   )
 })
 })
@@ -36,36 +36,41 @@ registerPartComponent("tool", function ToolPartDisplay(props) {
     const metadata = part.state.status === "pending" ? {} : (part.state.metadata ?? {})
     const metadata = part.state.status === "pending" ? {} : (part.state.metadata ?? {})
     const input = part.state.status === "completed" ? part.state.input : {}
     const input = part.state.status === "completed" ? part.state.input : {}
 
 
-    if (part.state.status === "error") {
-      const error = part.state.error.replace("Error: ", "")
-      const [title, ...rest] = error.split(": ")
-      return (
-        <Card variant="error">
-          <div class="flex items-center gap-2">
-            <Icon name="circle-ban-sign" size="small" class="text-icon-critical-active" />
-            <Switch>
-              <Match when={title}>
+    return (
+      <Switch>
+        <Match when={part.state.status === "error" && part.state.error}>
+          {(error) => {
+            const cleaned = error().replace("Error: ", "")
+            const [title, ...rest] = cleaned.split(": ")
+            return (
+              <Card variant="error">
                 <div class="flex items-center gap-2">
                 <div class="flex items-center gap-2">
-                  <div class="text-12-medium text-[var(--ember-light-11)] capitalize">{title}</div>
-                  <span>{rest.join(": ")}</span>
+                  <Icon name="circle-ban-sign" size="small" class="text-icon-critical-active" />
+                  <Switch>
+                    <Match when={title}>
+                      <div class="flex items-center gap-2">
+                        <div class="text-12-medium text-[var(--ember-light-11)] capitalize">{title}</div>
+                        <span>{rest.join(": ")}</span>
+                      </div>
+                    </Match>
+                    <Match when={true}>{cleaned}</Match>
+                  </Switch>
                 </div>
                 </div>
-              </Match>
-              <Match when={true}>{error}</Match>
-            </Switch>
-          </div>
-        </Card>
-      )
-    }
-
-    return (
-      <Dynamic
-        component={render}
-        input={input}
-        tool={part.tool}
-        metadata={metadata}
-        output={part.state.status === "completed" ? part.state.output : undefined}
-        hideDetails={props.hideDetails}
-      />
+              </Card>
+            )
+          }}
+        </Match>
+        <Match when={true}>
+          <Dynamic
+            component={render}
+            input={input}
+            tool={part.tool}
+            metadata={metadata}
+            output={part.state.status === "completed" ? part.state.output : undefined}
+            hideDetails={props.hideDetails}
+          />
+        </Match>
+      </Switch>
     )
     )
   })
   })
 
 

+ 1 - 1
packages/desktop/src/pages/index.tsx

@@ -832,7 +832,7 @@ export default function Page() {
                                                 </div>
                                                 </div>
                                               </Collapsible.Trigger>
                                               </Collapsible.Trigger>
                                               <Collapsible.Content>
                                               <Collapsible.Content>
-                                                <div class="w-full flex flex-col items-start self-stretch gap-8">
+                                                <div class="w-full flex flex-col items-start self-stretch gap-3">
                                                   <For each={assistantMessages()}>
                                                   <For each={assistantMessages()}>
                                                     {(assistantMessage) => {
                                                     {(assistantMessage) => {
                                                       const parts = createMemo(
                                                       const parts = createMemo(

+ 3 - 7
packages/ui/src/components/diff.tsx

@@ -3,12 +3,12 @@ import {
   FileDiff,
   FileDiff,
   type DiffLineAnnotation,
   type DiffLineAnnotation,
   type HunkData,
   type HunkData,
-  DiffFileRendererOptions,
+  FileDiffOptions,
   // registerCustomTheme,
   // registerCustomTheme,
 } from "@pierre/precision-diffs"
 } from "@pierre/precision-diffs"
 import { ComponentProps, createEffect, splitProps } from "solid-js"
 import { ComponentProps, createEffect, splitProps } from "solid-js"
 
 
-export type DiffProps<T = {}> = Omit<DiffFileRendererOptions<T>, "themes"> & {
+export type DiffProps<T = {}> = FileDiffOptions<T> & {
   before: FileContents
   before: FileContents
   after: FileContents
   after: FileContents
   annotations?: DiffLineAnnotation<T>[]
   annotations?: DiffLineAnnotation<T>[]
@@ -54,13 +54,9 @@ export function Diff<T>(props: DiffProps<T>) {
   // When ready to render, simply call .render with old/new file, optional
   // When ready to render, simply call .render with old/new file, optional
   // annotations and a container element to hold the diff
   // annotations and a container element to hold the diff
   createEffect(() => {
   createEffect(() => {
-    // @ts-expect-error
     const instance = new FileDiff<T>({
     const instance = new FileDiff<T>({
       // theme: "pierre-light",
       // theme: "pierre-light",
-      // theme: "pierre-light",
-      // Or can also provide a 'themes' prop, which allows the code to adapt
-      // to your OS light or dark theme
-      themes: { dark: "pierre-dark", light: "pierre-light" },
+      theme: { dark: "pierre-dark", light: "pierre-light" },
       // When using the 'themes' prop, 'themeType' allows you to force 'dark'
       // When using the 'themes' prop, 'themeType' allows you to force 'dark'
       // or 'light' theme, or inherit from the OS ('system') theme.
       // or 'light' theme, or inherit from the OS ('system') theme.
       themeType: "system",
       themeType: "system",

+ 1 - 5
packages/ui/src/components/message-part.tsx

@@ -55,11 +55,7 @@ export function AssistantMessageDisplay(props: { message: AssistantMessage; part
       return x.type !== "tool" || (x as ToolPart).tool !== "todoread"
       return x.type !== "tool" || (x as ToolPart).tool !== "todoread"
     })
     })
   })
   })
-  return (
-    <div data-component="assistant-message">
-      <For each={filteredParts()}>{(part) => <Part part={part} message={props.message} />}</For>
-    </div>
-  )
+  return <For each={filteredParts()}>{(part) => <Part part={part} message={props.message} />}</For>
 }
 }
 
 
 export function UserMessageDisplay(props: { message: UserMessage; parts: PartType[] }) {
 export function UserMessageDisplay(props: { message: UserMessage; parts: PartType[] }) {