Add logs tab with real-time server output and consolidate syntax highlighting

- Implement dedicated Logs tab showing stdout/stderr from OpenCode server
- Add log level parsing (INFO, ERROR, WARN, DEBUG) with color coding
- Stream logs from main process to renderer via IPC events
- Persist scroll position and auto-scroll state per instance
- Synchronize instance IDs between renderer and main process
- Consolidate syntax highlighting to single shared highlighter instance
- Optimize markdown rendering with global highlighter initialization
- Fix code block copy button to always appear on right side
- Enable debug logging with --print-logs --log-level DEBUG flags
This commit is contained in:
Shantur Rathore
2025-10-23 11:14:35 +01:00
parent b836086978
commit 3c5c4755b8
13 changed files with 779 additions and 157 deletions

View File

@@ -1,5 +1,5 @@
import { createEffect, createSignal, onMount, Show } from "solid-js"
import { initMarkdown, renderMarkdown } from "../lib/markdown"
import { createEffect, createSignal, Show } from "solid-js"
import { renderMarkdown } from "../lib/markdown"
interface MarkdownProps {
content: string
@@ -8,29 +8,11 @@ interface MarkdownProps {
export function Markdown(props: MarkdownProps) {
const [html, setHtml] = createSignal("")
const [ready, setReady] = createSignal(false)
let containerRef: HTMLDivElement | undefined
onMount(async () => {
await initMarkdown(props.isDark ?? false)
setReady(true)
})
createEffect(async () => {
if (ready()) {
const rendered = await renderMarkdown(props.content)
setHtml(rendered)
}
})
createEffect(async () => {
if (props.isDark !== undefined) {
await initMarkdown(props.isDark)
if (ready()) {
const rendered = await renderMarkdown(props.content)
setHtml(rendered)
}
}
const rendered = await renderMarkdown(props.content)
setHtml(rendered)
})
createEffect(() => {
@@ -87,9 +69,5 @@ export function Markdown(props: MarkdownProps) {
}
})
return (
<Show when={ready()} fallback={<div class="text-gray-500">Loading...</div>}>
<div ref={containerRef} class="prose prose-sm dark:prose-invert max-w-none" innerHTML={html()} />
</Show>
)
return <div ref={containerRef} class="prose prose-sm dark:prose-invert max-w-none" innerHTML={html()} />
}