@@ -14,7 +14,6 @@ import type {
1414
1515type ToolName = 'read_subtree'
1616
17-
1817export const handleReadSubtree = ( ( params : {
1918 previousToolCallFinished : Promise < void >
2019 toolCall : CodebuffToolCall < ToolName >
@@ -31,9 +30,44 @@ export const handleReadSubtree = ((params: {
3130 const allFiles = new Set ( getAllFilePaths ( fileContext . fileTree ) )
3231
3332 const buildDirectoryResult = ( dirNodes : FileTreeNode [ ] , outPath : string ) => {
33+ const subTree = deepClone ( dirNodes )
34+
35+ // Remap token scores so keys match the paths built by printFileTreeWithTokens.
36+ // When printFileTreeWithTokens walks a subtree starting from dirNodes,
37+ // it builds paths starting from the node names, not from an empty root.
38+ // So for a node with name 'backend' inside 'packages', the paths will be
39+ // 'backend/file.ts', not 'packages/backend/file.ts'.
40+ const remappedTokenScores : Record < string , Record < string , number > > = { }
41+ const prefix =
42+ outPath === '.' || outPath === '/' || outPath === ''
43+ ? ''
44+ : outPath . replace ( / \\ / g, '/' )
45+
46+ for ( const [ filePath , tokens ] of Object . entries (
47+ fileContext . fileTokenScores ,
48+ ) ) {
49+ const normalized = filePath . replace ( / \\ / g, '/' )
50+ if ( ! prefix || normalized . startsWith ( prefix + '/' ) ) {
51+ // Strip the parent path prefix and keep the dirBaseName + remainder
52+ const fullPrefix = prefix
53+ ? prefix . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' )
54+ : ''
55+ const afterParent = fullPrefix
56+ ? normalized . startsWith ( fullPrefix + '/' )
57+ ? normalized . slice ( fullPrefix . length + 1 )
58+ : null
59+ : normalized
60+
61+ if ( afterParent && ! afterParent . startsWith ( '../' ) ) {
62+ remappedTokenScores [ afterParent ] = tokens
63+ }
64+ }
65+ }
66+
3467 const subctx : ProjectFileContext = {
3568 ...fileContext ,
36- fileTree : deepClone ( dirNodes ) ,
69+ fileTree : subTree ,
70+ fileTokenScores : remappedTokenScores ,
3771 }
3872 const { printedTree, tokenCount, truncationLevel } =
3973 truncateFileTreeBasedOnTokenBudget ( {
0 commit comments