mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
Workspace and transcript selections now flow into the composer as lightweight references so users can carry exact snippets into the next prompt without file-only workarounds. The prompt formatter keeps workspace and chat excerpts separate, and the composer avoids sending chat snippets as fake file attachments. Constraint: Selection references must prepare model context without polluting backend file attachment payloads. Rejected: Reuse file attachments for chat selections | would leak chat:// pseudo paths into file-oriented payloads. Confidence: high Scope-risk: moderate Directive: Keep chat-selection references prompt-only unless the backend gains a first-class chat context attachment type. Tested: bun run check:desktop Tested: bun run verify Tested: agent-browser UI smoke for workspace, user-message, and assistant-message selections Not-tested: Strict Chrome extension channel; connection timed out, local browser automation covered the flow.
68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { fireEvent, render } from '@testing-library/react'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import { AttachmentGallery } from './AttachmentGallery'
|
|
|
|
describe('AttachmentGallery', () => {
|
|
it('renders a compact quote preview for selected workspace text', () => {
|
|
render(
|
|
<AttachmentGallery
|
|
variant="composer"
|
|
attachments={[{
|
|
id: 'selection-1',
|
|
type: 'file',
|
|
name: 'App.tsx',
|
|
path: 'src/App.tsx',
|
|
lineStart: 10,
|
|
lineEnd: 12,
|
|
quote: 'const value = calculate(input)\nreturn value',
|
|
}]}
|
|
/>,
|
|
)
|
|
|
|
expect(document.body.textContent).toContain('App.tsx:L10-L12')
|
|
expect(document.body.textContent).toContain('const value = calculate(input) return value')
|
|
})
|
|
|
|
it('keeps plain file chips on the one-line treatment', () => {
|
|
render(
|
|
<AttachmentGallery
|
|
variant="composer"
|
|
attachments={[{
|
|
id: 'file-1',
|
|
type: 'file',
|
|
name: 'README.md',
|
|
path: 'README.md',
|
|
}]}
|
|
/>,
|
|
)
|
|
|
|
expect(document.body.textContent).toContain('README.md')
|
|
expect(document.body.textContent).not.toContain(':L')
|
|
})
|
|
|
|
it('removes a quoted workspace attachment by id', () => {
|
|
const onRemove = vi.fn()
|
|
|
|
const view = render(
|
|
<AttachmentGallery
|
|
variant="composer"
|
|
onRemove={onRemove}
|
|
attachments={[{
|
|
id: 'selection-1',
|
|
type: 'file',
|
|
name: 'App.tsx',
|
|
path: 'src/App.tsx',
|
|
lineStart: 10,
|
|
quote: 'const value = 1',
|
|
}]}
|
|
/>,
|
|
)
|
|
|
|
fireEvent.click(view.getByRole('button', { name: 'Remove App.tsx' }))
|
|
|
|
expect(onRemove).toHaveBeenCalledWith('selection-1')
|
|
})
|
|
})
|