|
@@ -1,4 +1,4 @@
|
|
|
-import { Component, createMemo, For, Match, Show, Switch } from "solid-js"
|
|
|
|
|
|
|
+import { Component, createMemo, For, Match, Show, Switch, type JSX } from "solid-js"
|
|
|
import { Dynamic } from "solid-js/web"
|
|
import { Dynamic } from "solid-js/web"
|
|
|
import {
|
|
import {
|
|
|
AssistantMessage,
|
|
AssistantMessage,
|
|
@@ -22,6 +22,44 @@ import { Markdown } from "./markdown"
|
|
|
import { getDirectory as _getDirectory, getFilename } from "@opencode-ai/util/path"
|
|
import { getDirectory as _getDirectory, getFilename } from "@opencode-ai/util/path"
|
|
|
import { checksum } from "@opencode-ai/util/encode"
|
|
import { checksum } from "@opencode-ai/util/encode"
|
|
|
|
|
|
|
|
|
|
+interface Diagnostic {
|
|
|
|
|
+ range: {
|
|
|
|
|
+ start: { line: number; character: number }
|
|
|
|
|
+ end: { line: number; character: number }
|
|
|
|
|
+ }
|
|
|
|
|
+ message: string
|
|
|
|
|
+ severity?: number
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function getDiagnostics(
|
|
|
|
|
+ diagnosticsByFile: Record<string, Diagnostic[]> | undefined,
|
|
|
|
|
+ filePath: string | undefined,
|
|
|
|
|
+): Diagnostic[] {
|
|
|
|
|
+ if (!diagnosticsByFile || !filePath) return []
|
|
|
|
|
+ const diagnostics = diagnosticsByFile[filePath] ?? []
|
|
|
|
|
+ return diagnostics.filter((d) => d.severity === 1).slice(0, 3)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function DiagnosticsDisplay(props: { diagnostics: Diagnostic[] }): JSX.Element {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <Show when={props.diagnostics.length > 0}>
|
|
|
|
|
+ <div data-component="diagnostics">
|
|
|
|
|
+ <For each={props.diagnostics}>
|
|
|
|
|
+ {(diagnostic) => (
|
|
|
|
|
+ <div data-slot="diagnostic">
|
|
|
|
|
+ <span data-slot="diagnostic-label">Error</span>
|
|
|
|
|
+ <span data-slot="diagnostic-location">
|
|
|
|
|
+ [{diagnostic.range.start.line + 1}:{diagnostic.range.start.character + 1}]
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span data-slot="diagnostic-message">{diagnostic.message}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </For>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </Show>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export interface MessageProps {
|
|
export interface MessageProps {
|
|
|
message: MessageType
|
|
message: MessageType
|
|
|
parts: PartType[]
|
|
parts: PartType[]
|
|
@@ -444,6 +482,7 @@ ToolRegistry.register({
|
|
|
name: "edit",
|
|
name: "edit",
|
|
|
render(props) {
|
|
render(props) {
|
|
|
const diffComponent = useDiffComponent()
|
|
const diffComponent = useDiffComponent()
|
|
|
|
|
+ const diagnostics = createMemo(() => getDiagnostics(props.metadata.diagnostics, props.input.filePath))
|
|
|
return (
|
|
return (
|
|
|
<BasicTool
|
|
<BasicTool
|
|
|
defaultOpen
|
|
defaultOpen
|
|
@@ -482,6 +521,7 @@ ToolRegistry.register({
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</Show>
|
|
</Show>
|
|
|
|
|
+ <DiagnosticsDisplay diagnostics={diagnostics()} />
|
|
|
</BasicTool>
|
|
</BasicTool>
|
|
|
)
|
|
)
|
|
|
},
|
|
},
|
|
@@ -491,6 +531,7 @@ ToolRegistry.register({
|
|
|
name: "write",
|
|
name: "write",
|
|
|
render(props) {
|
|
render(props) {
|
|
|
const codeComponent = useCodeComponent()
|
|
const codeComponent = useCodeComponent()
|
|
|
|
|
+ const diagnostics = createMemo(() => getDiagnostics(props.metadata.diagnostics, props.input.filePath))
|
|
|
return (
|
|
return (
|
|
|
<BasicTool
|
|
<BasicTool
|
|
|
defaultOpen
|
|
defaultOpen
|
|
@@ -523,6 +564,7 @@ ToolRegistry.register({
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
</Show>
|
|
</Show>
|
|
|
|
|
+ <DiagnosticsDisplay diagnostics={diagnostics()} />
|
|
|
</BasicTool>
|
|
</BasicTool>
|
|
|
)
|
|
)
|
|
|
},
|
|
},
|