Skip to content

Commit 1d11dfe

Browse files
committed
Merge remote-tracking branch 'origin/main' into brandon/plan-ux
2 parents 8e5d6a0 + 2dc6a12 commit 1d11dfe

File tree

73 files changed

+4495
-896
lines changed

Some content is hidden

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

73 files changed

+4495
-896
lines changed

.agents/base2/base2.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,20 +289,23 @@ It should not include:
289289
290290
This is more like an extremely short PRD which describes the end result of what the user wants. Think of it like fleshing out the user's prompt to make it more precise, although it should be as short as possible.
291291
292-
## Questions
292+
## Follow-up questions
293293
294-
After closing the <PLAN> tags, the last optional section is Questions, which is a Questions header with a numbered list of questions and alternate choices demarcated by letters.
294+
After closing the <PLAN> tags, the last optional section is Follow-up questions, which has a numbered list of questions and alternate choices demarcated by letters to clarify and improve upon the spec. These questions are optional for to complete for the user.
295295
296-
For example, here is a nice short question, where the options are helpfully written out for the user:
296+
For example, here is a nice short follow-up question, where the options are helpfully written out for the user, with the answers a) and b) indented with two spaces for readability:
297297
298-
Questions:
298+
<example>
299+
## Optional follow-up questions:
299300
300301
1. Do you want to:
301-
a) (DEFAULT) Keep Express and integrate Bun WebSockets
302+
a) (CURRENT) Keep Express and integrate Bun WebSockets
302303
b) Migrate the entire HTTP server to Bun.serve()
304+
</example>
303305
304306
Try to have as few questions as possible (even none), and focus on the most important decisions or assumptions that it would be helpful to clarify with the user.
305-
You should also let them know what you plan to do by default, and let them know that they can choose a different option if they want to.
307+
308+
You should also let them know what the plan currently does by default by labeling that option with "(CURRENT)", and let them know that they can choose a different option if they want to.
306309
307310
The questions section should be last and there should be no summary or further elaboration. Just end your turn.
308311

.agents/researcher/researcher-docs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const definition: SecretAgentDefinition = {
2323
instructionsPrompt: `Instructions:
2424
1. Use the read_docs tool to get detailed documentation relevant to the user's question.
2525
2. Repeat the read_docs tool call until you have gathered all the relevant documentation.
26-
3. Write up a comprehensive report of the documentation. Include key findings, relevant insights, and actionable recommendations.
26+
3. Write up a concise report of the documentation. Include key findings for the user's prompt.
2727
`.trim(),
2828
}
2929

.agents/researcher/researcher-web.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const definition: SecretAgentDefinition = {
2323
2424
Use web_search to find current information. Repeat the web_search tool call until you have gathered all the relevant information.
2525
26-
Then, write up a report that includes key findings, relevant insights, and actionable recommendations for the user's prompt.
26+
Then, write up a concise report that includes key findings for the user's prompt.
2727
`.trim(),
2828

2929
handleSteps: function* ({ agentState, prompt, params }) {

bun.lock

Lines changed: 111 additions & 95 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/release-staging/index.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,30 @@ async function downloadBinary(version) {
240240
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`)
241241
}
242242

243-
const downloadUrl = `${process.env.NEXT_PUBLIC_CODEBUFF_APP_URL || 'https://codebuff.com'}/api/releases/download/${version}/${fileName}`
243+
const downloadUrl = `${
244+
process.env.NEXT_PUBLIC_CODEBUFF_APP_URL || 'https://codebuff.com'
245+
}/api/releases/download/${version}/${fileName}`
244246

245247
fs.mkdirSync(CONFIG.configDir, { recursive: true })
246248

247249
if (fs.existsSync(CONFIG.binaryPath)) {
248-
fs.unlinkSync(CONFIG.binaryPath)
250+
try {
251+
fs.unlinkSync(CONFIG.binaryPath)
252+
} catch (err) {
253+
// Fallback: try renaming the locked/undeletable binary
254+
const backupPath = CONFIG.binaryPath + `.old.${Date.now()}`
255+
256+
try {
257+
fs.renameSync(CONFIG.binaryPath, backupPath)
258+
} catch (renameErr) {
259+
// If we can't unlink OR rename, we can't safely proceed
260+
throw new Error(
261+
`Failed to replace existing binary. ` +
262+
`unlink error: ${err.code || err.message}, ` +
263+
`rename error: ${renameErr.code || renameErr.message}`,
264+
)
265+
}
266+
}
249267
}
250268

251269
term.write('Downloading...')

cli/src/__tests__/unit/segmented-control.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import type { ChatTheme } from '../../types/theme-system'
1111

1212
const theme: ChatTheme = {
13+
name: 'dark',
1314
// Core
1415
primary: '#ff0',
1516
secondary: '#888',

cli/src/app.tsx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { createValidationErrorBlocks } from './utils/create-validation-error-blo
1313
import { openFileAtPath } from './utils/open-file'
1414
import { pluralize } from '@codebuff/common/util/string'
1515

16+
import type { FileTreeNode } from '@codebuff/common/util/file'
17+
1618
interface AppProps {
1719
initialPrompt: string | null
1820
agentId?: string
@@ -23,6 +25,7 @@ interface AppProps {
2325
agentsDir: string
2426
} | null
2527
validationErrors: Array<{ id: string; message: string }>
28+
fileTree: FileTreeNode[]
2629
}
2730

2831
export const App = ({
@@ -32,6 +35,7 @@ export const App = ({
3235
hasInvalidCredentials,
3336
loadedAgentsData,
3437
validationErrors,
38+
fileTree,
3539
}: AppProps) => {
3640
const { contentMaxWidth, separatorWidth } = useTerminalDimensions()
3741
const theme = useTheme()
@@ -169,16 +173,15 @@ export const App = ({
169173
])
170174

171175
return (
172-
<box style={{ flexDirection: 'column', gap: 0, flexGrow: 1 }}>
173-
<Chat
174-
headerContent={headerContent}
175-
initialPrompt={initialPrompt}
176-
agentId={agentId}
177-
requireAuth={requireAuth}
178-
hasInvalidCredentials={hasInvalidCredentials}
179-
loadedAgentsData={loadedAgentsData}
180-
validationErrors={validationErrors}
181-
/>
182-
</box>
176+
<Chat
177+
headerContent={headerContent}
178+
initialPrompt={initialPrompt}
179+
agentId={agentId}
180+
requireAuth={requireAuth}
181+
hasInvalidCredentials={hasInvalidCredentials}
182+
loadedAgentsData={loadedAgentsData}
183+
validationErrors={validationErrors}
184+
fileTree={fileTree}
185+
/>
183186
)
184187
}

cli/src/chat.tsx

Lines changed: 69 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ import { computeInputLayoutMetrics } from './utils/text-layout'
4444
import { createMarkdownPalette } from './utils/theme-system'
4545
import { BORDER_CHARS } from './utils/ui-constants'
4646

47-
import type { SendMessageTimerEvent } from './hooks/use-send-message'
4847
import type { ContentBlock } from './types/chat'
4948
import type { SendMessageFn } from './types/contracts/send-message'
5049
import type { ScrollBoxRenderable } from '@opentui/core'
50+
import type { FileTreeNode } from '@codebuff/common/util/file'
5151

5252
const DEFAULT_AGENT_IDS = {
5353
DEFAULT: 'base2',
@@ -63,6 +63,7 @@ export const Chat = ({
6363
hasInvalidCredentials,
6464
loadedAgentsData,
6565
validationErrors,
66+
fileTree,
6667
}: {
6768
headerContent: React.ReactNode
6869
initialPrompt: string | null
@@ -74,6 +75,7 @@ export const Chat = ({
7475
agentsDir: string
7576
} | null
7677
validationErrors: Array<{ id: string; message: string }>
78+
fileTree: FileTreeNode[]
7779
}) => {
7880
const scrollRef = useRef<ScrollBoxRenderable | null>(null)
7981
const inputRef = useRef<MultilineInputHandle | null>(null)
@@ -119,6 +121,7 @@ export const Chat = ({
119121
setHasReceivedPlanResponse,
120122
lastMessageMode,
121123
setLastMessageMode,
124+
addSessionCredits,
122125
resetChatStore,
123126
} = useChatStore(
124127
useShallow((store) => ({
@@ -151,6 +154,7 @@ export const Chat = ({
151154
setHasReceivedPlanResponse: store.setHasReceivedPlanResponse,
152155
lastMessageMode: store.lastMessageMode,
153156
setLastMessageMode: store.setLastMessageMode,
157+
addSessionCredits: store.addSessionCredits,
154158
resetChatStore: store.reset,
155159
})),
156160
)
@@ -291,12 +295,15 @@ export const Chat = ({
291295
mentionContext,
292296
slashMatches,
293297
agentMatches,
298+
fileMatches,
294299
slashSuggestionItems,
295300
agentSuggestionItems,
301+
fileSuggestionItems,
296302
} = useSuggestionEngine({
297303
inputValue,
298304
slashCommands: SLASH_COMMANDS,
299305
localAgents,
306+
fileTree,
300307
})
301308

302309
// Reset suggestion menu indexes when context changes
@@ -326,19 +333,21 @@ export const Chat = ({
326333
}, [mentionContext.active, mentionContext.query, setAgentSelectedIndex])
327334

328335
useEffect(() => {
329-
if (agentMatches.length > 0 && agentSelectedIndex >= agentMatches.length) {
330-
setAgentSelectedIndex(agentMatches.length - 1)
336+
const totalMatches = agentMatches.length + fileMatches.length
337+
if (totalMatches > 0 && agentSelectedIndex >= totalMatches) {
338+
setAgentSelectedIndex(totalMatches - 1)
331339
}
332-
if (agentMatches.length === 0 && agentSelectedIndex !== 0) {
340+
if (totalMatches === 0 && agentSelectedIndex !== 0) {
333341
setAgentSelectedIndex(0)
334342
}
335-
}, [agentMatches.length, agentSelectedIndex, setAgentSelectedIndex])
343+
}, [agentMatches.length, fileMatches.length, agentSelectedIndex, setAgentSelectedIndex])
336344

337345
const { handleSuggestionMenuKey } = useSuggestionMenuHandlers({
338346
slashContext,
339347
mentionContext,
340348
slashMatches,
341349
agentMatches,
350+
fileMatches,
342351
slashSelectedIndex,
343352
agentSelectedIndex,
344353
inputValue,
@@ -403,6 +412,7 @@ export const Chat = ({
403412
setHasReceivedPlanResponse,
404413
lastMessageMode,
405414
setLastMessageMode,
415+
addSessionCredits,
406416
})
407417

408418
sendMessageRef.current = sendMessage
@@ -456,6 +466,7 @@ export const Chat = ({
456466
],
457467
)
458468

469+
const totalMentionMatches = agentMatches.length + fileMatches.length
459470
const historyNavUpEnabled =
460471
lastEditDueToNav ||
461472
(cursorPosition === 0 &&
@@ -468,7 +479,7 @@ export const Chat = ({
468479
((slashContext.active &&
469480
slashSelectedIndex === slashMatches.length - 1) ||
470481
(mentionContext.active &&
471-
agentSelectedIndex === agentMatches.length - 1) ||
482+
agentSelectedIndex === totalMentionMatches - 1) ||
472483
(!slashContext.active && !mentionContext.active)))
473484

474485
useKeyboardHandlers({
@@ -523,7 +534,7 @@ export const Chat = ({
523534
const hasMentionSuggestions =
524535
!slashContext.active &&
525536
mentionContext.active &&
526-
agentSuggestionItems.length > 0
537+
(agentSuggestionItems.length > 0 || fileSuggestionItems.length > 0)
527538
const hasSuggestionMenu = hasSlashSuggestions || hasMentionSuggestions
528539
const showAgentStatusLine = showAgentDisplayName && loadedAgentsData
529540

@@ -593,78 +604,64 @@ export const Chat = ({
593604
flexGrow: 1,
594605
}}
595606
>
596-
<box
607+
<scrollbox
608+
ref={scrollRef}
609+
stickyScroll
610+
stickyStart="bottom"
611+
scrollX={false}
612+
scrollbarOptions={{ visible: false }}
613+
{...appliedScrollboxProps}
597614
style={{
598-
flexDirection: 'column',
599615
flexGrow: 1,
600-
paddingLeft: 0,
601-
paddingRight: 0,
602-
paddingTop: 0,
603-
paddingBottom: 0,
604-
backgroundColor: 'transparent',
616+
rootOptions: {
617+
flexGrow: 1,
618+
padding: 0,
619+
gap: 0,
620+
flexDirection: 'column',
621+
shouldFill: true,
622+
backgroundColor: 'transparent',
623+
},
624+
wrapperOptions: {
625+
flexGrow: 1,
626+
border: false,
627+
shouldFill: true,
628+
backgroundColor: 'transparent',
629+
},
630+
contentOptions: {
631+
flexDirection: 'column',
632+
gap: 0,
633+
shouldFill: true,
634+
justifyContent: 'flex-end',
635+
backgroundColor: 'transparent',
636+
},
605637
}}
606638
>
607-
<scrollbox
608-
ref={scrollRef}
609-
stickyScroll
610-
stickyStart="bottom"
611-
scrollX={false}
612-
scrollbarOptions={{ visible: false }}
613-
{...appliedScrollboxProps}
614-
style={{
615-
flexGrow: 1,
616-
rootOptions: {
617-
flexGrow: 1,
618-
padding: 0,
619-
gap: 0,
620-
flexDirection: 'column',
621-
shouldFill: true,
622-
backgroundColor: 'transparent',
623-
},
624-
wrapperOptions: {
625-
flexGrow: 1,
626-
border: false,
627-
shouldFill: true,
628-
backgroundColor: 'transparent',
629-
},
630-
contentOptions: {
631-
flexDirection: 'column',
632-
gap: 0,
633-
shouldFill: true,
634-
justifyContent: 'flex-end',
635-
backgroundColor: 'transparent',
636-
},
637-
}}
638-
>
639-
{headerContent}
640-
{virtualizationNotice}
641-
<MessageRenderer
642-
messages={messages}
643-
messageTree={messageTree}
644-
topLevelMessages={virtualTopLevelMessages}
645-
availableWidth={separatorWidth}
646-
theme={theme}
647-
markdownPalette={markdownPalette}
648-
collapsedAgents={collapsedAgents}
649-
streamingAgents={streamingAgents}
650-
isWaitingForResponse={isWaitingForResponse}
651-
timerStartTime={timerStartTime}
652-
onCollapseToggle={handleCollapseToggle}
653-
setCollapsedAgents={setCollapsedAgents}
654-
setFocusedAgentId={setFocusedAgentId}
655-
userOpenedAgents={userOpenedAgents}
656-
setUserOpenedAgents={setUserOpenedAgents}
657-
onBuildFast={handleBuildFast}
658-
onBuildMax={handleBuildMax}
659-
/>
660-
</scrollbox>
661-
</box>
639+
{headerContent}
640+
{virtualizationNotice}
641+
<MessageRenderer
642+
messages={messages}
643+
messageTree={messageTree}
644+
topLevelMessages={virtualTopLevelMessages}
645+
availableWidth={separatorWidth}
646+
theme={theme}
647+
markdownPalette={markdownPalette}
648+
collapsedAgents={collapsedAgents}
649+
streamingAgents={streamingAgents}
650+
isWaitingForResponse={isWaitingForResponse}
651+
timerStartTime={timerStartTime}
652+
onCollapseToggle={handleCollapseToggle}
653+
setCollapsedAgents={setCollapsedAgents}
654+
setFocusedAgentId={setFocusedAgentId}
655+
userOpenedAgents={userOpenedAgents}
656+
setUserOpenedAgents={setUserOpenedAgents}
657+
onBuildFast={handleBuildFast}
658+
onBuildMax={handleBuildMax}
659+
/>
660+
</scrollbox>
662661

663662
<box
664663
style={{
665664
flexShrink: 0,
666-
paddingLeft: 0,
667-
paddingRight: 0,
668665
backgroundColor: 'transparent',
669666
}}
670667
>
@@ -765,7 +762,7 @@ export const Chat = ({
765762
) : null}
766763
{hasMentionSuggestions ? (
767764
<SuggestionMenu
768-
items={agentSuggestionItems}
765+
items={[...agentSuggestionItems, ...fileSuggestionItems]}
769766
selectedIndex={agentSelectedIndex}
770767
maxVisible={10}
771768
prefix="@"

0 commit comments

Comments
 (0)