From 554d52369d0546ab874879e558b7de063c038fe2 Mon Sep 17 00:00:00 2001 From: Hadi Minooei Date: Thu, 26 Mar 2026 23:11:02 -0700 Subject: [PATCH] fix(cli): improve simulator action history and fix dialog max items --- packages/cli/src/services/UserSimulator.ts | 33 +++++++++++++++++-- .../cli/src/ui/components/AskUserDialog.tsx | 2 +- .../__snapshots__/AskUserDialog.test.tsx.snap | 2 ++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/services/UserSimulator.ts b/packages/cli/src/services/UserSimulator.ts index 19194f17c0..4119611f39 100644 --- a/packages/cli/src/services/UserSimulator.ts +++ b/packages/cli/src/services/UserSimulator.ts @@ -22,6 +22,7 @@ export class UserSimulator { private interactionsFile: string | null = null; private knowledgeBase = ''; + private actionHistory: string[] = []; constructor( private readonly config: Config, @@ -122,6 +123,10 @@ export class UserSimulator { ? `\nUser Knowledge Base:\nUse this information to answer questions if applicable. If the answer is not here, respond as you normally would.\n${this.knowledgeBase}\n` : ''; + const historyInstruction = this.actionHistory.length > 0 + ? `\nRecent Simulator Actions (last 10):\n${this.actionHistory.slice(-10).map((a, i) => `${i + 1}. ${JSON.stringify(a)}`).join('\n')}\n` + : ''; + const prompt = `You are evaluating a CLI agent by simulating a user sitting at the terminal. Look carefully at the screen and determine the CLI's current state: @@ -145,7 +150,7 @@ CRITICAL RULES: - RULE 2: If there is an "Action Required" or confirmation prompt on the screen, YOU MUST HANDLE IT (State 2). This takes precedence over everything else. - RULE 3: Output ONLY the raw characters to send, , or . - RULE 4: Do NOT output markdown, explanations of your thought process, or quotes. -${goalInstruction}${knowledgeInstruction} +${goalInstruction}${knowledgeInstruction}${historyInstruction} Here is the current terminal screen output: @@ -217,6 +222,13 @@ ${strippedScreen} debugLogger.log( '[SIMULATOR] Skipping action (model decided to )', ); + this.actionHistory.push(''); + if (this.interactionsFile) { + fs.appendFileSync( + this.interactionsFile, + `[LOG] [SIMULATOR] Action History updated with: ""\n\n`, + ); + } this.lastScreenContent = normalizedScreen; return; } @@ -224,14 +236,31 @@ ${strippedScreen} if (responseText) { const keys = responseText.replace(/\\n/g, '\r').replace(/\\r/g, '\r'); - debugLogger.log( `[SIMULATOR] Sending to stdin: ${JSON.stringify(keys)}`, ); + + this.actionHistory.push(keys); + if (this.interactionsFile) { + fs.appendFileSync( + this.interactionsFile, + `[LOG] [SIMULATOR] Action History updated with: ${JSON.stringify(keys)}\n\n`, + ); + } + this.stdinBuffer.write(keys); this.lastScreenContent = normalizedScreen; } else { debugLogger.log('[SIMULATOR] Skipping (empty response)'); + + this.actionHistory.push(''); + if (this.interactionsFile) { + fs.appendFileSync( + this.interactionsFile, + `[LOG] [SIMULATOR] Action History updated with: ""\n\n`, + ); + } + this.lastScreenContent = normalizedScreen; } } catch (e: unknown) { diff --git a/packages/cli/src/ui/components/AskUserDialog.tsx b/packages/cli/src/ui/components/AskUserDialog.tsx index b1d23885e6..dac01b29ff 100644 --- a/packages/cli/src/ui/components/AskUserDialog.tsx +++ b/packages/cli/src/ui/components/AskUserDialog.tsx @@ -853,7 +853,7 @@ const ChoiceQuestionView: React.FC = ({ listHeight && !isAlternateBuffer ? question.unconstrainedHeight ? Math.max(1, listHeight - selectionItems.length * 2) - : Math.min(15, Math.max(1, listHeight - DIALOG_PADDING)) + : Math.min(15, Math.max(1, listHeight - Math.min(selectionItems.length, 5) * 2)) : undefined; const maxItemsToShow = diff --git a/packages/cli/src/ui/components/__snapshots__/AskUserDialog.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/AskUserDialog.test.tsx.snap index 30caf0fb40..1ab67a46db 100644 --- a/packages/cli/src/ui/components/__snapshots__/AskUserDialog.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/AskUserDialog.test.tsx.snap @@ -30,6 +30,8 @@ exports[`AskUserDialog > Scroll Arrows (useAlternateBuffer: false) > shows scrol Description 1 2. Option 2 Description 2 + 3. Option 3 + Description 3 ▼ Enter to select · ↑/↓ to navigate · Esc to cancel