Skip to content

Commit b3c9c59

Browse files
committed
cleanup
1 parent 988d5e0 commit b3c9c59

File tree

3 files changed

+54
-32
lines changed

3 files changed

+54
-32
lines changed

.agents/types/tools.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,28 @@ export interface AskUserParams {
6969
questions: {
7070
/** The question to ask the user */
7171
question: string
72-
/** Array of answer options for the question (minimum 2) */
73-
options: string[]
72+
/** Short label (max 12 chars) displayed as a chip/tag */
73+
header?: string
74+
/** Array of answer options with label and optional description (minimum 2) */
75+
options: {
76+
/** The display text for this option */
77+
label: string
78+
/** Explanation shown when option is focused */
79+
description?: string
80+
}[]
81+
/** If true, allows selecting multiple options (checkbox). If false, single selection only (radio). */
82+
multiSelect?: boolean
83+
/** Validation rules for "Other" text input */
84+
validation?: {
85+
/** Maximum length for "Other" text input */
86+
maxLength?: number
87+
/** Minimum length for "Other" text input */
88+
minLength?: number
89+
/** Regex pattern for "Other" text input */
90+
pattern?: string
91+
/** Custom error message when pattern fails */
92+
patternError?: string
93+
}
7494
}[]
7595
}
7696

cli/src/components/ask-user/hooks/use-keyboard-navigation.ts

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Integrates with @opentui/react useKeyboard and focus manager
44
*/
55

6-
import { useCallback } from 'react'
6+
import { useCallback, useRef, useEffect } from 'react'
77
import { useKeyboard } from '@opentui/react'
88
import type { FocusTarget, AskUserQuestion } from '../types'
99
import { isFocusOnOption, isFocusOnTextInput, isFocusOnConfirmSubmit } from '../types'
@@ -63,9 +63,36 @@ export function useKeyboardNavigation(params: KeyboardNavigationParams) {
6363
onGoBackFromConfirm,
6464
} = params
6565

66+
// Use refs for frequently changing values to avoid recreating the keyboard callback
67+
const paramsRef = useRef(params)
68+
useEffect(() => {
69+
paramsRef.current = params
70+
})
71+
6672
useKeyboard(
6773
useCallback(
6874
(key) => {
75+
// Get current values from ref to avoid stale closures
76+
const {
77+
focus,
78+
dispatchFocus,
79+
currentQuestionIndex,
80+
totalQuestions,
81+
isFirstQuestion,
82+
isLastQuestion,
83+
isOnConfirmScreen,
84+
otherTexts,
85+
onSelectAnswer,
86+
onOtherTextChange,
87+
onChangeQuestion,
88+
onSubmit,
89+
onAutoAdvance,
90+
onTextInputAdvance,
91+
onForceSubmit,
92+
onGoToConfirm,
93+
onGoBackFromConfirm,
94+
} = paramsRef.current
95+
6996
// Helper to prevent default behavior
7097
const preventDefault = () => {
7198
if ('preventDefault' in key && typeof key.preventDefault === 'function') {
@@ -236,27 +263,7 @@ export function useKeyboardNavigation(params: KeyboardNavigationParams) {
236263
}
237264
}
238265
},
239-
[
240-
focus,
241-
dispatchFocus,
242-
currentQuestionIndex,
243-
totalQuestions,
244-
currentQuestion,
245-
isFirstQuestion,
246-
isLastQuestion,
247-
isOnConfirmScreen,
248-
allAnswered,
249-
otherTexts,
250-
onSelectAnswer,
251-
onOtherTextChange,
252-
onChangeQuestion,
253-
onSubmit,
254-
onAutoAdvance,
255-
onTextInputAdvance,
256-
onForceSubmit,
257-
onGoToConfirm,
258-
onGoBackFromConfirm,
259-
]
266+
[] // Empty deps - callback is stable, values accessed via ref
260267
)
261268
)
262269
}

cli/src/components/ask-user/utils/validation.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,22 @@ export interface QuestionValidation {
2323

2424
/**
2525
* Validate "Other" text input against rules
26-
* Phase 1: Basic length check only
27-
* Phase 3: Full validation with regex, custom errors
26+
* Supports max/min length, regex patterns, and custom error messages
2827
*/
2928
export function validateOtherText(
3029
text: string,
3130
validation?: QuestionValidation,
3231
maxLength: number = 500
3332
): ValidationResult {
34-
// Phase 1: Simple max length check
33+
// Default max length check
3534
if (text.length > maxLength) {
3635
return {
3736
isValid: false,
3837
error: `Max ${maxLength} characters`,
3938
}
4039
}
4140

42-
// Phase 3 will add:
43-
// - minLength check
44-
// - pattern (regex) validation
45-
// - custom error messages
46-
41+
// Validation rules (if provided)
4742
if (validation) {
4843
if (validation.maxLength && text.length > validation.maxLength) {
4944
return {

0 commit comments

Comments
 (0)