mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(ui): rank a search hit by its name in the index too
Since the branch node reads "cbm · working tree", a search for "working" ranked it behind the folders of the other hits and cut it from the list. Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
This commit is contained in:
1 parent
ff3e88b238
commit
0f9340d883
2 files changed
+31
-2
No files matched your search
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { choicesFromSearchHits, searchPriority } from './GalaxyNavigator';
|
||||
|
||||
/*
|
||||
* Handtest 04.10. (abends): In cbm fand "working" den Branch-Knoten nicht mehr.
|
||||
* Seit er "cbm · working tree" heisst, beginnt sein gezeigter Name nicht mit dem
|
||||
* Suchwort, und die Ordner der anderen Treffer schoben ihn aus den zwoelf Plaetzen.
|
||||
* Sein Name im Index ("working-tree") zaehlt wie der gezeigte.
|
||||
*/
|
||||
describe('search priority', () => {
|
||||
const [branch] = choicesFromSearchHits([{ qualified_name: 'cbm.__branch__.working-tree', name: 'working-tree', label: 'Branch', file_path: '{}' } as never]);
|
||||
|
||||
it('ranks a hit whose name in the index starts with the search word with the name matches', () => {
|
||||
expect(branch.name).toBe('cbm · working tree');
|
||||
expect(searchPriority(branch, 'working')).toBe(1);
|
||||
expect(searchPriority(branch, 'working-tree')).toBe(0);
|
||||
});
|
||||
|
||||
it('keeps folders behind name matches and other hits behind folders', () => {
|
||||
const folder = { key: 'docs/', name: 'docs/', detail: 'Indexed folder', kind: 'Folder', scope: { kind: 'folder' as const, path: 'docs', name: 'docs/' } };
|
||||
expect(searchPriority(folder, 'working')).toBe(2);
|
||||
expect(searchPriority({ ...branch, name: 'other', scope: { kind: 'symbol' as const, qualifiedName: 'a.b', name: 'other' } }, 'working')).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -32,6 +32,12 @@ export function choicesFromSearchHits(hits: readonly SearchGraphHit[]): Choice[]
|
||||
}
|
||||
return [...choices.values()];
|
||||
}
|
||||
/** Exact names first, then names that start with the search word, then folders and files, then the rest.
|
||||
* The name in the index counts like the shown one: "cbm · working tree" is "working-tree" there. */
|
||||
export function searchPriority(choice: Choice, needle: string): number {
|
||||
const names = [choice.name, 'name' in choice.scope ? choice.scope.name : undefined].filter((name): name is string => Boolean(name)).map(name => name.toLocaleLowerCase());
|
||||
return names.includes(needle) ? 0 : names.some(name => name.startsWith(needle)) ? 1 : choice.kind === 'Folder' || choice.kind === 'File' ? 2 : 3;
|
||||
}
|
||||
/** One search for graph symbols and file/folder clusters, including unloaded symbols. */
|
||||
export default function GalaxyNavigator({ nodes, onSelect, onSelectScope, project, fetch: fetchImpl, embedded = false }: {
|
||||
nodes: readonly GraphNode[]; onSelect: (node: GraphNode) => void; onSelectScope?: (scope: GraphScope) => void;
|
||||
@@ -97,8 +103,7 @@ export default function GalaxyNavigator({ nodes, onSelect, onSelectScope, projec
|
||||
choices.push({ key: path, name: path, detail: `${count.toLocaleString()} loaded nodes`, kind: folder ? 'Folder' : 'File',
|
||||
scope: { kind: folder ? 'folder' : 'file', path: path.replace(/\/$/, ''), name: path } });
|
||||
}
|
||||
const priority = (choice: Choice) => choice.name.toLocaleLowerCase() === needle ? 0
|
||||
: choice.name.toLocaleLowerCase().startsWith(needle) ? 1 : choice.kind === 'Folder' || choice.kind === 'File' ? 2 : 3;
|
||||
const priority = (choice: Choice) => searchPriority(choice, needle);
|
||||
const unique = new Map(choices.map(choice => [choice.key, choice]));
|
||||
for (const choice of remote) if (!unique.has(choice.key)) unique.set(choice.key, choice);
|
||||
return [...unique.values()].sort((a, b) => priority(a) - priority(b) || a.name.localeCompare(b.name)).slice(0, 12);
|
||||
|
||||
Reference in new issue
Block a user