Skip to content

Commit a38fde3

Browse files
committed
[codecane] feat(cli): add agent status line and hover delay to mode toggle
- Add status line below input showing current agent display name - Look up agent name from loadedAgentsData based on mode - Map modes to default agent IDs (base2-fast, base2-max, base2-plan) - Add 250ms hover delay before opening toggle menu - Right-align agent status under toggle - Refactor agent ID lookup with object mapping
1 parent d466a3d commit a38fde3

File tree

2 files changed

+47
-19
lines changed

2 files changed

+47
-19
lines changed

cli/src/chat.tsx

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ import type { ScrollBoxRenderable } from '@opentui/core'
5757
const MAX_VIRTUALIZED_TOP_LEVEL = 60
5858
const VIRTUAL_OVERSCAN = 12
5959

60+
const DEFAULT_AGENT_IDS = {
61+
FAST: 'base2-fast',
62+
MAX: 'base2-max',
63+
PLAN: 'base2-plan',
64+
} as const
65+
6066
export const App = ({
6167
initialPrompt,
6268
agentId,
@@ -198,10 +204,6 @@ export const App = ({
198204
? repoRoot
199205
: `~/${relativePath}`
200206

201-
const agentSectionHeader = agentId
202-
? `**Active agent: ${agentId}**`
203-
: undefined
204-
205207
const buildBlocks = (listId: string): ContentBlock[] => {
206208
const blocks: ContentBlock[] = [
207209
{
@@ -244,16 +246,6 @@ export const App = ({
244246
agentsDir: loadedAgentsData.agentsDir,
245247
})
246248

247-
if (agentSectionHeader) {
248-
blocks.push({
249-
type: 'text',
250-
content: agentSectionHeader,
251-
marginTop: 1,
252-
marginBottom: 0,
253-
color: baseTextColor,
254-
})
255-
}
256-
257249
return blocks
258250
}
259251

@@ -390,6 +382,15 @@ export const App = ({
390382
})),
391383
)
392384

385+
// Get current agent display name based on mode
386+
const agentDisplayName = useMemo(() => {
387+
if (!loadedAgentsData) return null
388+
389+
const currentAgentId = agentId || DEFAULT_AGENT_IDS[agentMode]
390+
const agent = loadedAgentsData.agents.find((a) => a.id === currentAgentId)
391+
return agent?.displayName || currentAgentId
392+
}, [loadedAgentsData, agentId, agentMode])
393+
393394
// Handle successful login
394395
const handleLoginSuccess = useCallback(
395396
(loggedInUser: User) => {
@@ -1288,6 +1289,21 @@ export const App = ({
12881289
</box>
12891290
</box>
12901291
<Separator width={separatorWidth} />
1292+
{/* Agent status line - right-aligned under toggle */}
1293+
{loadedAgentsData && (
1294+
<box
1295+
style={{
1296+
flexDirection: 'row',
1297+
justifyContent: 'flex-end',
1298+
paddingRight: 1,
1299+
paddingTop: 0,
1300+
}}
1301+
>
1302+
<text>
1303+
<span fg={theme.muted}>Agent: {agentDisplayName}</span>
1304+
</text>
1305+
</box>
1306+
)}
12911307
</box>
12921308

12931309
{/* Login Modal Overlay - show when not authenticated and done checking */}

cli/src/components/agent-mode-toggle.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const AgentModeToggle = ({
3939
const config = getModeConfig(theme)
4040
const [isOpen, setIsOpen] = useState(false)
4141
const closeTimeoutRef = useRef<NodeJS.Timeout | null>(null)
42+
const openTimeoutRef = useRef<NodeJS.Timeout | null>(null)
4243

4344
const handlePress = (selectedMode: AgentMode) => {
4445
if (selectedMode === mode) {
@@ -61,10 +62,24 @@ export const AgentModeToggle = ({
6162
clearTimeout(closeTimeoutRef.current)
6263
closeTimeoutRef.current = null
6364
}
64-
setIsOpen(true)
65+
66+
// If already open, do nothing
67+
if (isOpen) return
68+
69+
// Delay opening by 500ms
70+
openTimeoutRef.current = setTimeout(() => {
71+
setIsOpen(true)
72+
openTimeoutRef.current = null
73+
}, 250)
6574
}
6675

6776
const handleMouseOut = () => {
77+
// Cancel any pending open
78+
if (openTimeoutRef.current) {
79+
clearTimeout(openTimeoutRef.current)
80+
openTimeoutRef.current = null
81+
}
82+
6883
// Delay closing by 1 second
6984
closeTimeoutRef.current = setTimeout(() => {
7085
setIsOpen(false)
@@ -111,10 +126,7 @@ export const AgentModeToggle = ({
111126
}
112127

113128
// Expanded state: show all modes with current mode rightmost
114-
const orderedModes = [
115-
...ALL_MODES.filter((m) => m !== mode),
116-
mode,
117-
]
129+
const orderedModes = [...ALL_MODES.filter((m) => m !== mode), mode]
118130

119131
// Calculate widths for each segment
120132
const segmentWidths = orderedModes.map((m) => {

0 commit comments

Comments
 (0)