Files
hermes-agent/apps/desktop/src/app/chat/session-artifacts.test.tsx
T
m4 6946e37f96 feat(desktop): surface produced files, session artifacts fold, header cwd
Completed diff-less writes (write_file creates) were invisible in the
transcript. They now appear in the per-turn files card with a "new" tag
(preview on click, system-app open on hover), a collapsible per-session
artifacts fold sits above the usage footer, and the chat header shows
the session's workspace path ahead of the title.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-09-18 19:16:57 +08:00

70 lines
2.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { deriveSessionArtifacts } from './session-artifacts'
const writePart = (path: string) => ({
type: 'tool-call',
toolName: 'write_file',
args: { path },
result: { path }
})
const editPart = (path: string) => ({
type: 'tool-call',
toolName: 'edit_file',
args: { path },
result: { inline_diff: `--- a/${path}\n+++ b/${path}\n+x`, path }
})
describe('deriveSessionArtifacts', () => {
it('collects completed file-edit paths across all messages in first-seen order', () => {
const artifacts = deriveSessionArtifacts([
{ role: 'user', parts: [{ type: 'text', text: 'hi' }] },
{ role: 'assistant', parts: [writePart('docs/a.md'), editPart('src/b.ts')] },
{ role: 'assistant', parts: [writePart('docs/c.md')] }
])
expect(artifacts).toEqual([
{ name: 'a.md', path: 'docs/a.md' },
{ name: 'b.ts', path: 'src/b.ts' },
{ name: 'c.md', path: 'docs/c.md' }
])
})
it('dedupes by path across turns', () => {
const artifacts = deriveSessionArtifacts([
{ role: 'assistant', parts: [writePart('a.md')] },
{ role: 'assistant', parts: [editPart('a.md')] }
])
expect(artifacts).toEqual([{ name: 'a.md', path: 'a.md' }])
})
it('skips running, failed, and non-file parts', () => {
const artifacts = deriveSessionArtifacts([
{
role: 'assistant',
parts: [
{ type: 'tool-call', toolName: 'write_file', args: { path: 'running.md' } },
{ type: 'tool-call', toolName: 'write_file', args: { path: 'failed.md' }, isError: true, result: {} },
{ type: 'tool-call', toolName: 'terminal', args: {}, result: { output: 'ok' } },
{ type: 'text', text: 'done' }
]
}
])
expect(artifacts).toEqual([])
})
it('reads parts from the content alias too', () => {
const artifacts = deriveSessionArtifacts([{ role: 'assistant', content: [writePart('via-content.md')] }])
expect(artifacts).toEqual([{ name: 'via-content.md', path: 'via-content.md' }])
})
it('handles empty and malformed messages', () => {
expect(deriveSessionArtifacts([])).toEqual([])
expect(deriveSessionArtifacts([null, {}, { parts: 'nope' }])).toEqual([])
})
})