mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
Desktop @ file search was recursively walking the filesystem with a local skip list, which let Python and Node generated directories leak into results and diverged from CLI behavior. Route candidate discovery through the same git-first model: tracked files, untracked files with exclude-standard, and ripgrep fallback for non-git folders, then derive selectable directories from those candidates. Constraint: Desktop picker must select both files and directories without surfacing ignored project artifacts. Constraint: No new dependencies; reuse the existing git, ripgrep, settings, and ignore utilities. Rejected: Maintain a hardcoded directory denylist | it would drift from CLI and miss project-specific ignore rules. Rejected: Full recursive readdir scanning | it ignores git index semantics and makes large dependency trees visible. Confidence: high Scope-risk: moderate Directive: Keep desktop @ file candidate discovery aligned with src/hooks/fileSuggestions.ts before changing ranking or ignore behavior. Tested: bun test src/server/__tests__/filesystem.test.ts Tested: cd desktop && bun run test -- FileSearchMenu.test.tsx ChatInput.test.tsx Tested: cd desktop && bun run lint && bun run test -- --run && bun run build Tested: bun run check:server Tested: bun run check:coverage Tested: bun run verify Not-tested: Native Windows/Linux manual UI smoke; path handling relies on cross-platform git/ripgrep wrappers and normalized relative paths.
32 lines
814 B
TypeScript
32 lines
814 B
TypeScript
import { api } from './client'
|
|
|
|
type DirEntry = {
|
|
name: string
|
|
path: string
|
|
isDirectory: boolean
|
|
relativePath?: string
|
|
}
|
|
|
|
type BrowseResult = {
|
|
currentPath: string
|
|
parentPath: string
|
|
entries: DirEntry[]
|
|
query?: string
|
|
}
|
|
|
|
export const filesystemApi = {
|
|
browse(path?: string, options?: { includeFiles?: boolean }) {
|
|
const q = new URLSearchParams()
|
|
if (path) q.set('path', path)
|
|
if (options?.includeFiles) q.set('includeFiles', 'true')
|
|
const qs = q.toString()
|
|
return api.get<BrowseResult>(`/api/filesystem/browse${qs ? `?${qs}` : ''}`)
|
|
},
|
|
|
|
search(query: string, cwd?: string) {
|
|
const q = new URLSearchParams({ search: query, maxResults: '200', includeFiles: 'true' })
|
|
if (cwd) q.set('path', cwd)
|
|
return api.get<BrowseResult>(`/api/filesystem/browse?${q}`)
|
|
},
|
|
}
|