Files
orca/src/main/ipc/markdown-documents.test.ts
T
Neil 08470f8b8e fix(markdown): bound Markdown document listing and renderer retention
Markdown link completion listed every .md/.mdx/.markdown file under a
workspace root with no ceiling on count, aggregate metadata, path length,
directories visited, or recursion depth, and the renderer retained one
document array per worktree forever. A large monorepo — or a symlink-free
but very deep tree — could grow both the main-process listing and the
renderer cache without limit.

- Add a shared listing budget (20,000 documents / 8 MiB metadata /
  64 KiB path / 100,000 visited entries / depth 256) enforced by the
  local, SSH, and relay producers alike. Caller-supplied limits are
  clamped down, never up, so the ceiling is enforced rather than advisory.
- Stream directory entries with opendir instead of materializing each
  directory's full entry array.
- Bound renderer retention to an LRU of 8 worktree snapshots capped at
  32 MiB aggregate.
- Surface capacity failures as a typed error (relay code -33008) and a
  single toast rather than a silent empty list.
2026-07-27 12:58:12 -07:00

80 lines
2.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
markdownDocumentFromFilePath,
markdownDocumentsFromRelativePaths
} from './markdown-documents'
import { MarkdownDocumentListingCapacityError } from '../../shared/markdown-document-listing-limits'
describe('markdownDocumentFromFilePath', () => {
it('keeps in-root path segments that merely start with parent traversal text', () => {
expect(markdownDocumentFromFilePath('/workspace', '/workspace/..notes/file.md')).toMatchObject({
filePath: '/workspace/..notes/file.md',
relativePath: '..notes/file.md',
basename: 'file.md',
name: 'file'
})
})
it('treats actual parent traversal as outside the root', () => {
expect(
markdownDocumentFromFilePath('/workspace', '/workspace-other/file.md', {
outsideRootRelativePath: 'basename'
})
).toMatchObject({
filePath: '/workspace-other/file.md',
relativePath: 'file.md',
basename: 'file.md',
name: 'file'
})
})
})
describe('markdownDocumentsFromRelativePaths', () => {
it('preserves filtering and sorted output below every limit', () => {
expect(
markdownDocumentsFromRelativePaths('/workspace', [
'z-last.markdown',
'src/app.ts',
'../outside.md',
'docs/Guide.MDX',
'README.md'
])
).toEqual([
{
filePath: '/workspace/docs/Guide.MDX',
relativePath: 'docs/Guide.MDX',
basename: 'Guide.MDX',
name: 'Guide'
},
{
filePath: '/workspace/README.md',
relativePath: 'README.md',
basename: 'README.md',
name: 'README'
},
{
filePath: '/workspace/z-last.markdown',
relativePath: 'z-last.markdown',
basename: 'z-last.markdown',
name: 'z-last'
}
])
})
it('rejects count, metadata, and UTF-8 path overflow before retaining another result', () => {
expect(() =>
markdownDocumentsFromRelativePaths('/workspace', ['one.md', 'two.md'], {
maxDocuments: 1
})
).toThrow(MarkdownDocumentListingCapacityError)
expect(() =>
markdownDocumentsFromRelativePaths('/workspace', ['metadata.md'], {
maxMetadataBytes: 1
})
).toThrow(MarkdownDocumentListingCapacityError)
expect(() =>
markdownDocumentsFromRelativePaths('/workspace', [`${'é'.repeat(40_000)}.md`])
).toThrow(MarkdownDocumentListingCapacityError)
})
})