feat: direct inquirer to stderr and throw if not TTY

old-agentic-v1^2
Philipp Burckhardt 2023-06-30 10:27:15 -04:00
rodzic 7a568e964c
commit ff601fd969
1 zmienionych plików z 48 dodań i 17 usunięć

Wyświetl plik

@ -4,19 +4,41 @@ import input from '@inquirer/input'
import select from '@inquirer/select' import select from '@inquirer/select'
import { setTimeout } from 'timers/promises' import { setTimeout } from 'timers/promises'
import { BaseTask } from '@/task'
import { CancelablePromise } from '@/types' import { CancelablePromise } from '@/types'
import { import {
HumanFeedbackMechanism, HumanFeedbackMechanism,
HumanFeedbackOptions,
HumanFeedbackType, HumanFeedbackType,
HumanFeedbackUserActionMessages, HumanFeedbackUserActionMessages,
HumanFeedbackUserActions HumanFeedbackUserActions
} from './feedback' } from './feedback'
const INQUIRER_CONTEXT = {
output: process.stderr
}
export class HumanFeedbackMechanismCLI< export class HumanFeedbackMechanismCLI<
T extends HumanFeedbackType, T extends HumanFeedbackType,
TOutput = any TOutput = any
> extends HumanFeedbackMechanism<T, TOutput> { > extends HumanFeedbackMechanism<T, TOutput> {
constructor({
task,
options
}: {
task: BaseTask
options: Required<HumanFeedbackOptions<T, TOutput>>
}) {
if (!process.stderr.isTTY) {
throw new Error(
'The CLI feedback requires an interactive terminal for error messages, but one is not available. This can occur if stderr is redirected. Run the script in a standard terminal without stderr redirection. If this is not possible, consider using an alternative feedback mechanism suitable for your environment.'
)
}
super({ task, options })
}
/** /**
* Prompt the user to select one of a list of options. * Prompt the user to select one of a list of options.
*/ */
@ -25,13 +47,16 @@ export class HumanFeedbackMechanismCLI<
choices: HumanFeedbackUserActions[] choices: HumanFeedbackUserActions[]
): Promise<HumanFeedbackUserActions> { ): Promise<HumanFeedbackUserActions> {
return this._errorAfterTimeout( return this._errorAfterTimeout(
select({ select(
message, {
choices: choices.map((choice) => ({ message,
name: HumanFeedbackUserActionMessages[choice], choices: choices.map((choice) => ({
value: choice name: HumanFeedbackUserActionMessages[choice],
})) value: choice
}) }))
},
INQUIRER_CONTEXT
)
) )
} }
@ -64,20 +89,26 @@ export class HumanFeedbackMechanismCLI<
protected async _edit(output: string): Promise<string> { protected async _edit(output: string): Promise<string> {
return this._defaultAfterTimeout( return this._defaultAfterTimeout(
editor({ editor(
message: 'Edit the output:', {
default: output message: 'Edit the output:',
}), default: output
},
INQUIRER_CONTEXT
),
output output
) )
} }
protected async _annotate(): Promise<string> { protected async _annotate(): Promise<string> {
return this._defaultAfterTimeout( return this._defaultAfterTimeout(
input({ input(
message: {
'Please leave an annotation (leave blank to skip; press enter to submit):' message:
}), 'Please leave an annotation (leave blank to skip; press enter to submit):'
},
INQUIRER_CONTEXT
),
'' ''
) )
} }
@ -94,7 +125,7 @@ export class HumanFeedbackMechanismCLI<
value: option value: option
})) }))
return this._errorAfterTimeout( return this._errorAfterTimeout(
select({ message: 'Pick one output:', choices }) select({ message: 'Pick one output:', choices }, INQUIRER_CONTEXT)
) )
} }
@ -110,7 +141,7 @@ export class HumanFeedbackMechanismCLI<
value: option value: option
})) }))
return this._errorAfterTimeout( return this._errorAfterTimeout(
checkbox({ message: 'Select outputs:', choices }) checkbox({ message: 'Select outputs:', choices }, INQUIRER_CONTEXT)
) )
} }
} }