import { afterEach, describe, expect, it } from 'bun:test' import * as fs from 'fs' import * as fsp from 'fs/promises' import * as path from 'path' import { handleFilesystemRoute } from '../api/filesystem.js' const cleanupDirs = new Set() function makeUrl(route: string, params: Record): URL { const url = new URL(`http://localhost${route}`) for (const [key, value] of Object.entries(params)) { url.searchParams.set(key, value) } return url } afterEach(async () => { for (const dir of cleanupDirs) { await fsp.rm(dir, { recursive: true, force: true }) } cleanupDirs.clear() }) describe('filesystem API', () => { it('allows browsing a directory under the user home directory', async () => { const homeFixtureDir = await fsp.mkdtemp(path.join(process.env.HOME || path.sep, 'claude-filesystem-test-')) cleanupDirs.add(homeFixtureDir) await fsp.writeFile(path.join(homeFixtureDir, 'note.txt'), 'hello') const res = await handleFilesystemRoute( '/api/filesystem/browse', makeUrl('/api/filesystem/browse', { path: homeFixtureDir, includeFiles: 'true', }), ) expect(res.status).toBe(200) const body = await res.json() as { entries: Array<{ name: string }> } expect(body.entries.some((entry) => entry.name === 'note.txt')).toBe(true) }) it('accepts /private/tmp aliases on macOS for browsing and file serving', async () => { if (process.platform !== 'darwin') return const tmpFixtureDir = await fsp.mkdtemp('/tmp/claude-filesystem-test-') cleanupDirs.add(tmpFixtureDir) const canonicalTmpDir = fs.realpathSync(tmpFixtureDir) const imagePath = path.join(canonicalTmpDir, 'preview.png') await fsp.writeFile( imagePath, Buffer.from('89504e470d0a1a0a0000000d4948445200000001000000010802000000907753de0000000c49444154789c63606060000000040001f61738550000000049454e44ae426082', 'hex'), ) const browseRes = await handleFilesystemRoute( '/api/filesystem/browse', makeUrl('/api/filesystem/browse', { path: canonicalTmpDir, includeFiles: 'true', }), ) expect(browseRes.status).toBe(200) const browseBody = await browseRes.json() as { entries: Array<{ name: string }> } expect(browseBody.entries.some((entry) => entry.name === 'preview.png')).toBe(true) const fileRes = await handleFilesystemRoute( '/api/filesystem/file', makeUrl('/api/filesystem/file', { path: imagePath, }), ) expect(fileRes.status).toBe(200) expect(fileRes.headers.get('Content-Type')).toBe('image/png') }) })