Skip to content

Commit 263937a

Browse files
committed
Merge remote-tracking branch 'origin/main' into jahooma/evalbuff-quality
2 parents af14ae3 + d6a3db3 commit 263937a

File tree

7 files changed

+750
-33
lines changed

7 files changed

+750
-33
lines changed

cli/src/__tests__/e2e-cli.test.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,28 @@ describe.skipIf(!sdkBuilt)('CLI End-to-End Tests', () => {
8080
test(
8181
'CLI accepts --agent flag',
8282
async () => {
83-
// Note: This will timeout and exit because we can't interact with stdin
84-
// But we can verify it starts without errors
83+
// Verify the CLI starts without errors when given --agent flag.
84+
// The CLI goes through full initialization (agent registry, skill registry,
85+
// renderer creation) before producing any piped output, so we need a
86+
// generous timeout. We also treat "process still alive" as success.
8587
const proc = spawn('bun', ['run', CLI_PATH, '--agent', 'ask'], {
8688
cwd: path.join(__dirname, '../..'),
8789
stdio: 'pipe',
8890
})
8991

9092
let started = false
93+
let exitedEarly = false
94+
proc.once('exit', () => {
95+
if (!started) exitedEarly = true
96+
})
97+
9198
await new Promise<void>((resolve) => {
9299
const timeout = setTimeout(() => {
100+
// Process is still alive after wait — it started successfully
101+
if (!exitedEarly) started = true
93102
resolve()
94-
}, 2000) // Increased timeout for CI environments
103+
}, 8000)
95104

96-
// Check both stdout and stderr - CLI may output to either
97105
proc.stdout?.once('data', () => {
98106
started = true
99107
clearTimeout(timeout)
@@ -122,12 +130,17 @@ describe.skipIf(!sdkBuilt)('CLI End-to-End Tests', () => {
122130
})
123131

124132
let started = false
133+
let exitedEarly = false
134+
proc.once('exit', () => {
135+
if (!started) exitedEarly = true
136+
})
137+
125138
await new Promise<void>((resolve) => {
126139
const timeout = setTimeout(() => {
140+
if (!exitedEarly) started = true
127141
resolve()
128-
}, 2000) // Increased timeout for CI environments
142+
}, 8000)
129143

130-
// Check both stdout and stderr - CLI may output to either
131144
proc.stdout?.once('data', () => {
132145
started = true
133146
clearTimeout(timeout)

cli/src/chat.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,6 +1440,7 @@ export const Chat = ({
14401440
isAtBottom={isAtBottom}
14411441
scrollToLatest={scrollToLatest}
14421442
statusIndicatorState={statusIndicatorState}
1443+
onStop={chatKeyboardHandlers.onInterruptStream}
14431444
/>
14441445
)}
14451446

cli/src/components/status-bar.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'
22

33
import { ScrollToBottomButton } from './scroll-to-bottom-button'
44
import { ShimmerText } from './shimmer-text'
5+
import { StopButton } from './stop-button'
56
import { useTheme } from '../hooks/use-theme'
67
import { formatElapsedTime } from '../utils/format-elapsed-time'
78

@@ -15,13 +16,15 @@ interface StatusBarProps {
1516
isAtBottom: boolean
1617
scrollToLatest: () => void
1718
statusIndicatorState: StatusIndicatorState
19+
onStop?: () => void
1820
}
1921

2022
export const StatusBar = ({
2123
timerStartTime,
2224
isAtBottom,
2325
scrollToLatest,
2426
statusIndicatorState,
27+
onStop,
2528
}: StatusBarProps) => {
2629
const theme = useTheme()
2730
const [elapsedSeconds, setElapsedSeconds] = useState(0)
@@ -161,9 +164,14 @@ export const StatusBar = ({
161164
flexBasis: 0,
162165
flexDirection: 'row',
163166
justifyContent: 'flex-end',
167+
alignItems: 'center',
168+
gap: 1,
164169
}}
165170
>
166171
<text style={{ wrapMode: 'none' }}>{elapsedTimeContent}</text>
172+
{onStop && (statusIndicatorState.kind === 'waiting' || statusIndicatorState.kind === 'streaming') && (
173+
<StopButton onClick={onStop} />
174+
)}
167175
</box>
168176
</box>
169177
)

cli/src/components/stop-button.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { TextAttributes } from '@opentui/core'
2+
import { useState } from 'react'
3+
4+
import { Button } from './button'
5+
import { useTheme } from '../hooks/use-theme'
6+
7+
interface StopButtonProps {
8+
onClick: () => void
9+
}
10+
11+
export const StopButton = ({ onClick }: StopButtonProps) => {
12+
const theme = useTheme()
13+
const [hovered, setHovered] = useState(false)
14+
15+
return (
16+
<Button
17+
style={{ paddingLeft: 1, paddingRight: 1 }}
18+
onClick={onClick}
19+
onMouseOver={() => setHovered(true)}
20+
onMouseOut={() => setHovered(false)}
21+
>
22+
<text>
23+
<span
24+
fg={theme.secondary}
25+
attributes={hovered ? TextAttributes.BOLD : TextAttributes.DIM}
26+
>
27+
■ Stop
28+
</span>
29+
</text>
30+
</Button>
31+
)
32+
}

0 commit comments

Comments
 (0)