Skip to content

Commit db8996f

Browse files
committed
refactor: improve timer architecture and connection checking
- Refactored elapsed time tracking to pass timer objects directly instead of timestamps - Removed useElapsedTimeFrom hook in favor of direct timer object usage - Updated StatusIndicator and MessageBlock to accept ElapsedTimeTracker - Fixed useConnectionStatus to always return boolean instead of boolean | null - Implemented real health check in SDK checkConnection method - Now hits /healthz endpoint with 5s timeout - Returns true only if response is OK and body is 'ok' - Un-deprecated the method since it now has real functionality Benefits: - Single timer instance shared across components (no duplicate timers) - No unnecessary re-renders from unstable dependencies - Clearer architecture and ready for multiple timers in the future
1 parent 6351db0 commit db8996f

File tree

6 files changed

+217
-207
lines changed

6 files changed

+217
-207
lines changed

cli/src/chat.tsx

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -278,24 +278,28 @@ export const App = ({
278278
? repoRoot // If outside home dir, show absolute path
279279
: `~/${relativePath}`
280280

281+
const handleActivateRepoPath = async () => {
282+
await openFileAtPath(repoRoot)
283+
}
284+
285+
const renderRepoPathInfo = () => (
286+
<box style={{ flexDirection: 'row', gap: 0, flexWrap: 'wrap' }}>
287+
<text wrap={false}>Codebuff can read and write files in </text>
288+
<TerminalLink
289+
text={displayPath}
290+
color="#3b82f6"
291+
inline={false}
292+
lineWrap={false}
293+
containerStyle={{ flexDirection: 'row', width: 'auto' }}
294+
onActivate={handleActivateRepoPath}
295+
/>
296+
<text wrap={false}>, and run terminal commands to help you build.</text>
297+
</box>
298+
)
299+
281300
blocks.push({
282301
type: 'html',
283-
render: () => (
284-
<box style={{ flexDirection: 'row', gap: 0, flexWrap: 'wrap' }}>
285-
<text wrap={false}>Codebuff can read and write files in </text>
286-
<TerminalLink
287-
text={displayPath}
288-
color="#3b82f6"
289-
inline={false}
290-
lineWrap={false}
291-
containerStyle={{ flexDirection: 'row', width: 'auto' }}
292-
onActivate={async () => {
293-
await openFileAtPath(repoRoot)
294-
}}
295-
/>
296-
<text wrap={false}>, and run terminal commands to help you build.</text>
297-
</box>
298-
),
302+
render: renderRepoPathInfo,
299303
})
300304

301305
blocks.push({
@@ -857,7 +861,7 @@ export const App = ({
857861
const hasStatus = useHasStatus(
858862
isStatusActive,
859863
clipboardMessage,
860-
mainAgentTimer.startTime,
864+
mainAgentTimer,
861865
)
862866

863867
const handleSubmit = useCallback(() => {
@@ -988,7 +992,7 @@ export const App = ({
988992
collapsedAgents,
989993
streamingAgents,
990994
isWaitingForResponse,
991-
streamStartTime: mainAgentTimer.startTime,
995+
timer: mainAgentTimer,
992996
setCollapsedAgents,
993997
setFocusedAgentId,
994998
registerAgentRef,
@@ -1016,7 +1020,7 @@ export const App = ({
10161020
theme={theme}
10171021
clipboardMessage={clipboardMessage}
10181022
isActive={isStatusActive}
1019-
streamStartTime={mainAgentTimer.startTime}
1023+
timer={mainAgentTimer}
10201024
/>
10211025
)
10221026

@@ -1043,13 +1047,39 @@ export const App = ({
10431047
}
10441048

10451049
// Get agent info by ID
1050+
const createAgentInfoEntry = (
1051+
agent: any,
1052+
): [string, LocalAgentInfo] => [agent.id, agent as LocalAgentInfo]
1053+
10461054
const agentInfoById = new Map<string, LocalAgentInfo>(
1047-
(loadedAgentsData?.agents.map((agent) => [
1048-
agent.id,
1049-
agent as LocalAgentInfo,
1050-
]) || []) as [string, LocalAgentInfo][],
1055+
(loadedAgentsData?.agents.map(createAgentInfoEntry) ||
1056+
[]) as [string, LocalAgentInfo][],
10511057
)
10521058

1059+
const formatErrorLine = (
1060+
error: { id: string; message: string },
1061+
index: number,
1062+
): string => {
1063+
const agentId = error.id.replace(/_\d+$/, '')
1064+
const agentInfo = agentInfoById.get(agentId)
1065+
const relativePath = agentInfo
1066+
? normalizeRelativePath(agentInfo.filePath)
1067+
: null
1068+
1069+
const { fieldName, message } = formatValidationError(error.message)
1070+
const errorMsg = fieldName ? `${fieldName}: ${message}` : message
1071+
const truncatedMsg =
1072+
errorMsg.length > 68 ? errorMsg.substring(0, 65) + '...' : errorMsg
1073+
1074+
let output = index === 0 ? '\n' : '\n\n'
1075+
output += agentId
1076+
if (relativePath) {
1077+
output += ` (${relativePath})`
1078+
}
1079+
output += '\n ' + truncatedMsg
1080+
return output
1081+
}
1082+
10531083
return (
10541084
<box
10551085
style={{
@@ -1081,25 +1111,7 @@ export const App = ({
10811111

10821112
{/* Error list - build as single text with newlines */}
10831113
<text wrap style={{ fg: theme.messageAiText }}>
1084-
{visibleErrors.map((error, index) => {
1085-
const agentId = error.id.replace(/_\d+$/, '')
1086-
const agentInfo = agentInfoById.get(agentId)
1087-
const relativePath = agentInfo
1088-
? normalizeRelativePath(agentInfo.filePath)
1089-
: null
1090-
1091-
const { fieldName, message } = formatValidationError(error.message)
1092-
const errorMsg = fieldName ? `${fieldName}: ${message}` : message
1093-
const truncatedMsg = errorMsg.length > 68 ? errorMsg.substring(0, 65) + '...' : errorMsg
1094-
1095-
let output = index === 0 ? '\n' : '\n\n'
1096-
output += agentId
1097-
if (relativePath) {
1098-
output += ` (${relativePath})`
1099-
}
1100-
output += '\n ' + truncatedMsg
1101-
return output
1102-
}).join('')}
1114+
{visibleErrors.map(formatErrorLine).join('')}
11031115
</text>
11041116

11051117
{/* Show count of additional errors */}

0 commit comments

Comments
 (0)