Preserve tree selection when returning from summary selector or abort

This commit is contained in:
Mario Zechner 2026-01-12 00:15:12 +01:00
parent a0311fd5b9
commit c16e21331a
2 changed files with 19 additions and 11 deletions

View file

@ -62,7 +62,12 @@ class TreeList implements Component {
public onCancel?: () => void; public onCancel?: () => void;
public onLabelEdit?: (entryId: string, currentLabel: string | undefined) => void; public onLabelEdit?: (entryId: string, currentLabel: string | undefined) => void;
constructor(tree: SessionTreeNode[], currentLeafId: string | null, maxVisibleLines: number) { constructor(
tree: SessionTreeNode[],
currentLeafId: string | null,
maxVisibleLines: number,
initialSelectedId?: string,
) {
this.currentLeafId = currentLeafId; this.currentLeafId = currentLeafId;
this.maxVisibleLines = maxVisibleLines; this.maxVisibleLines = maxVisibleLines;
this.multipleRoots = tree.length > 1; this.multipleRoots = tree.length > 1;
@ -70,10 +75,11 @@ class TreeList implements Component {
this.buildActivePath(); this.buildActivePath();
this.applyFilter(); this.applyFilter();
// Start with current leaf selected // Start with initialSelectedId if provided, otherwise current leaf
const leafIndex = this.filteredNodes.findIndex((n) => n.node.entry.id === currentLeafId); const targetId = initialSelectedId ?? currentLeafId;
if (leafIndex !== -1) { const targetIndex = this.filteredNodes.findIndex((n) => n.node.entry.id === targetId);
this.selectedIndex = leafIndex; if (targetIndex !== -1) {
this.selectedIndex = targetIndex;
} else { } else {
this.selectedIndex = Math.max(0, this.filteredNodes.length - 1); this.selectedIndex = Math.max(0, this.filteredNodes.length - 1);
} }
@ -788,13 +794,14 @@ export class TreeSelectorComponent extends Container {
onSelect: (entryId: string) => void, onSelect: (entryId: string) => void,
onCancel: () => void, onCancel: () => void,
onLabelChange?: (entryId: string, label: string | undefined) => void, onLabelChange?: (entryId: string, label: string | undefined) => void,
initialSelectedId?: string,
) { ) {
super(); super();
this.onLabelChangeCallback = onLabelChange; this.onLabelChangeCallback = onLabelChange;
const maxVisibleLines = Math.max(5, Math.floor(terminalHeight / 2)); const maxVisibleLines = Math.max(5, Math.floor(terminalHeight / 2));
this.treeList = new TreeList(tree, currentLeafId, maxVisibleLines); this.treeList = new TreeList(tree, currentLeafId, maxVisibleLines, initialSelectedId);
this.treeList.onSelect = onSelect; this.treeList.onSelect = onSelect;
this.treeList.onCancel = onCancel; this.treeList.onCancel = onCancel;
this.treeList.onLabelEdit = (entryId, currentLabel) => this.showLabelInput(entryId, currentLabel); this.treeList.onLabelEdit = (entryId, currentLabel) => this.showLabelInput(entryId, currentLabel);

View file

@ -2773,7 +2773,7 @@ export class InteractiveMode {
}); });
} }
private showTreeSelector(): void { private showTreeSelector(initialSelectedId?: string): void {
const tree = this.sessionManager.getTree(); const tree = this.sessionManager.getTree();
const realLeafId = this.sessionManager.getLeafId(); const realLeafId = this.sessionManager.getLeafId();
@ -2819,8 +2819,8 @@ export class InteractiveMode {
]); ]);
if (summaryChoice === undefined) { if (summaryChoice === undefined) {
// User pressed escape - re-show tree selector // User pressed escape - re-show tree selector with same selection
this.showTreeSelector(); this.showTreeSelector(entryId);
return; return;
} }
@ -2864,9 +2864,9 @@ export class InteractiveMode {
}); });
if (result.aborted) { if (result.aborted) {
// Summarization aborted - re-show tree selector // Summarization aborted - re-show tree selector with same selection
this.showStatus("Branch summarization cancelled"); this.showStatus("Branch summarization cancelled");
this.showTreeSelector(); this.showTreeSelector(entryId);
return; return;
} }
if (result.cancelled) { if (result.cancelled) {
@ -2899,6 +2899,7 @@ export class InteractiveMode {
this.sessionManager.appendLabelChange(entryId, label); this.sessionManager.appendLabelChange(entryId, label);
this.ui.requestRender(); this.ui.requestRender();
}, },
initialSelectedId,
); );
return { component: selector, focus: selector }; return { component: selector, focus: selector };
}); });