Skip to main content
📝 Laravel-applicaties

Laravel Prompts v0.3.15: De CLI-bouwstenen waar je op wachtte

Laravel Prompts v0.3.15: De CLI-bouwstenen waar je op wachtte Ik was vorige week halverwege het bouwen van een deployment-commando voor een klantproje...

22 min

Leestijd

4,298

Woorden

Mar 18, 2026

Gepubliceerd

Engr Mejba Ahmed

Geschreven door

Engr Mejba Ahmed

Artikel delen

Laravel Prompts v0.3.15: De CLI-bouwstenen waar je op wachtte

Laravel Prompts v0.3.15: De CLI-bouwstenen waar je op wachtte

Ik was vorige week halverwege het bouwen van een deployment-commando voor een klantproject toen ik tegen de muur aanliep die elke Laravel-developer maar al te goed kent. Het commando moest zes opeenvolgende operaties uitvoeren — afhankelijkheden ophalen, assets compileren, migraties draaien, caches legen, routes opwarmen en een health check pingen. Elke stap duurde ergens tussen de 3 en 45 seconden. En mijn gebruikerservaring voor dit alles? Een knipperende cursor. Misschien een $this->info()-aanroep tussen de stappen als ik me genereus voelde.

De terminal zat daar gewoon. Stil. Het soort stilte dat je doet afvragen of het proces is vastgelopen, of je Ctrl+C moet indrukken en opnieuw moet beginnen, of dat de databasemigratie daadwerkelijk 200.000 rijen aan het verwerken is en je gewoon even geduld moet hebben.

Toen zag ik de v0.3.15 release notes verschijnen op 17 maart 2026. Vijf nieuwe primitieven. Allemaal geëxtraheerd uit de Laravel Cloud CLI — de interne tooling die het Laravel-team bouwde voor het beheren van cloud-deployments. De hoofdfunctie is task(), en die lost precies het probleem op dat ik net beschreef. Maar de ondersteunende cast — stream(), notify(), autocomplete() en title() — vult hiaten op waarvan ik niet eens besefte dat ik er al jaren omheen werkte.

Ik maakte mijn middag vrij en herschreef dat deployment-commando. Hier is alles wat ik vond.

Waarom deze primitieven bestaan — en waarom ze nu pas kwamen

Het achtergrondverhaal is hier relevant omdat het verklaart waarom deze functies vanaf het begin zo gepolijst aanvoelen.

Toen het Laravel-team de Cloud CLI bouwde — de commandoregeltool die je hele Laravel Cloud-infrastructuur beheert — hadden ze terminal-interacties nodig die veel verder gingen dan "stel een vraag, krijg een antwoord." Cloud-deployments omvatten langlopende processen met realtime log-output. Ze hebben spinners nodig die hun labels bijwerken naarmate de context verandert. Ze hebben statusberichten nodig (succes, waarschuwing, fout) die op het scherm blijven staan terwijl scrollende logs eronder doorstromen. Ze hebben streaming tekst nodig voor AI-ondersteunde operaties. Ze hebben desktopnotificaties nodig wanneer een deployment van 10 minuten klaar is terwijl je in een ander venster werkt.

Niets daarvan bestond eerder in Laravel Prompts. Dus bouwden ze het intern. En met v0.3.15 extraheerden ze die primitieven terug naar het pakket zelf — beproefd na maanden van dagelijks gebruik binnen Cloud CLI.

Dat extractiepatroon is een van de dingen die ik het meest respecteer aan het Laravel-ecosysteem. Functies verschijnen niet als theoretische API's. Ze verschijnen omdat iemand ze nodig had in productie, ze onder druk bouwde, ze verfijnde door dagelijks gebruik, en ze vervolgens generaliseerde voor alle anderen. De task()-functie begon niet als een specificatiedocument. Het begon als een deployment-scherm dat engineers op de hoogte moest houden tijdens builds van 5 minuten.

Met meer dan 179 miljoen installaties op Packagist en 535 afhankelijke pakketten, hebben wijzigingen in Laravel Prompts invloed op het hele PHP-ecosysteem. Deze release is geen kleine patch — het is een fundamentele uitbreiding van wat mogelijk is in terminal-UI voor PHP-applicaties.

Hier is wat er daadwerkelijk is uitgebracht.

De task()-functie — Langlopende processen krijgen eindelijk een echte UI

Dit is het middelpunt van v0.3.15, en terecht. De task()-functie geeft je een live-bijwerkende spinner, scrollende log-output, stabiele statusberichten die op het scherm blijven staan, en de mogelijkheid om het label bij te werken naarmate de taak vordert. Allemaal vanuit één enkele functieaanroep.

Hier is de basissignatuur:

use function Laravel\Prompts\task;

task(
    title: 'Deploying application',
    callback: function ($task) {
        $task->log('Pulling latest changes...');
        // ... actual work ...

        $task->label('Compiling assets');
        $task->log('Running npm build...');
        // ... more work ...

        $task->succeed('Deployment complete');
    }
);

Wat er gebeurt als dit draait: een spinner animeert naast "Deploying application." Terwijl je callback draait, schrijft elke $task->log()-aanroep een regel naar een scrollend outputgebied onder de spinner. Het loggebied scrollt automatisch — oude regels schuiven omhoog terwijl nieuwe binnenkomen, zodat de meest recente output zichtbaar blijft. De spinner blijft de hele tijd animeren, zodat de gebruiker altijd weet dat het proces leeft.

De $task->label()-aanroep is subtiel maar krachtig. Het verandert de tekst naast de spinner zonder de scrollende log te onderbreken. Zo kun je "Pulling dependencies" tonen voor de eerste fase, "Compiling assets" voor de tweede, "Running migrations" voor de derde — terwijl de gedetailleerde log-output er gewoon onder doorstroomt. Twee niveaus van informatiedichtheid: het label vertelt je in welke fase je zit, de log vertelt je wat er nu gebeurt.

Statusberichten die blijven staan

Het onderdeel dat me overtuigde: stabiele statusberichten.

task(
    title: 'Running test suite',
    callback: function ($task) {
        $task->log('PHPUnit 11.5.2 — 342 tests');

        // Tests run...
        $task->log('Passed: UserRegistrationTest (0.234s)');
        $task->log('Passed: PaymentProcessingTest (1.203s)');

        // A warning surfaces
        $task->warning('3 tests marked as risky');

        // More tests...
        $task->log('Passed: ApiEndpointTest (0.089s)');

        $task->succeed('342 tests passed');
    }
);

Wanneer je $task->warning() aanroept, wordt dat bericht boven het scrollende loggebied weergegeven als een gemarkeerde, persistente regel. Het scrollt niet weg. Het blijft bovenaan vastgepind terwijl de rest van de log eronder doorstroomt. Hetzelfde gedrag geldt voor $task->error(). En $task->succeed() rondt de taak af met een groen vinkje en je bericht, ter vervanging van de spinner.

Dit lost een probleem op waar ik jarenlang omheen heb gewerkt: belangrijke statusinformatie die verdwijnt in uitgebreide output. In een migratiecommando hoort de waarschuwing "3 tabellen worden verwijderd" niet voorbij te scrollen in een muur van SQL-statements. Het hoort te blijven staan. Nu doet het dat.

De PCNTL-vereiste

Één ding om te weten: de spinneranimatie vereist de pcntl PHP-extensie. Op macOS en de meeste Linux-distributies is deze standaard beschikbaar. Op Windows (zonder WSL) is de PCNTL-extensie niet beschikbaar — je krijgt dan een statische fallback-versie. De taak werkt nog steeds, de log geeft nog steeds output, maar de spinner animeert niet.

Controleer of je het hebt:

php -m | grep pcntl

Als je Artisan-commando's bouwt die platformonafhankelijk moeten draaien, ontwerp dan je output zodat deze ook zonder de animatie bruikbaar is. De task()-functie handelt dit sierlijk af — je hoeft geen voorwaardelijke code te schrijven.

Mijn deployment-commando, opnieuw gebouwd

Hier is hoe mijn deployment-commando er nu uitziet versus daarvoor. Het verschil in gebruikerservaring is dramatisch.

Daarvoor (de donkere middeleeuwen):

public function handle()
{
    $this->info('Starting deployment...');

    // Pull code
    $this->call('down');
    $output = shell_exec('git pull origin main 2>&1');
    $this->info('Code pulled.');

    // Install dependencies
    $output = shell_exec('composer install --no-dev 2>&1');
    $this->info('Dependencies installed.');

    // Compile assets
    $output = shell_exec('npm run build 2>&1');
    $this->info('Assets compiled.');

    // Migrate
    $this->call('migrate', ['--force' => true]);
    $this->info('Migrations complete.');

    $this->call('up');
    $this->info('Done!');
}

Functioneel? Zeker. Maar de gebruiker ziet 30 seconden lang niets, gevolgd door een uitbarsting van statische tekst. Geen indicatie van voortgang tijdens elke stap. Geen onderscheid tussen "alles is in orde" en "er ging iets mis maar we zijn doorgegaan."

Daarna (v0.3.15):

use function Laravel\Prompts\task;
use function Laravel\Prompts\notify;
use function Laravel\Prompts\title;

public function handle()
{
    title('Deploy: production');

    task(
        title: 'Deploying to production',
        callback: function ($task) {
            $task->label('Pulling latest code');
            $task->log('Running git pull origin main...');

            $gitOutput = [];
            $gitCode = 0;
            exec('git pull origin main 2>&1', $gitOutput, $gitCode);

            foreach ($gitOutput as $line) {
                $task->log($line);
            }

            if ($gitCode !== 0) {
                $task->error('Git pull failed — aborting deployment');
                return;
            }

            $task->label('Installing dependencies');
            $task->log('Running composer install --no-dev...');
            exec('composer install --no-dev 2>&1', $composerOutput);

            foreach ($composerOutput as $line) {
                $task->log($line);
            }

            $task->label('Compiling assets');
            $task->log('Running npm build...');
            exec('npm run build 2>&1', $npmOutput);

            $task->label('Running migrations');
            $task->log('Applying pending migrations...');
            Artisan::call('migrate', ['--force' => true]);
            $task->log('Migrations applied.');

            $task->label('Clearing caches');
            Artisan::call('cache:clear');
            Artisan::call('config:clear');
            Artisan::call('route:clear');
            $task->log('All caches cleared.');

            $task->label('Warming caches');
            Artisan::call('config:cache');
            Artisan::call('route:cache');
            $task->log('Caches warmed.');

            $task->succeed('Deployment complete — all systems operational');
        }
    );

    title('Deploy: complete');

    notify(
        title: 'Deployment Complete',
        body: 'Production deployment finished successfully.'
    );
}

De terminal toont nu een draaiende indicator tijdens elke fase, het label wordt bijgewerkt terwijl het commando door de stappen vordert, elke regel echte output van git, Composer en npm stroomt naar de scrollende log, fouten verschijnen onmiddellijk als vastgepinde statusberichten, en als het klaar is, verschijnt er een native desktopnotificatie. Dat laatste onderdeel — de notificatie — brengt ons bij de volgende primitieve.

notify() — Native desktopnotificaties vanuit PHP

Deze verraste me. Niet omdat desktopnotificaties een nieuw concept zijn, maar omdat ik ze nooit verwachtte van een PHP CLI-tool.

use function Laravel\Prompts\notify;

notify(
    title: 'Build Complete',
    body: 'Your application has been compiled and deployed.'
);

Dat is alles. Een native besturingssysteemnotificatie verschijnt — dezelfde soort die je krijgt van Slack, VS Code of je e-mailclient. Op macOS gebruikt het het systeemnotificatiecentrum. Op Linux werkt het via de standaard notificatiedaemon. Op Windows met WSL brug het door naar Windows-notificaties.

De use case die me meteen aansprak: langlopende Artisan-commando's die ik start en dan vergeet. Ik start een database seed die 8 minuten duurt, schakel over naar mijn editor, begin aan iets anders te werken, en vergeet de terminal volledig. Twintig minuten later vraag ik me af "was dat al klaar?" en moet ik gaan kijken.

Nu voeg ik één regel toe aan het einde van het commando. De notificatie vindt me waar ik ook ben.

public function handle()
{
    // ... 8 minutes of seeding ...

    notify(
        title: 'Database Seeded',
        body: sprintf('%d records created in %d seconds.', $count, $elapsed)
    );
}

Een klein ding. Maar kleine dingen die cognitieve belasting wegnemen, stapelen zich op tot een daadwerkelijk betere ontwikkelervaring.

stream() — Tekst die zichzelf in de terminal typt

Als task() het werkpaard van deze release is, dan is stream() het paradepaardje. Het toont tekst die karakter voor karakter (of stuk voor stuk) de terminal in stroomt, met een geleidelijk fade-in effect.

use function Laravel\Prompts\stream;

$stream = stream('Processing analysis');

$stream->append('Analyzing codebase structure... ');
$stream->append("found 342 files.\n");
$stream->append('Identifying patterns... ');
$stream->append("detected 12 architectural concerns.\n");
$stream->append('Generating recommendations...');

$stream->close();

De append()-methode voegt tekst toe met een visueel fade-in effect — tekens materialiseren geleidelijk in plaats van allemaal tegelijk te verschijnen. Dit klinkt misschien als een trucje totdat je het primaire gebruik bedenkt: AI-gegenereerde content tonen in de terminal.

Als je Artisan-commando's bouwt die OpenAI, Anthropic of een andere LLM API aanroepen met streaming responses, dan geeft stream() je hetzelfde typemachine-effect dat je ziet in de ChatGPT-interface — maar in je terminal. De tekst arriveert terwijl het model deze genereert, en stream() rendert het met die bevredigende geleidelijke onthulling.

use function Laravel\Prompts\stream;
use OpenAI\Laravel\Facades\OpenAI;

$stream = stream('AI Analysis');

$response = OpenAI::chat()->createStreamed([
    'model' => 'gpt-4o',
    'messages' => [
        ['role' => 'user', 'content' => 'Analyze this error log...'],
    ],
]);

foreach ($response as $chunk) {
    $text = $chunk->choices[0]->delta->content ?? '';
    $stream->append($text);
}

$stream->close();

De close()-methode rondt de output af, herstelt de cursor en signaleert dat het streamen is voltooid. Zonder deze methode zou de terminal in een onbepaalde staat blijven.

Ik kan al zien dat dit standaard wordt in AI-aangedreven Artisan-commando's — het soort tooling dat snel normaal wordt in Laravel-applicaties sinds het ecosysteem AI-integraties omarmde gedurende 2025 en in 2026. Een eersteklas rendering-primitieve voor gestreamde tekst is precies de fundamentele ondersteuning die het pakket nodig had.

autocomplete() — Spooktekst in de terminal

De autocomplete()-functie voegt inline automatische aanvulling toe aan tekstinvoer, en toont suggesties als spooktekst die de gebruiker kan accepteren met Tab of de pijltjestoets naar rechts.

use function Laravel\Prompts\autocomplete;

$framework = autocomplete(
    label: 'Which framework?',
    options: fn (string $value) => collect([
        'Laravel', 'Symfony', 'Slim', 'Lumen', 'CakePHP',
    ])
        ->filter(fn ($item) => str_contains(
            strtolower($item),
            strtolower($value)
        ))
        ->values()
        ->all()
);

Typ "la" en "Laravel" verschijnt als vervaagde spooktekst na je cursor. Druk op Tab om het te accepteren. Als je verder typt naar "lum," verschuift de spooktekst naar "Lumen." De options-callback ontvangt de huidige invoerwaarde en retourneert overeenkomende suggesties in realtime.

Het verschil tussen autocomplete() en de bestaande suggest()-functie is het interactiemodel. suggest() toont een dropdownlijst met overeenkomende opties onder de invoer. autocomplete() toont inline spooktekst — hetzelfde patroon dat je kent van GitHub Copilot, je IDE of moderne browser-adresbalken. Het is sneller voor ervaren gebruikers die weten wat ze willen en alleen het systeem nodig hebben om hun gedachte af te maken.

Wanneer gebruik je welke?

  • suggest() werkt wanneer de gebruiker opties verkent en meerdere overeenkomsten tegelijk moet zien
  • autocomplete() werkt wanneer de gebruiker ongeveer weet wat het antwoord is en snelheid wil — minder toetsaanslagen, snellere doorstroming

Voor commando's die ervaren developers dagelijks gebruiken — omgevingen selecteren, branches kiezen, modelnamen specificeren — zal autocomplete() merkbaar vlotter aanvoelen dan suggest().

title() — Stel de terminalvenstertitel in

Deze is bedrieglijk eenvoudig:

use function Laravel\Prompts\title;

title('Application Installer');

Het verandert de titel van het terminalvenster of de tab. Dat is alles. De tekst in de titelbalk of tablabel van je terminal wordt bijgewerkt naar de string die je doorgeeft.

Waarom is dit belangrijk? Omdat iedereen die meer dan drie terminaltabs tegelijk open heeft de pijn kent van het zoeken naar de juiste. Als je Artisan-commando de titel instelt op "Deploying: staging" of "Queue Worker: emails" of "Migrating: production," wordt de juiste tab vinden een fluitje van een cent.

Combineer het met notify() voor langlopende commando's:

title('Deploy: production');

task(
    title: 'Running deployment',
    callback: function ($task) {
        // ... deployment steps ...
        $task->succeed('All clear');
    }
);

title('Deploy: complete');

notify(
    title: 'Production Deploy',
    body: 'Finished at ' . now()->format('H:i:s')
);

De terminaltab vertelt je de status in één oogopslag. De notificatie haalt je terug wanneer je ergens anders bent. Twee primitieven, en je deployment-commando respecteert je aandacht in plaats van deze op te eisen.

Alles samenbrengen — Een praktijkcommando

Individuele primitieven zijn interessant. Gecombineerd zijn ze transformatief. Hier is een compleet Artisan-commando dat elke nieuwe v0.3.15-functie gebruikt — het soort commando dat je daadwerkelijk zou bouwen voor een productie-workflow:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use function Laravel\Prompts\autocomplete;
use function Laravel\Prompts\task;
use function Laravel\Prompts\stream;
use function Laravel\Prompts\notify;
use function Laravel\Prompts\title;
use function Laravel\Prompts\info;

class AnalyzeCodebase extends Command
{
    protected $signature = 'analyze {--fix}';
    protected $description = 'Run AI-powered codebase analysis';

    public function handle()
    {
        title('Codebase Analysis');

        $scope = autocomplete(
            label: 'What should I analyze?',
            options: fn (string $value) => collect([
                'Full codebase',
                'Controllers only',
                'Models only',
                'Routes and middleware',
                'Database migrations',
                'Test coverage',
            ])
                ->filter(fn ($item) => str_contains(
                    strtolower($item),
                    strtolower($value)
                ))
                ->values()
                ->all()
        );

        // Phase 1: Scan with task()
        $results = [];

        task(
            title: 'Scanning codebase',
            callback: function ($task) use ($scope, &$results) {
                $task->label('Discovering files');
                $task->log("Scope: {$scope}");

                $files = $this->discoverFiles($scope);
                $task->log(count($files) . ' files found.');

                $task->label('Analyzing patterns');

                foreach ($files as $file) {
                    $task->log("Scanning: {$file}");
                    $results[] = $this->analyzeFile($file);
                }

                $issues = collect($results)->where('has_issues', true);

                if ($issues->count() > 10) {
                    $task->warning($issues->count() . ' files with issues detected');
                }

                $task->succeed(
                    count($files) . ' files scanned, '
                    . $issues->count() . ' issues found'
                );
            }
        );

        // Phase 2: AI analysis with stream()
        $analysis = stream('Generating recommendations');

        foreach ($this->getAiAnalysis($results) as $chunk) {
            $analysis->append($chunk);
        }

        $analysis->close();

        // Phase 3: Signal completion
        title('Analysis: complete');

        notify(
            title: 'Analysis Complete',
            body: count($results) . ' files analyzed. Check your terminal.'
        );
    }
}

Dat is één enkel Artisan-commando dat title() gebruikt voor tabidentificatie, autocomplete() voor snelle invoer, task() voor het zware werk met realtime voortgang, stream() voor AI-gegenereerde output, en notify() voor het voltooiingssignaal. Zes maanden geleden zou het bouwen van dit niveau terminal-UX in PHP een externe bibliotheek of honderden regels aangepaste renderercode hebben vereist. Nu is het een handvol functieaanroepen.

Wat er verder recent is uitgebracht — De ondersteunende releases

De v0.3.15-functies verschenen niet in isolatie. De releases die eraan voorafgingen legden de basis:

v0.3.12 (februari 2026) voegde Laravel 13-ondersteuning toe en repareerde validatieafhandeling voor de number prompt — de numerieke invoer geïntroduceerd in v0.3.11 waarmee gebruikers kunnen ophogen en verlagen met pijltjestoetsen en min/max-beperkingen worden afgedwongen.

v0.3.10 (januari 2026) introduceerde het Grid-component voor lay-outorganisatie binnen terminalinterfaces. Beschouw het als een basale flexbox voor de CLI — meerdere elementen naast elkaar positioneren in plaats van alles verticaal te stapelen.

v0.3.15 bracht ook dynamische secundaire informatie voor select-type prompts. Je kunt nu een callback doorgeven die secundaire detailtekst genereert voor elke optie, weergegeven naast het optielabel. Handig voor het tonen van beschrijvingen, metadata of statusindicatoren naast elke keuze in een select()- of multiselect()-aanroep.

En een PHPStan-opschoning die de typeveiligheid over het hele pakket verbeterde — het soort onzichtbaar werk dat de bibliotheek betrouwbaarder maakt voor IDE-autocompletion en statische analyse in je eigen projecten.

De primitieven die je al had (maar mogelijk onderbenut)

Nu we het toch over de complete Prompts-toolkit hebben, hier een snelle inventarisatie van de bestaande primitieven die goed combineren met de v0.3.15-toevoegingen. Ik noem ze omdat de meeste Laravel-developers die ik spreek alleen select() en confirm() gebruiken — en daarmee aanzienlijke terminal-UX laten liggen.

Informatieve berichtfuncties:

use function Laravel\Prompts\info;
use function Laravel\Prompts\note;
use function Laravel\Prompts\warning;
use function Laravel\Prompts\error;
use function Laravel\Prompts\alert;

info('Migration complete.');         // Blue, informational
note('Check the logs for details.'); // Gray, subtle
warning('3 deprecated methods.');    // Yellow, cautionary
error('Connection refused.');        // Red, critical
alert('Action required!');           // Bold, attention-demanding

Tabellen voor gestructureerde output:

use function Laravel\Prompts\table;

table(
    headers: ['Migration', 'Status', 'Duration'],
    rows: [
        ['2026_03_01_create_users', 'Applied', '0.34s'],
        ['2026_03_02_create_orders', 'Applied', '1.21s'],
        ['2026_03_03_add_indexes', 'Pending', '---'],
    ]
);

Voortgangsbalken voor iteratieve operaties:

use function Laravel\Prompts\progress;

$results = progress(
    label: 'Importing records',
    steps: $csvRows,
    callback: function ($row) {
        return $this->importRow($row);
    }
);

Spin voor eenvoudige laadtoestanden:

use function Laravel\Prompts\spin;

$result = spin(
    message: 'Fetching remote configuration...',
    callback: fn () => Http::get('https://api.example.com/config')->json()
);

Het verschil tussen spin() en task() is de reikwijdte. spin() is voor eenvoudige operaties waar je alleen "even geduld" met een spinner en één bericht nodig hebt. task() is voor meerfase-operaties met scrollende log-output, labelupdates en persistente statusberichten. Gebruik spin() voor een API-aanroep van 3 seconden. Gebruik task() voor een deployment van 3 minuten.

Hoe kies je de juiste primitieve — Een besliskader

Na een week commando's herschrijven met deze tools, heb ik een mentaal model ontwikkeld voor de keuze ertussen:

Gebruik task() wanneer:

  • De operatie langer dan 5 seconden duurt
  • Er meerdere fasen zijn waarvan de gebruiker op de hoogte moet zijn
  • Je log-output hebt die de gebruiker mogelijk wil lezen
  • Fouten of waarschuwingen op het scherm moeten blijven staan
  • Je het label wilt bijwerken terwijl de operatie vordert

Gebruik spin() wanneer:

  • De operatie één enkele stap is zonder zinvolle log-output
  • Het binnen 10 seconden klaar is
  • Je alleen "even geduld, dit werkt" nodig hebt

Gebruik stream() wanneer:

  • Je AI-gegenereerde of gestreamde tekst rendert
  • De output geleidelijk moet verschijnen, niet allemaal tegelijk
  • Je het typemachine/fade-in visuele effect wilt

Gebruik progress() wanneer:

  • Je over een bekend aantal items itereert
  • Elke iteratie ongeveer even lang duurt
  • De gebruiker baat heeft bij "47 van 200 voltooid"

Gebruik autocomplete() wanneer:

  • De gebruiker ongeveer weet wat hij wil typen
  • Snelheid belangrijker is dan het bekijken van een volledige lijst
  • Je een kleine tot middelgrote set voorspelbare opties hebt

Gebruik suggest() wanneer:

  • De gebruiker meerdere overeenkomsten tegelijk moet zien
  • De optieset groot is en baat heeft bij visueel scannen
  • Ontdekking belangrijker is dan snelheid

Gebruik notify() wanneer:

  • Het commando lang genoeg draait dat de gebruiker mogelijk van venster wisselt
  • Voltooiing een gebeurtenis is die de moeite van het onderbreken waard is
  • Je meerdere terminaltabs tegelijk draait

Gebruik title() wanneer:

  • Het commando in een permanente terminaltab draait
  • Je meerdere soortgelijke commando's in verschillende tabs hebt
  • Je in één oogopslag wilt zien wat elke terminal doet

Als je liever hebt dat iemand dit soort gepolijste CLI-tools en deployment-workflows voor je team bouwt, neem ik Laravel-consultancy en aangepaste Artisan-tooling opdrachten aan. Je kunt zien wat ik heb gebouwd op fiverr.com/s/EgxYmWD.

Het grotere plaatje — PHP CLI wordt volwassen

Dit is wat me opvalt aan deze release. Jarenlang was terminal-UX in PHP een bijzaak. Je had de helpers van Symfony Console — voortgangsbalken, tabellen, vraaghelpers — en die waren prima. Functioneel. Niet mooi. Gewoon prima.

Laravel Prompts veranderde die koers toen het in 2023 werd gelanceerd met Laravel 10. Maar de initiële release was gericht op invoer — text, select, multiselect, confirm. Informatie van de gebruiker krijgen op een gepolijste manier. De output-kant — informatie aan de gebruiker tonen tijdens operaties — was nog steeds basic. $this->info() en $this->error() en af en toe een voortgangsbalk.

v0.3.15 maakt het plaatje compleet. Invoer en output zijn nu beide eersteklas. Je kunt een CLI-ervaring bouwen die kan concurreren met wat je zou verwachten van een Node.js-tool gebouwd met Ink of een Rust-tool gebouwd met Ratatui. Spinners, streaming tekst, live-bijwerkende labels, persistente statusberichten, native notificaties, terminalitelbeheer — dit zijn de bouwstenen die het verschil maken tussen een "commando" en een "ervaring."

En het feit dat deze zijn geëxtraheerd uit de Cloud CLI betekent dat ze de zwaarste test al hebben doorstaan: echte engineers die ze elke dag gebruiken onder echte omstandigheden. De spinner moest soepel zijn. Het scrollen van logs moest snelle output aankunnen zonder te flikkeren. De notificaties moesten daadwerkelijk betrouwbaar verschijnen op macOS, Linux en WSL. Dit zijn geen theoretische functies — het zijn productiebewezen functies.

Voor het Laravel-ecosysteem specifiek denk ik dat deze release een verschuiving markeert. Artisan-commando's zijn altijd krachtig geweest aan de logica-kant. Nu kunnen ze ook krachtig zijn aan de ervaring-kant. En in een tijdperk waarin developers steeds vaker tools kiezen op basis van hoe ze aanvoelen — niet alleen wat ze doen — maakt dat onderscheid meer uit dan de meeste mensen beseffen.

Wat ik hierna wil zien

De primitieven zijn er. De basis is solide. Maar er zijn hiaten die ik in de gaten houd.

Samen te stellen lay-outs. Het Grid-component uit v0.3.10 is een begin, maar ik wil de mogelijkheid om een task()-spinner naast een table() te plaatsen die in realtime wordt bijgewerkt. Zij-aan-zij elementen. Dashboard-achtige lay-outs. De Cloud CLI heeft hier waarschijnlijk intern een deel van — ik hoop dat er meer van wordt geëxtraheerd.

Sneltoetsen binnen taken. Stel je voor dat je "v" drukt om uitgebreide logging aan/uit te zetten, of "s" om de huidige stap over te slaan. Interactieve taken, niet alleen weergavetaken. De pcntl-extensie maakt signaalafhandeling al mogelijk — uitbreiding naar toetsdetectie binnen een lopende taak voelt als de logische volgende stap.

Thema-ondersteuning. De huidige weergave is prachtig, maar het is één esthetiek. Verschillende projecten hebben verschillende terminalomgevingen. Een thema-API — zelfs een eenvoudige waarmee je kleuren en symbolen kunt overschrijven — zou Prompts native laten aanvoelen bij de tooling-setup van elk team.

Niets hiervan is kritiek. v0.3.15 is een oprecht sterke release. Maar de richting die het uitzet is misschien nog spannender dan wat het heeft opgeleverd. De kloof tussen "PHP CLI-tool" en "gepolijste terminalapplicatie" is net een stuk smaller geworden.

Begin met één commando

Kies één Artisan-commando in je project — degene die het langst duurt, degene die de meeste tekst output, degene die je team vermijdt omdat de ervaring pijnlijk is. Herschrijf het met task(). Voeg een notify() toe aan het einde. Stel de title() in aan het begin.

Het kost je 30 minuten. Het commando doet precies hetzelfde als voorheen. Maar het voelt als een ander gereedschap. En de volgende keer dat iemand in je team het draait, merken ze het. Dat is het soort upgrade dat niets kost en alles verandert aan hoe je tooling wordt ervaren.

De primitieven zijn er. Composer heeft ze al:

composer require laravel/prompts:^0.3.15

Of als je op Laravel 12 of 13 zit, zijn ze al gebundeld. Begin gewoon de functies te gebruiken.

Eén commando. Dertig minuten. Aan de slag.

Veelgestelde vragen

Werkt Laravel Prompts task() op Windows?

De task()-functie werkt op alle platformen, maar de geanimeerde spinner vereist de PCNTL PHP-extensie, die niet beschikbaar is op native Windows. Op Windows wordt in plaats daarvan een statische fallback weergegeven. Het gebruik van WSL op Windows geeft je volledige animatie-ondersteuning omdat het een echte Linux-kernel draait.

Wat is het verschil tussen spin() en task() in Laravel Prompts?

spin() is voor eenvoudige, eenstaps-operaties waar je een spinner en één bericht nodig hebt. task() is voor meerfase-operaties met scrollende log-output, dynamische labelupdates en persistente succes-/waarschuwing-/foutberichten. Gebruik spin() voor snelle API-aanroepen onder de 10 seconden; gebruik task() voor deployments, migraties en meerstaps-builds.

Kan ik Laravel Prompts stream() gebruiken voor AI-gegenereerde tekst?

Ja — stream() is specifiek voor dit gebruik ontworpen. Roep $stream->append() aan met elk fragment van een streaming LLM API-response, en de tekst wordt weergegeven met een geleidelijk fade-in effect. Roep $stream->close() aan wanneer de stream eindigt om de output af te ronden en de cursor te herstellen.

Welke PHP-versie vereist Laravel Prompts v0.3.15?

Laravel Prompts v0.3.15 vereist PHP 8.1 of hoger en de ext-mbstring-extensie. Het werkt met Symfony Console 6.2, 7.0 en 8.0, en wordt gebundeld met Laravel 12 en Laravel 13.

Hoe stuur ik desktopnotificaties vanuit een Laravel Artisan-commando?

Gebruik de notify()-functie van Laravel Prompts v0.3.15: notify(title: 'Done', body: 'Your task finished.'). Het stuurt een native OS-notificatie op macOS (Notification Center), Linux (notificatiedaemon) en Windows via WSL. Geen extra pakketten of configuratie vereist.

Let's Work Together

Looking to build AI systems, automate workflows, or scale your tech infrastructure? I'd love to help.

Coffee cup

Vond u dit artikel leuk?

Uw steun helpt mij meer diepgaande technische content, open-source tools en gratis bronnen voor de ontwikkelaarsgemeenschap te maken.

Gerelateerde onderwerpen

Engr Mejba Ahmed

Over de auteur

Engr Mejba Ahmed

Engr. Mejba Ahmed builds AI-powered applications and secure cloud systems for businesses worldwide. With 10+ years shipping production software in Laravel, Python, and AWS, he's helped companies automate workflows, reduce infrastructure costs, and scale without security headaches. He writes about practical AI integration, cloud architecture, and developer productivity.

Discussion

Comments

0

No comments yet

Be the first to share your thoughts

Leave a Comment

Your email won't be published

9  -  1  =  ?

Blijf leren

Gerelateerde artikelen

Alles bekijken

Comments

Leave a Comment

Comments are moderated before appearing.

Learning Resources

Expand Your Knowledge

Accelerate your growth with structured courses, verified certificates, interactive flashcards, and production-ready AI agent skills.

Sample Certificate of Completion

Sample certificate — complete any course to earn yours