Skip to content

Commit 098c79f

Browse files
committed
Add /interview command!
1 parent 0346b70 commit 098c79f

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

cli/src/commands/command-registry.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { CLAUDE_OAUTH_ENABLED } from '@codebuff/common/constants/claude-oauth'
33
import open from 'open'
44

55
import { handleAdsEnable, handleAdsDisable } from './ads'
6-
import { buildPlanPrompt, buildReviewPromptFromArgs } from './prompt-builders'
6+
import { buildInterviewPrompt, buildPlanPrompt, buildReviewPromptFromArgs } from './prompt-builders'
77
import { useThemeStore } from '../hooks/use-theme'
88
import { handleHelpCommand } from './help'
99
import { handleImageCommand } from './image'
@@ -572,6 +572,30 @@ const ALL_COMMANDS: CommandDefinition[] = [
572572
useChatStore.getState().setInputMode('plan')
573573
},
574574
}),
575+
defineCommandWithArgs({
576+
name: 'interview',
577+
handler: (params, args) => {
578+
const trimmedArgs = args.trim()
579+
580+
params.saveToHistory(params.inputValue.trim())
581+
clearInput(params)
582+
583+
// If user provided text directly, send it immediately
584+
if (trimmedArgs) {
585+
params.sendMessage({
586+
content: buildInterviewPrompt(trimmedArgs),
587+
agentMode: params.agentMode,
588+
})
589+
setTimeout(() => {
590+
params.scrollToLatest()
591+
}, 0)
592+
return
593+
}
594+
595+
// Otherwise enter interview mode
596+
useChatStore.getState().setInputMode('interview')
597+
},
598+
}),
575599
defineCommandWithArgs({
576600
name: 'review',
577601
handler: (params, args) => {

cli/src/commands/prompt-builders.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ export function buildPlanPrompt(input: string): string {
2222
return `${PLAN_BASE_PROMPT}\n\n${trimmedInput}`
2323
}
2424

25+
// Base prompt for interview command - asks clarifying questions before acting
26+
export const INTERVIEW_BASE_PROMPT = 'Interview me to better understand my request and then create a spec file. First, gather any relevant context (read files, do research, etc.). Then, use several rounds of the ask_user tool to ask non-obvious clarifying questions — things you cannot easily infer from the codebase or my initial message. Ask about edge cases, preferences, constraints, and design decisions. All questions should be directed through the ask_user tool -- not written out as text. Keep coming up with new questions that get at unique aspects of the request. Aim for at least **3 rounds** with multiple questions each round. When satisfied, write a [INSERT_REQUEST_SHORT_NAME]-spec.md file with all the information you have gathered about the request. Aim for as much detail as possible. You should NOT make any code changes yet. Stop after creating the spec file. End by using the suggest_followups tool with ways to flesh out the spec file. Here is my request:'
27+
28+
/**
29+
* Build an interview prompt from user input.
30+
* @param input - The user's request to be interviewed about
31+
* @returns The full prompt to send to the agent
32+
*/
33+
export function buildInterviewPrompt(input: string): string {
34+
const trimmedInput = input.trim()
35+
if (!trimmedInput) {
36+
return INTERVIEW_BASE_PROMPT
37+
}
38+
return `${INTERVIEW_BASE_PROMPT}\n\n${trimmedInput}`
39+
}
40+
2541
/**
2642
* Review scope presets for the review screen.
2743
*/

cli/src/commands/router.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from './router-utils'
2020
import { handleClaudeAuthCode } from '../components/claude-connect-banner'
2121
import { handleChatGptAuthCode } from '../components/chatgpt-connect-banner'
22-
import { buildPlanPrompt, buildReviewPrompt } from './prompt-builders'
22+
import { buildInterviewPrompt, buildPlanPrompt, buildReviewPrompt } from './prompt-builders'
2323
import { getProjectRoot } from '../project-files'
2424
import { useChatStore } from '../state/chat-store'
2525
import { trackEvent } from '../utils/analytics'
@@ -328,6 +328,22 @@ export async function routeUserPrompt(
328328
return
329329
}
330330

331+
// Handle interview mode input
332+
if (inputMode === 'interview') {
333+
if (!trimmed) return
334+
saveToHistory(trimmed)
335+
setInputValue({ text: '', cursorPosition: 0, lastEditDueToNav: false })
336+
setInputMode('default')
337+
setInputFocused(true)
338+
inputRef.current?.focus()
339+
340+
sendMessage({ content: buildInterviewPrompt(trimmed), agentMode })
341+
setTimeout(() => {
342+
scrollToLatest()
343+
}, 0)
344+
return
345+
}
346+
331347
// Handle review mode input
332348
if (inputMode === 'review') {
333349
if (!trimmed) return

cli/src/data/slash-commands.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ const ALL_SLASH_COMMANDS: SlashCommand[] = [
133133
label: 'review',
134134
description: 'Review code changes with GPT 5.4',
135135
},
136+
{
137+
id: 'interview',
138+
label: 'interview',
139+
description: 'AI asks a series of questions to flesh out request into a spec',
140+
},
136141
{
137142
id: 'new',
138143
label: 'new',

cli/src/utils/input-modes.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type InputMode =
1111
| 'homeDir'
1212
| 'plan'
1313
| 'review'
14+
| 'interview'
1415
| 'referral'
1516
| 'usage'
1617
| 'image'
@@ -82,6 +83,16 @@ export const INPUT_MODE_CONFIGS: Record<InputMode, InputModeConfig> = {
8283
disableSlashSuggestions: false,
8384
blockKeyboardExit: false,
8485
},
86+
interview: {
87+
icon: null,
88+
label: 'Interview',
89+
color: 'info',
90+
placeholder: 'describe a feature/bug or other request to be fleshed out...',
91+
widthAdjustment: 12,
92+
showAgentModeToggle: false,
93+
disableSlashSuggestions: true,
94+
blockKeyboardExit: false,
95+
},
8596
plan: {
8697
icon: null,
8798
label: 'Plan',

0 commit comments

Comments
 (0)