summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJay V <[email protected]>2025-06-09 15:41:19 -0500
committerJay V <[email protected]>2025-06-09 15:41:19 -0500
commit54c4a783b3058e33003a3401f3c11b7e9bf2cd9f (patch)
treeaca3d250d33a8c7697265f9a1a10d42d7daf11fe
parentc091cbb624827029f7392f124ee86345f21ab22d (diff)
downloadopencode-54c4a783b3058e33003a3401f3c11b7e9bf2cd9f.tar.gz
opencode-54c4a783b3058e33003a3401f3c11b7e9bf2cd9f.zip
share page show lsp diag
-rw-r--r--packages/web/src/components/Share.tsx39
1 files changed, 39 insertions, 0 deletions
diff --git a/packages/web/src/components/Share.tsx b/packages/web/src/components/Share.tsx
index 7fefb2713..333c349c5 100644
--- a/packages/web/src/components/Share.tsx
+++ b/packages/web/src/components/Share.tsx
@@ -13,6 +13,7 @@ import {
} from "solid-js"
import { DateTime } from "luxon"
import { createStore, reconcile } from "solid-js/store"
+import type { Diagnostic } from "vscode-languageserver-types"
import { IconOpenAI, IconGemini, IconAnthropic } from "./icons/custom"
import {
IconCpuChip,
@@ -150,6 +151,30 @@ function flattenToolArgs(obj: any, prefix: string = ""): Array<[string, any]> {
return entries
}
+/**
+ * Return a flat array of error diagnostics, in the format:
+ * "ERROR [65:20] Property 'x' does not exist on type 'Y'"
+ */
+export function getDiagnostics(
+ diagnosticsByFile: Record<string, Diagnostic[]>
+): string[] {
+ const result: string[] = [];
+
+ for (const diags of Object.values(diagnosticsByFile)) {
+ for (const d of diags) {
+ // Only keep diagnostics explicitly marked as Error (severity === 1)
+ if (d.severity !== 1) continue;
+
+ const line = d.range.start.line + 1; // 1-based
+ const column = d.range.start.character + 1; // 1-based
+
+ result.push(`ERROR [${line}:${column}] ${d.message}`);
+ }
+ }
+
+ return result;
+}
+
function stripEnclosingTag(text: string): string {
const wrappedRe = /^\s*<([A-Za-z]\w*)>\s*([\s\S]*?)\s*<\/\1>\s*$/
const match = text.match(wrappedRe)
@@ -1248,6 +1273,9 @@ export default function Share(props: {
const result =
part().toolInvocation.state === "result" &&
part().toolInvocation.result
+ const diagnostics = createMemo(() =>
+ getDiagnostics(metadata()?.diagnostics)
+ )
const duration = createMemo(() =>
DateTime.fromMillis(metadata()?.time.end || 0)
@@ -1276,6 +1304,10 @@ export default function Share(props: {
<span data-element-label>Write</span>
<b>{filePath}</b>
</span>
+ <TextPart
+ data-size="sm"
+ text={diagnostics().join("\n\n")}
+ />
<Switch>
<Match when={hasError}>
<div data-part-tool-result>
@@ -1333,6 +1365,9 @@ export default function Share(props: {
)
const args = part().toolInvocation.args
const filePath = args.filePath
+ const diagnostics = createMemo(() =>
+ getDiagnostics(metadata()?.diagnostics)
+ )
const duration = createMemo(() =>
DateTime.fromMillis(metadata()?.time.end || 0)
@@ -1368,6 +1403,10 @@ export default function Share(props: {
lang={getFileType(filePath)}
/>
</div>
+ <TextPart
+ data-size="sm"
+ text={diagnostics().join("\n\n")}
+ />
</div>
<ToolFooter time={duration()} />
</div>