add ranked search to pql sidebar with DSL toggle
test / unit + widget + golden + a11y (push) Failing after 33s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped

Search tab defaults to ranked text search via pql search — debounced
300ms, scored results with visual score bar.  DSL toggle switches to
raw PQL query mode for SQL-like queries.  Clicking a search result
opens it in the markdown context viewer.

Adds pql.search IPC command and PqlClient.search method.  Controller
gains SearchMode enum and search() method alongside existing runQuery.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-04-23 22:22:16 +02:00
co-authored by Claude
parent 2f7f797288
commit 226520cfce
5 changed files with 194 additions and 17 deletions
+41 -2
View File
@@ -1,7 +1,7 @@
/// State model for the pql sidebar panel.
///
/// Manages schema cache, query execution, file listing, and
/// decision/ticket views. All data comes through pql.* IPC verbs.
/// Manages search, DSL query execution, and markdown file listing.
/// All data comes through pql.* IPC verbs.
library;
import 'dart:async';
@@ -11,6 +11,8 @@ import 'package:flutter/foundation.dart';
enum PqlView { query, markdown }
enum SearchMode { search, dsl }
class PqlController extends ChangeNotifier {
PqlController({required this.ipc});
@@ -19,6 +21,9 @@ class PqlController extends ChangeNotifier {
PqlView _view = PqlView.query;
PqlView get view => _view;
SearchMode _searchMode = SearchMode.search;
SearchMode get searchMode => _searchMode;
String? _error;
String? get error => _error;
@@ -45,6 +50,40 @@ class PqlController extends ChangeNotifier {
}
}
void toggleSearchMode() {
_searchMode = _searchMode == SearchMode.search ? SearchMode.dsl : SearchMode.search;
_results = const [];
_error = null;
notifyListeners();
}
Future<void> search(String terms) async {
if (terms.trim().isEmpty) {
_results = const [];
_error = null;
notifyListeners();
return;
}
_loading = true;
_error = null;
notifyListeners();
final r = await ipc.request('pql.search', args: {
'terms': terms,
'limit': 50,
});
_loading = false;
if (!r.ok) {
_error = r.error?.message;
_results = const [];
notifyListeners();
return;
}
_results = _castList(r.data['results']);
notifyListeners();
}
Future<void> loadMarkdownFiles({String? glob}) async {
_loading = true;
notifyListeners();