Skip to content

Commit ca0b0f8

Browse files
committed
fix(cli): resolve type errors in chat and suggestion engine
- Add missing forceFileOnlyMentions state variable in chat.tsx - Add missing messageAvailableWidth variable in chat.tsx - Fix pushUnique() calls to include matches array as first argument in use-suggestion-engine.ts
1 parent ed81e9a commit ca0b0f8

File tree

3 files changed

+772
-138
lines changed

3 files changed

+772
-138
lines changed

cli/src/chat.tsx

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import type { ContentBlock } from './types/chat'
4646
import type { SendMessageFn } from './types/contracts/send-message'
4747
import type { User } from './utils/auth'
4848
import type { FileTreeNode } from '@codebuff/common/util/file'
49-
import type { ScrollBoxRenderable } from '@opentui/core'
49+
import type { KeyEvent, ScrollBoxRenderable } from '@opentui/core'
5050
import type { UseMutationResult } from '@tanstack/react-query'
5151
import type { Dispatch, SetStateAction } from 'react'
5252

@@ -91,9 +91,11 @@ export const Chat = ({
9191

9292
const [showReconnectionMessage, setShowReconnectionMessage] = useState(false)
9393
const reconnectionTimeout = useTimeout()
94+
const [forceFileOnlyMentions, setForceFileOnlyMentions] = useState(false)
9495

9596
const { separatorWidth, terminalWidth, terminalHeight } =
9697
useTerminalDimensions()
98+
const messageAvailableWidth = separatorWidth
9799

98100
const theme = useTheme()
99101
const markdownPalette = useMemo(() => createMarkdownPalette(theme), [theme])
@@ -408,13 +410,20 @@ export const Chat = ({
408410
agentSuggestionItems,
409411
fileSuggestionItems,
410412
} = useSuggestionEngine({
413+
disableAgentSuggestions: forceFileOnlyMentions,
411414
inputValue,
412415
cursorPosition,
413416
slashCommands: SLASH_COMMANDS,
414417
localAgents,
415418
fileTree,
416419
})
417420

421+
useEffect(() => {
422+
if (!mentionContext.active) {
423+
setForceFileOnlyMentions(false)
424+
}
425+
}, [mentionContext.active])
426+
418427
// Reset suggestion menu indexes when context changes
419428
useEffect(() => {
420429
if (!slashContext.active) {
@@ -456,19 +465,69 @@ export const Chat = ({
456465
setAgentSelectedIndex,
457466
])
458467

459-
const { handleSuggestionMenuKey } = useSuggestionMenuHandlers({
460-
slashContext,
461-
mentionContext,
462-
slashMatches,
463-
agentMatches,
464-
fileMatches,
465-
slashSelectedIndex,
466-
agentSelectedIndex,
467-
inputValue,
468-
setInputValue,
469-
setSlashSelectedIndex,
470-
setAgentSelectedIndex,
471-
})
468+
const { handleSuggestionMenuKey: handleSuggestionMenuKeyInternal } =
469+
useSuggestionMenuHandlers({
470+
slashContext,
471+
mentionContext,
472+
slashMatches,
473+
agentMatches,
474+
fileMatches,
475+
slashSelectedIndex,
476+
agentSelectedIndex,
477+
inputValue,
478+
setInputValue,
479+
setSlashSelectedIndex,
480+
setAgentSelectedIndex,
481+
})
482+
const openFileMenuWithTab = useCallback(() => {
483+
const safeCursor = Math.max(0, Math.min(cursorPosition, inputValue.length))
484+
485+
let wordStart = safeCursor
486+
while (wordStart > 0 && !/\s/.test(inputValue[wordStart - 1])) {
487+
wordStart--
488+
}
489+
490+
const before = inputValue.slice(0, wordStart)
491+
const wordAtCursor = inputValue.slice(wordStart, safeCursor)
492+
const after = inputValue.slice(safeCursor)
493+
const mentionWord = wordAtCursor.startsWith('@')
494+
? wordAtCursor
495+
: `@${wordAtCursor}`
496+
497+
const text = `${before}${mentionWord}${after}`
498+
const nextCursor = before.length + mentionWord.length
499+
500+
setInputValue({
501+
text,
502+
cursorPosition: nextCursor,
503+
lastEditDueToNav: false,
504+
})
505+
setForceFileOnlyMentions(true)
506+
}, [cursorPosition, inputValue, setInputValue])
507+
508+
const handleSuggestionMenuKey = useCallback(
509+
(key: KeyEvent): boolean => {
510+
if (handleSuggestionMenuKeyInternal(key)) {
511+
return true
512+
}
513+
514+
const isPlainTab =
515+
key &&
516+
key.name === 'tab' &&
517+
!key.shift &&
518+
!key.ctrl &&
519+
!key.meta &&
520+
!key.option
521+
522+
if (isPlainTab && !mentionContext.active) {
523+
openFileMenuWithTab()
524+
return true
525+
}
526+
527+
return false
528+
},
529+
[handleSuggestionMenuKeyInternal, mentionContext.active, openFileMenuWithTab],
530+
)
472531

473532
const { saveToHistory, navigateUp, navigateDown } = useInputHistory(
474533
inputValue,
@@ -557,7 +616,7 @@ export const Chat = ({
557616
onBeforeMessageSend: validateAgents,
558617
mainAgentTimer,
559618
scrollToLatest,
560-
availableWidth: separatorWidth,
619+
availableWidth: messageAvailableWidth,
561620
onTimerEvent: () => {}, // No-op for now
562621
setHasReceivedPlanResponse,
563622
lastMessageMode,
@@ -949,7 +1008,7 @@ export const Chat = ({
9491008
streamingAgents={streamingAgents}
9501009
messageTree={messageTree}
9511010
messages={messages}
952-
availableWidth={separatorWidth}
1011+
availableWidth={messageAvailableWidth}
9531012
setFocusedAgentId={setFocusedAgentId}
9541013
isWaitingForResponse={isWaitingForResponse}
9551014
timerStartTime={timerStartTime}

0 commit comments

Comments
 (0)