mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-30 11:52:04 +00:00
feat(desktop): PR-style file diffs in chat
Render write_file/edit_file/patch as a reviewable diff instead of raw result JSON, closer to a Cursor/T3 per-edit review. - Unified diff via FileDiffPanel: strip git file-header + @@ hunk noise, drop the +/- gutter, color by line with a 2px gutter accent, full-bleed to the card, transparent context lines, compact scroll height. - Header shows filename + language icon + +N/-N stats; full path moves to a hover tooltip (no Edited verb, no ms). - Treat the three file-edit tools uniformly (isFileEditTool); read diff from inline_diff or patch's diff field; suppress raw-arg detail. - Reusable FileTypeIcon primitive sharing the code-block icon mapping (codiconForFilename), codicon fallback. - Per-row scaffolding fade (not the group wrapper, which trapped child opacity); expanded edits stay full, collapsed fade; keyboard-only focus lift. Hide diff-less rehydrated creates that read as dupes.
This commit is contained in:
parent
fb3d31ba8b
commit
a61baa9615
7 changed files with 451 additions and 50 deletions
|
|
@ -108,6 +108,56 @@ export function codiconForLanguage(language: string | undefined): string {
|
|||
return CODICON_BY_LANGUAGE[sanitizeLanguageTag(language || '')] || 'code'
|
||||
}
|
||||
|
||||
// File extension → language tag, so a filename can resolve to the same icon a
|
||||
// fenced code block of that language would get. Only extensions that map to a
|
||||
// non-generic codicon need an entry; everything else falls through to `code`.
|
||||
const LANGUAGE_BY_EXTENSION: Record<string, string> = {
|
||||
bash: 'bash',
|
||||
cfg: 'ini',
|
||||
conf: 'ini',
|
||||
css: 'css',
|
||||
dockerfile: 'dockerfile',
|
||||
env: 'env',
|
||||
gql: 'graphql',
|
||||
graphql: 'graphql',
|
||||
ini: 'ini',
|
||||
json: 'json',
|
||||
json5: 'json',
|
||||
less: 'less',
|
||||
markdown: 'markdown',
|
||||
md: 'markdown',
|
||||
mdx: 'markdown',
|
||||
mmd: 'mermaid',
|
||||
ps1: 'powershell',
|
||||
psql: 'sql',
|
||||
sass: 'sass',
|
||||
scss: 'scss',
|
||||
sh: 'bash',
|
||||
sql: 'sql',
|
||||
svg: 'svg',
|
||||
toml: 'toml',
|
||||
yaml: 'yaml',
|
||||
yml: 'yml',
|
||||
zsh: 'zsh'
|
||||
}
|
||||
|
||||
// Pick an icon for a file path by its extension (or bare name like
|
||||
// `Dockerfile`), reusing the language→codicon map so file-edit rows and code
|
||||
// blocks share one visual vocabulary. Unknown / generic code files get `code`.
|
||||
export function codiconForFilename(path: string | undefined): string {
|
||||
const base = (path || '').replace(/\\/g, '/').split('/').pop()?.trim().toLowerCase() || ''
|
||||
|
||||
if (!base) {
|
||||
return 'code'
|
||||
}
|
||||
|
||||
const dot = base.lastIndexOf('.')
|
||||
const token = dot > 0 ? base.slice(dot + 1) : base
|
||||
const language = LANGUAGE_BY_EXTENSION[token] || token
|
||||
|
||||
return codiconForLanguage(language)
|
||||
}
|
||||
|
||||
function proseLineCount(body: string): number {
|
||||
return body.split('\n').filter(line => {
|
||||
const trimmed = line.trim()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue