Files
rhema-claw/web/claw/app/components/AppMarkdown.vue
T
vhaudiquet 81da26b955 feat(rhema-code): add the colors setting with four palettes
The stored `colors` key names a palette — rhema (the default,
Jadeite), aquamarine, black-and-white, or dracula — and the
Appearance page of /settings cycles it live, like the theme and
icon toggles beside it. Each palette carries a dark and a light
appearance under the existing `theme` key; dracula's light side is
derived, the official palette ships only dark.

The appearance decision moves off token comparison: Theme now
answers is_dark() from the ground/text luminance, so palettes
beyond the original two get the right per-profile fallback tones.
2026-10-17 04:28:31 +08:00

37 lines
1.2 KiB
Vue

<script setup lang="ts">
// Agent replies are markdown; this mounts the rendered HTML. The parser
// keeps raw HTML in the source escaped (html stays false) and refuses
// javascript: link targets, so v-html only ever receives generated
// markup.
import MarkdownIt from 'markdown-it'
import type { RendererRule } from 'markdown-it'
const props = defineProps<{
text: string
/** While true, a blinking cursor trails the last rendered block. */
streaming?: boolean
}>()
const md = new MarkdownIt({ html: false, linkify: true })
// Rendered links leave the dashboard; open them in a new tab so the
// transcript and its event stream survive the click.
const defaultLinkOpen: RendererRule =
md.renderer.rules.link_open ??
((tokens, idx, options, env, self) => self.renderToken(tokens, idx, options))
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx]
if (token) {
token.attrSet('target', '_blank')
token.attrSet('rel', 'noopener noreferrer')
}
return defaultLinkOpen(tokens, idx, options, env, self)
}
const html = computed(() => md.render(props.text))
</script>
<template>
<div class="md" :class="{ streaming }" v-html="html" />
</template>