Skip to content

Commit 836a937

Browse files
committed
Merge branch 'main' into subscription-client
2 parents 2053bb5 + 52d4a81 commit 836a937

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3475
-296
lines changed

agents/editor/best-of-n/editor-implementor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ IMPORTANT: Use propose_str_replace and propose_write_file tools to make your edi
4242
You can make multiple tool calls across multiple steps to complete the implementation. Only the file changes will be passed on, so you can say whatever you want to help you think. Do not write any final summary as that would be a waste of tokens because no one is reading it.
4343
<codebuff_tool_call>
4444
{
45-
"cb_tool_name": "str_replace",
45+
"cb_tool_name": "propose_str_replace",
4646
"path": "path/to/file",
4747
"replacements": [
4848
{
@@ -61,7 +61,7 @@ OR for new files or major rewrites:
6161
6262
<codebuff_tool_call>
6363
{
64-
"cb_tool_name": "write_file",
64+
"cb_tool_name": "propose_write_file",
6565
"path": "path/to/file",
6666
"instructions": "What the change does",
6767
"content": "Complete file content or edit snippet"

cli/release/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codebuff",
3-
"version": "1.0.606",
3+
"version": "1.0.607",
44
"description": "AI coding agent",
55
"license": "MIT",
66
"bin": {

cli/src/chat.tsx

Lines changed: 99 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { AdBanner } from './components/ad-banner'
1616
import { BottomStatusLine } from './components/bottom-status-line'
1717
import { ChatInputBar } from './components/chat-input-bar'
1818
import { LoadPreviousButton } from './components/load-previous-button'
19+
import { ReviewScreen } from './components/review-screen'
1920
import { MessageWithAgents } from './components/message-with-agents'
2021
import { areCreditsRestored } from './components/out-of-credits-banner'
2122
import { PendingBashMessage } from './components/pending-bash-message'
@@ -47,6 +48,7 @@ import { WEBSITE_URL } from './login/constants'
4748
import { getProjectRoot } from './project-files'
4849
import { useChatHistoryStore } from './state/chat-history-store'
4950
import { useChatStore } from './state/chat-store'
51+
import { useReviewStore } from './state/review-store'
5052
import { useFeedbackStore } from './state/feedback-store'
5153
import { useMessageBlockStore } from './state/message-block-store'
5254
import { usePublishStore } from './state/publish-store'
@@ -635,6 +637,13 @@ export const Chat = ({
635637
})),
636638
)
637639

640+
const { reviewMode, closeReviewScreen } = useReviewStore(
641+
useShallow((state) => ({
642+
reviewMode: state.reviewMode,
643+
closeReviewScreen: state.closeReviewScreen,
644+
})),
645+
)
646+
638647
const publishMutation = usePublishMutation()
639648

640649
const handleCommandResult = useCallback(
@@ -666,6 +675,10 @@ export const Chat = ({
666675
if (result.openChatHistory) {
667676
useChatHistoryStore.getState().openChatHistory()
668677
}
678+
679+
if (result.openReviewScreen) {
680+
useReviewStore.getState().openReviewScreen()
681+
}
669682
},
670683
[
671684
saveCurrentInput,
@@ -792,6 +805,26 @@ export const Chat = ({
792805
setInputFocused(true)
793806
}, [closePublish, setInputFocused])
794807

808+
const handleReviewOptionSelect = useCallback(
809+
(reviewText: string) => {
810+
closeReviewScreen()
811+
setInputFocused(true)
812+
// Submit the review request
813+
onSubmitPrompt(reviewText, agentMode)
814+
.then((result) => handleCommandResult(result))
815+
.catch((error) => {
816+
logger.error({ error }, '[review] Failed to submit review prompt')
817+
showClipboardMessage('Failed to send review request', { durationMs: 3000 })
818+
})
819+
},
820+
[closeReviewScreen, setInputFocused, onSubmitPrompt, agentMode, handleCommandResult],
821+
)
822+
823+
const handleCloseReviewScreen = useCallback(() => {
824+
closeReviewScreen()
825+
setInputFocused(true)
826+
}, [closeReviewScreen, setInputFocused])
827+
795828
const handlePublish = useCallback(
796829
async (agentIds: string[]) => {
797830
await publishMutation.mutateAsync(agentIds)
@@ -1144,7 +1177,7 @@ export const Chat = ({
11441177
useChatKeyboard({
11451178
state: chatKeyboardState,
11461179
handlers: chatKeyboardHandlers,
1147-
disabled: askUserState !== null,
1180+
disabled: askUserState !== null || reviewMode,
11481181
})
11491182

11501183
// Sync message block context to zustand store for child components
@@ -1399,64 +1432,71 @@ export const Chat = ({
13991432

14001433
{ad && getAdsEnabled() && <AdBanner ad={ad} />}
14011434

1402-
<ChatInputBar
1403-
inputValue={inputValue}
1404-
cursorPosition={cursorPosition}
1405-
setInputValue={setInputValue}
1406-
inputFocused={inputFocused}
1407-
inputRef={inputRef}
1408-
inputPlaceholder={inputPlaceholder}
1409-
lastEditDueToNav={lastEditDueToNav}
1410-
agentMode={agentMode}
1411-
toggleAgentMode={toggleAgentMode}
1412-
setAgentMode={setAgentMode}
1413-
hasSlashSuggestions={hasSlashSuggestions}
1414-
hasMentionSuggestions={hasMentionSuggestions}
1415-
hasSuggestionMenu={hasSuggestionMenu}
1416-
slashSuggestionItems={slashSuggestionItems}
1417-
agentSuggestionItems={agentSuggestionItems}
1418-
fileSuggestionItems={fileSuggestionItems}
1419-
slashSelectedIndex={slashSelectedIndex}
1420-
agentSelectedIndex={agentSelectedIndex}
1421-
onSlashItemClick={handleSlashItemClick}
1422-
onMentionItemClick={handleMentionItemClick}
1423-
theme={theme}
1424-
terminalHeight={terminalHeight}
1425-
separatorWidth={separatorWidth}
1426-
shouldCenterInputVertically={shouldCenterInputVertically}
1427-
inputBoxTitle={inputBoxTitle}
1428-
isCompactHeight={isCompactHeight}
1429-
isNarrowWidth={isNarrowWidth}
1430-
feedbackMode={feedbackMode}
1431-
handleExitFeedback={handleExitFeedback}
1432-
publishMode={publishMode}
1433-
handleExitPublish={handleExitPublish}
1434-
handlePublish={handlePublish}
1435-
handleSubmit={handleSubmit}
1436-
onPaste={createPasteHandler({
1437-
text: inputValue,
1438-
cursorPosition,
1439-
onChange: setInputValue,
1440-
onPasteImage: chatKeyboardHandlers.onPasteImage,
1441-
onPasteImagePath: chatKeyboardHandlers.onPasteImagePath,
1442-
onPasteLongText: (pastedText) => {
1443-
const id = crypto.randomUUID()
1444-
const preview = pastedText.slice(0, 100).replace(/\n/g, ' ')
1445-
useChatStore.getState().addPendingTextAttachment({
1446-
id,
1447-
content: pastedText,
1448-
preview,
1449-
charCount: pastedText.length,
1450-
})
1451-
// Show temporary status message
1452-
showClipboardMessage(
1453-
`📋 Pasted text (${pastedText.length.toLocaleString()} chars)`,
1454-
{ durationMs: 5000 },
1455-
)
1456-
},
1457-
cwd: getProjectRoot() ?? process.cwd(),
1458-
})}
1459-
/>
1435+
{reviewMode ? (
1436+
<ReviewScreen
1437+
onSelectOption={handleReviewOptionSelect}
1438+
onCancel={handleCloseReviewScreen}
1439+
/>
1440+
) : (
1441+
<ChatInputBar
1442+
inputValue={inputValue}
1443+
cursorPosition={cursorPosition}
1444+
setInputValue={setInputValue}
1445+
inputFocused={inputFocused}
1446+
inputRef={inputRef}
1447+
inputPlaceholder={inputPlaceholder}
1448+
lastEditDueToNav={lastEditDueToNav}
1449+
agentMode={agentMode}
1450+
toggleAgentMode={toggleAgentMode}
1451+
setAgentMode={setAgentMode}
1452+
hasSlashSuggestions={hasSlashSuggestions}
1453+
hasMentionSuggestions={hasMentionSuggestions}
1454+
hasSuggestionMenu={hasSuggestionMenu}
1455+
slashSuggestionItems={slashSuggestionItems}
1456+
agentSuggestionItems={agentSuggestionItems}
1457+
fileSuggestionItems={fileSuggestionItems}
1458+
slashSelectedIndex={slashSelectedIndex}
1459+
agentSelectedIndex={agentSelectedIndex}
1460+
onSlashItemClick={handleSlashItemClick}
1461+
onMentionItemClick={handleMentionItemClick}
1462+
theme={theme}
1463+
terminalHeight={terminalHeight}
1464+
separatorWidth={separatorWidth}
1465+
shouldCenterInputVertically={shouldCenterInputVertically}
1466+
inputBoxTitle={inputBoxTitle}
1467+
isCompactHeight={isCompactHeight}
1468+
isNarrowWidth={isNarrowWidth}
1469+
feedbackMode={feedbackMode}
1470+
handleExitFeedback={handleExitFeedback}
1471+
publishMode={publishMode}
1472+
handleExitPublish={handleExitPublish}
1473+
handlePublish={handlePublish}
1474+
handleSubmit={handleSubmit}
1475+
onPaste={createPasteHandler({
1476+
text: inputValue,
1477+
cursorPosition,
1478+
onChange: setInputValue,
1479+
onPasteImage: chatKeyboardHandlers.onPasteImage,
1480+
onPasteImagePath: chatKeyboardHandlers.onPasteImagePath,
1481+
onPasteLongText: (pastedText) => {
1482+
const id = crypto.randomUUID()
1483+
const preview = pastedText.slice(0, 100).replace(/\n/g, ' ')
1484+
useChatStore.getState().addPendingTextAttachment({
1485+
id,
1486+
content: pastedText,
1487+
preview,
1488+
charCount: pastedText.length,
1489+
})
1490+
// Show temporary status message
1491+
showClipboardMessage(
1492+
`📋 Pasted text (${pastedText.length.toLocaleString()} chars)`,
1493+
{ durationMs: 5000 },
1494+
)
1495+
},
1496+
cwd: getProjectRoot() ?? process.cwd(),
1497+
})}
1498+
/>
1499+
)}
14601500

14611501
<BottomStatusLine
14621502
isClaudeConnected={isClaudeOAuthActive}

cli/src/commands/command-registry.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import open from 'open'
22

33
import { handleAdsEnable, handleAdsDisable } from './ads'
4+
import { useThemeStore } from '../hooks/use-theme'
45
import { handleHelpCommand } from './help'
56
import { handleImageCommand } from './image'
67
import { handleInitializationFlowLocally } from './init'
@@ -56,6 +57,7 @@ export type CommandResult = {
5657
openFeedbackMode?: boolean
5758
openPublishMode?: boolean
5859
openChatHistory?: boolean
60+
openReviewScreen?: boolean
5961
preSelectAgents?: string[]
6062
} | void
6163

@@ -495,6 +497,45 @@ export const COMMAND_REGISTRY: CommandDefinition[] = [
495497
return { openChatHistory: true }
496498
},
497499
}),
500+
defineCommandWithArgs({
501+
name: 'review',
502+
handler: (params, args) => {
503+
const trimmedArgs = args.trim()
504+
505+
params.saveToHistory(params.inputValue.trim())
506+
clearInput(params)
507+
508+
// If user provided review text directly, send it immediately without showing the screen
509+
if (trimmedArgs) {
510+
const reviewPrompt = `@GPT-5 Agent Please review: ${trimmedArgs}`
511+
params.sendMessage({
512+
content: reviewPrompt,
513+
agentMode: params.agentMode,
514+
})
515+
setTimeout(() => {
516+
params.scrollToLatest()
517+
}, 0)
518+
return
519+
}
520+
521+
// Otherwise open the selection UI
522+
return { openReviewScreen: true }
523+
},
524+
}),
525+
defineCommand({
526+
name: 'theme:toggle',
527+
handler: (params) => {
528+
const { theme, setThemeName } = useThemeStore.getState()
529+
const newTheme = theme.name === 'dark' ? 'light' : 'dark'
530+
setThemeName(newTheme)
531+
params.setMessages((prev) => [
532+
...prev,
533+
getUserMessage(params.inputValue.trim()),
534+
getSystemMessage(`Switched to ${newTheme} theme.`),
535+
])
536+
clearInput(params)
537+
},
538+
}),
498539
]
499540

500541
export function findCommand(cmd: string): CommandDefinition | undefined {

cli/src/components/chat-input-bar.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ export const ChatInputBar = ({
115115
const modeConfig = getInputModeConfig(inputMode)
116116
const askUserState = useChatStore((state) => state.askUserState)
117117
const hasAnyPreview = hasSuggestionMenu
118+
119+
// Increase menu size on larger screen heights
120+
const normalModeMaxVisible = terminalHeight > 35 ? 15 : 10
118121
const { submitAnswers, skip } = useAskUserBridge()
119122
const [askUserTitle] = React.useState(' Some questions for you ')
120123

@@ -388,7 +391,7 @@ export const ChatInputBar = ({
388391
<SuggestionMenu
389392
items={slashSuggestionItems}
390393
selectedIndex={slashSelectedIndex}
391-
maxVisible={10}
394+
maxVisible={normalModeMaxVisible}
392395
prefix="/"
393396
onItemClick={onSlashItemClick}
394397
/>
@@ -397,7 +400,7 @@ export const ChatInputBar = ({
397400
<SuggestionMenu
398401
items={[...agentSuggestionItems, ...fileSuggestionItems]}
399402
selectedIndex={agentSelectedIndex}
400-
maxVisible={10}
403+
maxVisible={normalModeMaxVisible}
401404
prefix="@"
402405
onItemClick={onMentionItemClick}
403406
/>

0 commit comments

Comments
 (0)