fix(tui): better footer subagent link and alignment (#1283)
This commit is contained in:
@@ -267,7 +267,7 @@ const InputFooter = memo(function InputFooter({
|
|||||||
|
|
||||||
// Subscribe to subagent state for background agent indicators
|
// Subscribe to subagent state for background agent indicators
|
||||||
useSyncExternalStore(subscribeToSubagents, getSubagentSnapshot);
|
useSyncExternalStore(subscribeToSubagents, getSubagentSnapshot);
|
||||||
const backgroundAgents = getActiveBackgroundAgents();
|
const backgroundAgents = [...getActiveBackgroundAgents()];
|
||||||
|
|
||||||
// Tick counter for elapsed time display (only active when background agents exist)
|
// Tick counter for elapsed time display (only active when background agents exist)
|
||||||
const [, setTick] = useState(0);
|
const [, setTick] = useState(0);
|
||||||
@@ -277,26 +277,18 @@ const InputFooter = memo(function InputFooter({
|
|||||||
return () => clearInterval(t);
|
return () => clearInterval(t);
|
||||||
}, [backgroundAgents.length]);
|
}, [backgroundAgents.length]);
|
||||||
|
|
||||||
// Build background agent display text (no useMemo — must recalculate each tick for elapsed time)
|
// Background agent display parts for the footer indicator
|
||||||
const bgAgentText =
|
const bgAgentParts = backgroundAgents.map((a) => {
|
||||||
backgroundAgents.length === 0
|
|
||||||
? ""
|
|
||||||
: backgroundAgents
|
|
||||||
.map((a) => {
|
|
||||||
const elapsedS = Math.round((Date.now() - a.startTime) / 1000);
|
const elapsedS = Math.round((Date.now() - a.startTime) / 1000);
|
||||||
const agentId = a.agentURL?.match(/\/agents\/([^/]+)/)?.[1];
|
const agentId =
|
||||||
const chatUrl = agentId ? buildChatUrl(agentId) : null;
|
a.agentURL?.match(/\/(?:agents|chat)\/([^/?#]+)/)?.[1] ?? null;
|
||||||
const typeLabel = a.type.toLowerCase();
|
return {
|
||||||
const linkedType = chatUrl
|
id: a.id,
|
||||||
? `\x1b]8;;${chatUrl}\x1b\\${typeLabel}\x1b]8;;\x1b\\`
|
typeLabel: a.type.toLowerCase(),
|
||||||
: typeLabel;
|
chatUrl: agentId ? buildChatUrl(agentId) : null,
|
||||||
return `${linkedType} (${elapsedS}s)`;
|
elapsed: `${elapsedS}s`,
|
||||||
})
|
};
|
||||||
.join(" · ");
|
});
|
||||||
|
|
||||||
// Width of the background agent indicator: "· " + text + " │ "
|
|
||||||
const bgIndicatorWidth =
|
|
||||||
backgroundAgents.length > 0 ? 2 + stringWidth(bgAgentText) + 3 : 0;
|
|
||||||
|
|
||||||
const maxAgentChars = Math.max(10, Math.floor(rightColumnWidth * 0.45));
|
const maxAgentChars = Math.max(10, Math.floor(rightColumnWidth * 0.45));
|
||||||
const displayAgentName = truncateEnd(agentName || "Unnamed", maxAgentChars);
|
const displayAgentName = truncateEnd(agentName || "Unnamed", maxAgentChars);
|
||||||
@@ -309,11 +301,32 @@ const InputFooter = memo(function InputFooter({
|
|||||||
|
|
||||||
const maxModelChars = Math.max(8, rightColumnWidth - baseReservedChars);
|
const maxModelChars = Math.max(8, rightColumnWidth - baseReservedChars);
|
||||||
const displayModel = truncateEnd(modelWithReasoning, maxModelChars);
|
const displayModel = truncateEnd(modelWithReasoning, maxModelChars);
|
||||||
|
|
||||||
const rightTextLength =
|
const rightTextLength =
|
||||||
displayAgentName.length + displayModel.length + byokExtraChars + 3;
|
displayAgentName.length + displayModel.length + byokExtraChars + 3;
|
||||||
const rightPrefixSpaces = Math.max(0, rightColumnWidth - rightTextLength);
|
const rightPrefixSpaces = Math.max(0, rightColumnWidth - rightTextLength);
|
||||||
|
|
||||||
|
// When bg agents are active, widen the right column to fit the indicator + label
|
||||||
|
// "· " (2) + parts text + " │ " (3)
|
||||||
|
const bgIndicatorWidth =
|
||||||
|
backgroundAgents.length > 0
|
||||||
|
? 2 +
|
||||||
|
bgAgentParts.reduce(
|
||||||
|
(acc, p, i) =>
|
||||||
|
acc +
|
||||||
|
(i > 0 ? 3 : 0) +
|
||||||
|
p.typeLabel.length +
|
||||||
|
1 +
|
||||||
|
p.elapsed.length +
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
) +
|
||||||
|
3
|
||||||
|
: 0;
|
||||||
|
const effectiveRightWidth =
|
||||||
|
backgroundAgents.length > 0
|
||||||
|
? Math.max(rightColumnWidth, bgIndicatorWidth + rightTextLength)
|
||||||
|
: rightColumnWidth;
|
||||||
|
|
||||||
// Agent label without leading spaces (used by both default and bg-agent cases)
|
// Agent label without leading spaces (used by both default and bg-agent cases)
|
||||||
const rightLabelCore = useMemo(() => {
|
const rightLabelCore = useMemo(() => {
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
@@ -387,7 +400,9 @@ const InputFooter = memo(function InputFooter({
|
|||||||
statusLineRight && !hideFooterContent ? "flex-end" : undefined
|
statusLineRight && !hideFooterContent ? "flex-end" : undefined
|
||||||
}
|
}
|
||||||
width={
|
width={
|
||||||
statusLineRight && !hideFooterContent ? undefined : rightColumnWidth
|
statusLineRight && !hideFooterContent
|
||||||
|
? undefined
|
||||||
|
: effectiveRightWidth
|
||||||
}
|
}
|
||||||
flexShrink={0}
|
flexShrink={0}
|
||||||
>
|
>
|
||||||
@@ -401,9 +416,26 @@ const InputFooter = memo(function InputFooter({
|
|||||||
))
|
))
|
||||||
) : backgroundAgents.length > 0 ? (
|
) : backgroundAgents.length > 0 ? (
|
||||||
<Text>
|
<Text>
|
||||||
{" ".repeat(Math.max(0, rightPrefixSpaces - bgIndicatorWidth))}
|
|
||||||
<BlinkDot color={colors.tool.pending} symbol="·" />
|
<BlinkDot color={colors.tool.pending} symbol="·" />
|
||||||
<Text dimColor>{` ${bgAgentText} │ `}</Text>
|
<Text dimColor> </Text>
|
||||||
|
{bgAgentParts.map((part, i) => (
|
||||||
|
<Text key={`bg-agent-${part}`}>
|
||||||
|
{i > 0 && (
|
||||||
|
<Text key={`bg-agent-indicator-${part}`} dimColor>
|
||||||
|
{" · "}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
{part.chatUrl ? (
|
||||||
|
<Link url={part.chatUrl}>
|
||||||
|
<Text dimColor>{part.typeLabel}</Text>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<Text dimColor>{part.typeLabel}</Text>
|
||||||
|
)}
|
||||||
|
<Text dimColor> ({part.elapsed})</Text>
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
<Text dimColor>{" │ "}</Text>
|
||||||
{rightLabelCore}
|
{rightLabelCore}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
Reference in New Issue
Block a user