Installation:
composer require moox/prompts
Register the service provider in config/app.php under providers:
Moox\Prompts\PromptsServiceProvider::class,
First Use Case: Create a simple CLI command with a single prompt:
php artisan make:command TestPromptCommand
Update the generated command:
use Moox\Prompts\Support\FlowCommand;
use function Moox\Prompts\text;
class TestPromptCommand extends FlowCommand
{
protected $signature = 'test:prompt';
protected $description = 'Test a simple prompt';
public ?string $name = null;
public function handle(): void
{
$this->name = text(label: 'What is your name?', validate: fn($name) => filled($name));
$this->info("Hello, {$this->name}!");
}
}
Run it:
php artisan test:prompt
Where to Look First:
src/Support/FlowCommand.php for base class details.src/Prompts/ for available prompt types (e.g., text.php, select.php).Define a Flow Command:
Extend FlowCommand and declare steps in promptFlowSteps().
class SetupCommand extends FlowCommand
{
public ?string $projectName;
public ?string $environment;
public function promptFlowSteps(): array
{
return ['stepProjectName', 'stepEnvironment', 'stepConfirm'];
}
}
Step-by-Step Prompts: Each step method should:
text(), select(), confirm(), etc., from Moox\Prompts\.public function stepProjectName(): void
{
$this->projectName = text(
label: 'Project name:',
validate: fn($name) => strlen($name) > 3
);
}
Web Integration:
Route::get('/setup', [SetupCommand::class, 'webHandle']);
Conditional Logic:
Use if checks to skip steps or alter prompts based on prior responses:
public function stepEnvironment(): void
{
if ($this->projectName === 'admin') {
$this->environment = 'production';
$this->info('Admin project: defaulting to production.');
} else {
$this->environment = select(
label: 'Environment:',
options: ['staging', 'production', 'local']
);
}
}
Validation: Leverage Laravel’s validation rules or closures:
$this->projectName = text(
label: 'Project name:',
validate: fn($name) => [
'required',
'string',
'max:50',
fn($attr, $value, $fail) => strlen($value) > 3 || $fail('Too short!')
]
);
Multi-Step Forms: For complex flows, group prompts into logical steps:
public function stepDatabase(): void
{
$this->databaseHost = text(label: 'Host:');
$this->databaseName = text(label: 'Database name:');
$this->databaseUser = text(label: 'Username:');
}
State Persistence:
public ?string $var = null).public string $name; // ❌ Fails if not set in first step.
Web Flow Quirks:
@csrf in forms.app/Http/Middleware/StartSession.php:
public function getSession(): Session
{
$session = parent::getSession();
$session->setTimeout(3600); // 1 hour
return $session;
}
Prompt API Mismatches:
// CLI-only: Uses Symfony Style
$this->error('This won’t work in web!');
// Web-safe: Use $this->line() or $this->info() instead.
Validation Feedback:
// CLI: Shows "The name field is required."
// Web: Shows "name: The name field is required."
Step Order:
promptFlowSteps() order matters. Reordering steps requires updating all references (e.g., conditional logic).Inspect State: Dump persisted state in a step to verify data:
public function stepDebug(): void
{
$this->line(print_r(get_object_vars($this), true));
}
Web Flow Debugging:
$this->line(session()->all());
<input type="hidden" name="_moox_prompt_state" value="...">
Prompt-Specific Issues:
options is an array of strings or Option objects.false for destructive actions:
$this->deleteDatabase = confirm(
label: 'Delete database?',
default: false
);
Custom Prompt Types:
Extend Moox\Prompts\Prompt to create reusable prompts:
class EmailPrompt extends Prompt
{
public function __invoke(string $label, array $options = []): string
{
return text($label, [
'validate' => fn($email) => filter_var($email, FILTER_VALIDATE_EMAIL),
...$options
]);
}
}
Register it in PromptsServiceProvider:
$this->app->singleton('prompts.email', fn() => new EmailPrompt());
Override Default Prompts:
Bind custom implementations in PromptsServiceProvider:
$this->app->bind(\Moox\Prompts\Contracts\Prompt::class, CustomPrompt::class);
Web Flow Customization:
Override the web template in resources/views/vendor/moox-prompts/flow.blade.php:
// Example: Add a progress bar.
<progress max="{{ count($steps) }}" value="{{ $currentStep }}"></progress>
CLI Styling:
Use Symfony’s Output methods for custom styling:
$this->text('Warning:', ['fg' => 'yellow']);
Localization: Prompts support Laravel’s localization. Translate labels:
$this->projectName = text(label: __('prompts.project_name'));
Add translations to resources/lang/en/prompts.php:
return [
'project_name' => 'What is the project name?',
];
How can I help you explore Laravel packages today?