feat(pijul-qol:zero-live-search): make search live from zero side. Next idea would be to kinda list out the intent tags with what changes group in them or something.

Chasesomero
Mar 6, 2026, 4:06 PM
TNNBD7ZMNCA3L6DV2DKBC2KHOAQZM3D6OUYRYQBUF4CVTUK6AR3QC

Dependencies

  • [2] 32ICZXL4 init laravel zero for fun
  • [3] WNLMHTPQ feat(pijul-qol:move-to-zero): two new commands, to try make intent-tag discovery easier

Change contents

  • edit in tests/Feature/PijulSearchIntentTagsCommandTest.php at line 3
    [3.69]
    [3.69]
    use App\Prompts\LiveSuggestPrompt;
    use App\Prompts\Renderers\LiveSuggestPromptRenderer;
  • edit in tests/Feature/PijulSearchIntentTagsCommandTest.php at line 7
    [3.148]
    [3.148]
    use Laravel\Prompts\Key;
  • edit in tests/Feature/PijulSearchIntentTagsCommandTest.php at line 54
    [3.1823]
    [3.1823]
    ->assertExitCode(0);
    });
    it('shows live suggestions starting from all tags when prompted for a query', function () {
    Process::fake(function (PendingProcess $process) {
    return match ($process->command) {
    ['pijul', 'log', '--output-format', 'json'] => Process::result(json_encode([
    ['message' => 'feat(pijul-qol): first'],
    ['message' => 'feat(pijul-qol:move-to-zero): second'],
    ['message' => 'fix(cli): third'],
    ], JSON_THROW_ON_ERROR)),
    default => Process::result('', 'Unexpected command.', 1),
    };
    });
    LiveSuggestPrompt::fake(['z', 'e', 'r', 'o', Key::ENTER]);
    $this->artisan('pijul:search-intent-tags')
    ->expectsOutput('feat(pijul-qol:move-to-zero)')
  • edit in tests/Feature/PijulSearchIntentTagsCommandTest.php at line 75
    [3.1856]
    it('renders initial live suggestions before any query is typed', function () {
    LiveSuggestPrompt::fake();
    $prompt = new LiveSuggestPrompt(
    label: 'Search query',
    options: fn (string $value): array => $value === ''
    ? ['feat(pijul-qol)', 'feat(pijul-qol:move-to-zero)', 'fix(cli)']
    : ['fix(cli)'],
    placeholder: 'Type to filter intent tags...',
    scroll: 10,
    required: 'Please provide a search query.',
    );
    $output = (new LiveSuggestPromptRenderer($prompt))($prompt);
    expect(preg_replace("/\e\[[0-9;?]*[A-Za-z]/", '', $output))
    ->toContain('feat(pijul-qol)')
    ->toContain('fix(cli)');
    });
    it('returns all tags when the live filter has no input yet', function () {
    $command = app(App\Commands\PijulSearchIntentTagsCommand::class);
    $method = new ReflectionMethod($command, 'suggestedTags');
    $method->setAccessible(true);
    expect($method->invoke($command, [
    'feat(pijul-qol)',
    'feat(pijul-qol:move-to-zero)',
    'fix(cli)',
    ], ''))->toBe([
    'feat(pijul-qol)',
    'feat(pijul-qol:move-to-zero)',
    'fix(cli)',
    ]);
    });
  • edit in app/Providers/AppServiceProvider.php at line 5
    [2.310310]
    [2.310310]
    use App\Prompts\LiveSuggestPrompt;
    use App\Prompts\Renderers\LiveSuggestPromptRenderer;
  • edit in app/Providers/AppServiceProvider.php at line 8
    [2.310350]
    [2.310350]
    use Laravel\Prompts\Prompt;
  • replacement in app/Providers/AppServiceProvider.php at line 17
    [2.310500][2.310500:310511]()
    //
    [2.310500]
    [2.310511]
    Prompt::addTheme('pijul', [
    LiveSuggestPrompt::class => LiveSuggestPromptRenderer::class,
    ]);
    Prompt::theme('pijul');
  • file addition: Prompts (d--r------)
    [2.310204]
  • file addition: Renderers (d--r------)
    [0.2372]
  • file addition: LiveSuggestPromptRenderer.php (----------)
    [0.2395]
    <?php
    namespace App\Prompts\Renderers;
    use Laravel\Prompts\SuggestPrompt;
    use Laravel\Prompts\Themes\Default\SuggestPromptRenderer;
    class LiveSuggestPromptRenderer extends SuggestPromptRenderer
    {
    protected function renderOptions(SuggestPrompt $prompt): string
    {
    if (empty($prompt->matches())) {
    return '';
    }
    return implode(PHP_EOL, $this->scrollbar(
    array_map(function ($label, $key) use ($prompt) {
    $label = $this->truncate($label, $prompt->terminal()->cols() - 12);
    return $prompt->highlighted === $key
    ? "{$this->cyan('›')} {$label} "
    : " {$this->dim($label)} ";
    }, $visible = $prompt->visible(), array_keys($visible)),
    $prompt->firstVisible,
    $prompt->scroll,
    count($prompt->matches()),
    min($this->longest($prompt->matches(), padding: 4), $prompt->terminal()->cols() - 6),
    $prompt->state === 'cancel' ? 'dim' : 'cyan'
    ));
    }
    }
  • file addition: LiveSuggestPrompt.php (----------)
    [0.2372]
    <?php
    namespace App\Prompts;
    use Laravel\Prompts\SuggestPrompt;
    class LiveSuggestPrompt extends SuggestPrompt
    {
    }
  • edit in app/Commands/PijulSearchIntentTagsCommand.php at line 5
    [3.3223]
    [3.3223]
    use App\Prompts\LiveSuggestPrompt;
  • edit in app/Commands/PijulSearchIntentTagsCommand.php at line 10
    [3.3321]
    [3.3321]
    private const LIVE_RESULTS_SCROLL = 10;
  • edit in app/Commands/PijulSearchIntentTagsCommand.php at line 36
    [3.4268]
    [3.4268]
    $tags = $listIntentTags->resolveTags(
    limit: $this->option('limit'),
    repository: $this->option('repository'),
    channel: $this->option('channel'),
    noPrompt: (bool) $this->option('no-prompt'),
    );
  • replacement in app/Commands/PijulSearchIntentTagsCommand.php at line 44
    [3.4331][3.4331:4395]()
    $query = trim((string) $this->ask('Search query'));
    [3.4331]
    [3.4395]
    $query = trim((string) (new LiveSuggestPrompt(
    label: 'Search query',
    options: fn (string $value): array => $this->suggestedTags($tags, $value),
    placeholder: 'Type to filter intent tags...',
    scroll: self::LIVE_RESULTS_SCROLL,
    required: 'Please provide a search query.',
    hint: 'Results update on each keypress. Use arrows to scroll, then press Enter.',
    ))->prompt());
  • edit in app/Commands/PijulSearchIntentTagsCommand.php at line 60
    [3.4541][3.4541:4799]()
    $tags = $listIntentTags->resolveTags(
    limit: $this->option('limit'),
    repository: $this->option('repository'),
    channel: $this->option('channel'),
    noPrompt: (bool) $this->option('no-prompt'),
    );
  • edit in app/Commands/PijulSearchIntentTagsCommand.php at line 78
    [3.5206]
    [3.5206]
    /**
    * @param list<string> $tags
    * @return list<string>
    */
    private function suggestedTags(array $tags, string $query): array
    {
    $query = trim($query);
    if ($query === '') {
    return array_values($tags);
    }
    return array_values(array_filter(
    $tags,
    fn (string $tag): bool => str_contains(strtolower($tag), strtolower($query)),
    ));
    }
  • edit in README.md at line 38
    [3.8745]
    [3.8745]
    If you omit the query in an interactive terminal, it opens a live, scrollable filter that starts by showing known tags and narrows on each keypress.