Describe the Bug
In packages/web/src/features/git/utils.ts, buildFileTree constructs a nested FileTreeNode hierarchy from a flat list of { type, path } objects.
When creating intermediate directory nodes (lines 68-74), the new node's path property is assigned item.path (the full path of the current leaf file being processed), instead of the path of that directory:
// packages/web/src/features/git/utils.ts:67-75
if (!next) {
next = {
name: part,
path: item.path, // <--- Bug: assigns leaf file's path to intermediate directory node
type: nodeType,
children: [],
};
current.children.push(next);
}
Impact
- Broken Folder State & Expansion in UI: In
packages/web/src/app/(app)/browse/components/fileTreePanel.tsx, folder expand/collapse state is tracked via openPaths.has(node.path) and route sync via pathParts.slice(0, i + 1).join('/'). Because directory nodes receive the child file's path instead of their own directory path, clicking folders or deep-linking to nested paths causes folder state tracking and auto-expansion to fail.
- Public API Corruption: The
getTree endpoint (/api/git/tree) returns FileTreeNode with corrupted directory paths to API consumers.
Reproduction
const flatList = [
{ type: 'blob', path: 'src/components/buttons/PrimaryButton.tsx' }
];
const tree = buildFileTree(flatList);
const srcDir = tree.children[0];
console.log(srcDir.name); // "src"
console.log(srcDir.path); // Expected "src", but Got "src/components/buttons/PrimaryButton.tsx"
Proposed Fix
Reconstruct the directory node's path using parts.slice(0, i + 1).join('/'):
if (!next) {
next = {
name: part,
path: parts.slice(0, i + 1).join('/'),
type: nodeType,
children: [],
};
current.children.push(next);
}
For intermediate directory levels (i < parts.length - 1), this evaluates to the proper directory path (e.g. "src", "src/components"), and for leaf files (i === parts.length - 1), it matches item.path.
Describe the Bug
In
packages/web/src/features/git/utils.ts,buildFileTreeconstructs a nestedFileTreeNodehierarchy from a flat list of{ type, path }objects.When creating intermediate directory nodes (lines 68-74), the new node's
pathproperty is assigneditem.path(the full path of the current leaf file being processed), instead of the path of that directory:Impact
packages/web/src/app/(app)/browse/components/fileTreePanel.tsx, folder expand/collapse state is tracked viaopenPaths.has(node.path)and route sync viapathParts.slice(0, i + 1).join('/'). Because directory nodes receive the child file's path instead of their own directory path, clicking folders or deep-linking to nested paths causes folder state tracking and auto-expansion to fail.getTreeendpoint (/api/git/tree) returnsFileTreeNodewith corrupted directory paths to API consumers.Reproduction
Proposed Fix
Reconstruct the directory node's path using
parts.slice(0, i + 1).join('/'):For intermediate directory levels (
i < parts.length - 1), this evaluates to the proper directory path (e.g."src","src/components"), and for leaf files (i === parts.length - 1), it matchesitem.path.