Download the PHP package moox/prompts without Composer
On this page you can find all versions of the php package moox/prompts. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package prompts
Short Description Prompts is a package that provides CLI-compatible prompts for Laravel Artisan Commands with identical API to Laravel Prompts. Supports all prompt types
License MIT
Homepage https://moox.org/docs/prompts
Informations about the package prompts
Moox Prompts
CLI- and Web-compatible prompts for Laravel Artisan commands – with a flow that can continue step-by-step in the browser.
What does a Flow Command look like?
To make a command work as a flow in both CLI and Web, you only need to follow these rules:
-
Extend
FlowCommand -
Store state as public properties
(they are automatically persisted between steps in the web flow) -
Define steps via
promptFlowSteps()– the array order is the flow order -
Each step is a
public function stepXyz(): void– ideally one prompt per step -
Optional steps can simply be skipped with a guard at the beginning:
- Calling other Artisan commands – in a flow, always use
$this->call()instead ofArtisan::call(), so the output is also visible in the web UI:
That’s all you need in the command – no special flow methods, no custom persistence.
Everything else (CLI/Web differences, state, web UI) is handled by the package.
Running flows in the browser (Filament)
Once you’ve created a flow command, you can run it in both CLI and browser.
CLI
The command behaves like a normal Laravel Artisan command – all prompts are shown in the terminal.
Web
- Open the Filament page “Run Command” (automatically added to navigation)
- Select your flow command from the list
- Click “Start command”
- The flow runs step by step in the browser:
- Every step shows a prompt (text, select, multiselect, confirm, etc.)
- After each step you see the step’s output
- You can cancel any time with “Back to command selection”
- After a successful run the button switches to “Start new command”
Note: All commands executed via the web UI are automatically logged in the database (see Command Execution Logging).
How and why reflection is used
If you’re just writing commands, you don’t need to care about reflection.
To understand what happens under the hood, here’s a short overview.
-
Problem 1: Setting arguments & options in the web flow
Laravel stores arguments/options internally on a protected$inputproperty of your command.
In CLI mode the Artisan kernel takes care of this.
In the web flow, we create fresh command instances – and need to set$inputourselves.
That’s whatPromptFlowRunner::setCommandInput()does via reflection:- finds the
inputproperty on your command object, - temporarily makes it accessible,
- assigns the current
ArrayInputinstance.
Result: In flow commands you can keep usingargument()andoption()normally – both in CLI and in the browser.
- finds the
-
Problem 2: Remembering command state between web requests
In the web flow, your command runs across multiple HTTP requests. Without extra logic, properties like$environment,$features,$projectNamewould be lost between steps.
PromptFlowRunnerhandles this with two internal methods:captureCommandContext($command, $state)- uses reflection to read all non-static properties of your concrete command class
- stores simple values (scalars, arrays,
null) intoPromptFlowState::$context restoreCommandContext($command, $state)- restores all stored values back onto the new command instance on the next request
Result: For your code it feels like the same command instance keeps running – you don’t need your own persistence layer (cache, DB, session, …).
- Problem 3: Initializing package tools in the web context
Many packages usingSpatie\LaravelPackageToolsonly register publishable resources (config, views, migrations, assets, …) in CLI context.
WebCommandRunneruses reflection to access the internalpackageobject and replaypublishes(...)registrations for the web context.
Result: Commands likevendor:publishwork just as well in the browser as in CLI, even though Laravel is not running in console mode there.
Important:
Reflection is only used inside the package internals, not in your flow commands.
Your commands remain normal Laravel commands – you only need to:
- extend
FlowCommand, - define properties for your state,
- list steps in
promptFlowSteps(), - implement
step*methods (ideally one prompt per step).
The package takes care of the rest (reflection, state, web flow).
Are there alternatives without reflection?
Yes – technically we could avoid reflection, but it would degrade the DX:
- For arguments & options we’d need a custom API instead of
argument()/option(), or force you to manage everything via properties/arrays. That’s less “Laravel-ish” and harder to learn. - For state between steps we could ask you to manually list all properties to persist (e.g.
flowContextKeys()), or manage cache/DB/session yourself. That’s more boilerplate and error-prone. - For Spatie Package Tools in the web we’d either need changes in the Spatie package or manual configuration of all publishable paths – both would make setup more complex.
That’s why we intentionally keep reflection encapsulated in the package and keep your command API as simple as possible.
Command Execution Logging
All commands executed via the web interface are automatically logged in the database.
You can inspect them via the Filament resource “Command Executions”.
Status
Each execution has one of the following statuses:
running: The command is currently runningcompleted: The command finished successfullyfailed: The command failed with an errorcancelled: The command was cancelled by the user or aborted mid-flow
Stored information
For each execution we store:
- Basic information: command name, description, status, timestamps
- Steps: ordered list of all defined steps
- Step outputs: output of each step (JSON)
- Context: all command properties (e.g.
$environment,$projectName,$features, …) - Failure details: for
failedstatus – the error message and the step where it occurred (failed_at_step) - Cancellation details: for
cancelledstatus – the step where cancellation happened (cancelled_at_step) - User: polymorphic relation to the user who started the command (
created_by)
Important: step_outputs vs context
It’s important to understand the difference between these two fields:
-
step_outputs- Contains the console output of each step.
- This is everything you print via
$this->info(),$this->line(),$this->warn(), etc. - Example:
will result in e.g.:
-
context- Contains the raw state of your command – all public, non-static properties from your concrete command class.
- This includes values returned from
text(),select(),multiselect(),confirm(), etc. - Example:
will store in
contextsomething like:but
step_outputs["stepPublishConfigConfirm"]will be an empty string, becauseconfirm()itself doesn’t print anything.
If you want to see the user’s choice in the step output as well, you can explicitly print it:
This way you have:
- the decision in
context.publishConfig, and - a readable line in
step_outputs.stepPublishConfigConfirmfor the history/inspector UI.
Running the migration
To enable logging, run:
This creates the command_executions table with all necessary fields.
Filament resource
The Filament resource “Command Executions” is automatically available in the Filament navigation (if enabled). There you can:
- inspect all past command executions,
- filter by status,
- see details per execution (steps, outputs, context, errors),
- analyze failed or cancelled commands.
The resource also shows which step a command failed on (failed_at_step) or where it was cancelled (cancelled_at_step).
License
See LICENSE.md