Merge main HEAD (segment 5) into sandboxed-agent-rebase

Resolve 83 conflicts: 10 backend, 62 frontend, 11 config/lock files.
Preserve sandbox/agent/collaboration features while adopting main's
UI refactorings (Dialog/AlertDialog/Popover), model provider updates,
and enterprise features.

Made-with: Cursor
This commit is contained in:
Novice
2026-03-23 14:20:06 +08:00
1671 changed files with 124822 additions and 22302 deletions

View File

@ -0,0 +1,24 @@
import { render } from '@testing-library/react'
import { NoteEditorContextProvider } from '../../../context'
import FormatDetectorPlugin from '../index'
const emptyValue = JSON.stringify({ root: { children: [] } })
describe('FormatDetectorPlugin', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// The plugin should register its observers without rendering extra UI.
describe('Rendering', () => {
it('should mount inside the real note editor context without visible output', () => {
const { container } = render(
<NoteEditorContextProvider value={emptyValue}>
<FormatDetectorPlugin />
</NoteEditorContextProvider>,
)
expect(container).toBeEmptyDOMElement()
})
})
})

View File

@ -0,0 +1,71 @@
import type { createNoteEditorStore } from '../../../store'
import { act, render, screen, waitFor } from '@testing-library/react'
import { useEffect } from 'react'
import { NoteEditorContextProvider } from '../../../context'
import { useNoteEditorStore } from '../../../store'
import LinkEditorPlugin from '../index'
type NoteEditorStore = ReturnType<typeof createNoteEditorStore>
const emptyValue = JSON.stringify({ root: { children: [] } })
const StoreProbe = ({
onReady,
}: {
onReady?: (store: NoteEditorStore) => void
}) => {
const store = useNoteEditorStore()
useEffect(() => {
onReady?.(store)
}, [onReady, store])
return null
}
describe('LinkEditorPlugin', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// Without an anchor element the plugin should stay hidden.
describe('Visibility', () => {
it('should render nothing when no link anchor is selected', () => {
const { container } = render(
<NoteEditorContextProvider value={emptyValue}>
<LinkEditorPlugin containerElement={null} />
</NoteEditorContextProvider>,
)
expect(container).toBeEmptyDOMElement()
expect(screen.queryByRole('textbox')).not.toBeInTheDocument()
})
it('should render the link editor when the store has an anchor element', async () => {
let store: NoteEditorStore | null = null
render(
<NoteEditorContextProvider value={emptyValue}>
<StoreProbe onReady={instance => (store = instance)} />
<LinkEditorPlugin containerElement={document.createElement('div')} />
</NoteEditorContextProvider>,
)
await waitFor(() => {
expect(store).not.toBeNull()
})
act(() => {
store!.setState({
linkAnchorElement: document.createElement('a'),
linkOperatorShow: false,
selectedLinkUrl: 'https://example.com',
})
})
await waitFor(() => {
expect(screen.getByDisplayValue('https://example.com')).toBeInTheDocument()
})
})
})
})