feat(studio): plain-language ask bar + collapsible filter + AI search (v0.32.0)
Three changes against the user feedback "der text ist zu
zerhackt, die filter-leiste nimmt zu viel sicht weg, llm-suche
wenn das geht":
1. Today-Hero copy rewritten in flowing prose. The fallback
story drops the code-fence templates ("`mcp.<server>.<tool>`")
and reads as a single arc per language. Same trust model,
gentler register.
2. Filter row collapses behind a single `_FilterButton` with a
"Filter · N active" count badge. Status / Source / Installed
chips now live inside `_FilterDialog` — invisible until the
operator wants them, recovers a full row of viewport. The
category strip stays inline because category is the most
common cut and benefits from being one click away.
3. New `_AskBar` replaces the old single-line `_SearchField`:
- Multi-line input (1-4 lines auto-grow) so questions don't
overflow horizontally.
- Cmd+Enter / Ctrl+Enter submits; bare Enter inserts a
newline so the operator can write multi-line questions
naturally.
- Heuristic question detector (ends in `?` or ≥4 words)
routes the submit to the System-AI's askAi RPC instead of
the substring search. Live keystrokes still keyword-search
for short queries; question-shaped input holds the grid
steady until submit so the visible result set doesn't
wipe with every space.
- The LLM is asked for a strict-JSON ranking of up to 5
modules with a one-phrase reason each. Unknown module
names are dropped silently — operators must not see
hallucinated entries.
- The new `_AiAnswerCard` renders the LLM's answer plus the
ranked match list above the grid; the grid filters to
just those names so the answer and the visible cards
stay coherent. Clearing the question collapses everything
back.
- Falls back to plain keyword search when System AI is off
(with an explanatory hint instead of the AI hint).
The AI path uses the System-AI the operator already configured
in Settings; same privacy mode, same audit-log trail. Nothing
new leaves the hub.
Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
b0f09260e1
commit
c7869870c4
8 changed files with 1010 additions and 145 deletions
|
|
@ -103,6 +103,24 @@
|
|||
"channelsDisableAutostart": "Autostart deaktivieren",
|
||||
|
||||
"storeSearchHint": "Module suchen — Name, Tagline, Tag, Capability…",
|
||||
"storeAskHint": "Was brauchst du? Versuch's mit „ein Modul, das tabellarische Daten liest\" oder tippe einfach einen Begriff.",
|
||||
"storeAskSubmit": "Suchen",
|
||||
"storeAskAi": "KI fragen",
|
||||
"storeAskClear": "Frage zurücksetzen",
|
||||
"storeAskAiThinking": "Module werden durchsucht…",
|
||||
"storeAskAiUnavailable": "Konfiguriere eine System-AI in den Einstellungen, um Fragen in normaler Sprache zu stellen.",
|
||||
"storeAskNoMatches": "Keine Treffer — Frage verfeinern oder im Grid unten stöbern.",
|
||||
"storeAskAnswerLabel": "KI-Vorschlag",
|
||||
"storeAskAnswerWhy": "Warum es passt",
|
||||
"storeAskMatchPill": "Treffer",
|
||||
"storeFilterLabel": "Filter",
|
||||
"storeFilterActiveCount": "{n} aktiv",
|
||||
"@storeFilterActiveCount": { "placeholders": { "n": { "type": "int" } } },
|
||||
"storeFilterReset": "Filter zurücksetzen",
|
||||
"storeFilterApply": "Fertig",
|
||||
"storeFilterStatusGroup": "Status",
|
||||
"storeFilterSourceGroup": "Quelle",
|
||||
"storeFilterInstalledGroup": "Nur installierte zeigen",
|
||||
"storeFeatured": "EMPFOHLEN",
|
||||
"storeFeaturedHint": "kuratierte Auswahl · klicken für Details",
|
||||
"storeNoMatches": "Keine Treffer",
|
||||
|
|
|
|||
|
|
@ -104,6 +104,24 @@
|
|||
"channelsDisableAutostart": "Disable autostart",
|
||||
|
||||
"storeSearchHint": "Search modules — name, tagline, tag, capability…",
|
||||
"storeAskHint": "What do you need? Try \"a module that reads tabular data\" or just type a keyword.",
|
||||
"storeAskSubmit": "Search",
|
||||
"storeAskAi": "Ask the AI",
|
||||
"storeAskClear": "Clear question",
|
||||
"storeAskAiThinking": "Looking through modules…",
|
||||
"storeAskAiUnavailable": "Configure a System AI in Settings to ask questions in plain language.",
|
||||
"storeAskNoMatches": "No matches yet — refine the question or browse the grid below.",
|
||||
"storeAskAnswerLabel": "AI suggestion",
|
||||
"storeAskAnswerWhy": "Why this matches",
|
||||
"storeAskMatchPill": "match",
|
||||
"storeFilterLabel": "Filter",
|
||||
"storeFilterActiveCount": "{n} active",
|
||||
"@storeFilterActiveCount": { "placeholders": { "n": { "type": "int" } } },
|
||||
"storeFilterReset": "Reset filters",
|
||||
"storeFilterApply": "Done",
|
||||
"storeFilterStatusGroup": "Status",
|
||||
"storeFilterSourceGroup": "Source",
|
||||
"storeFilterInstalledGroup": "Show only installed",
|
||||
"storeFeatured": "FEATURED",
|
||||
"storeFeaturedHint": "curated picks · click for details",
|
||||
"storeNoMatches": "No matches",
|
||||
|
|
|
|||
|
|
@ -620,6 +620,108 @@ abstract class AppLocalizations {
|
|||
/// **'Search modules — name, tagline, tag, capability…'**
|
||||
String get storeSearchHint;
|
||||
|
||||
/// No description provided for @storeAskHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'What do you need? Try \"a module that reads tabular data\" or just type a keyword.'**
|
||||
String get storeAskHint;
|
||||
|
||||
/// No description provided for @storeAskSubmit.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Search'**
|
||||
String get storeAskSubmit;
|
||||
|
||||
/// No description provided for @storeAskAi.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Ask the AI'**
|
||||
String get storeAskAi;
|
||||
|
||||
/// No description provided for @storeAskClear.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Clear question'**
|
||||
String get storeAskClear;
|
||||
|
||||
/// No description provided for @storeAskAiThinking.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Looking through modules…'**
|
||||
String get storeAskAiThinking;
|
||||
|
||||
/// No description provided for @storeAskAiUnavailable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Configure a System AI in Settings to ask questions in plain language.'**
|
||||
String get storeAskAiUnavailable;
|
||||
|
||||
/// No description provided for @storeAskNoMatches.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No matches yet — refine the question or browse the grid below.'**
|
||||
String get storeAskNoMatches;
|
||||
|
||||
/// No description provided for @storeAskAnswerLabel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'AI suggestion'**
|
||||
String get storeAskAnswerLabel;
|
||||
|
||||
/// No description provided for @storeAskAnswerWhy.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Why this matches'**
|
||||
String get storeAskAnswerWhy;
|
||||
|
||||
/// No description provided for @storeAskMatchPill.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'match'**
|
||||
String get storeAskMatchPill;
|
||||
|
||||
/// No description provided for @storeFilterLabel.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Filter'**
|
||||
String get storeFilterLabel;
|
||||
|
||||
/// No description provided for @storeFilterActiveCount.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{n} active'**
|
||||
String storeFilterActiveCount(int n);
|
||||
|
||||
/// No description provided for @storeFilterReset.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Reset filters'**
|
||||
String get storeFilterReset;
|
||||
|
||||
/// No description provided for @storeFilterApply.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Done'**
|
||||
String get storeFilterApply;
|
||||
|
||||
/// No description provided for @storeFilterStatusGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Status'**
|
||||
String get storeFilterStatusGroup;
|
||||
|
||||
/// No description provided for @storeFilterSourceGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Source'**
|
||||
String get storeFilterSourceGroup;
|
||||
|
||||
/// No description provided for @storeFilterInstalledGroup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Show only installed'**
|
||||
String get storeFilterInstalledGroup;
|
||||
|
||||
/// No description provided for @storeFeatured.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -306,6 +306,62 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get storeSearchHint =>
|
||||
'Module suchen — Name, Tagline, Tag, Capability…';
|
||||
|
||||
@override
|
||||
String get storeAskHint =>
|
||||
'Was brauchst du? Versuch\'s mit „ein Modul, das tabellarische Daten liest\" oder tippe einfach einen Begriff.';
|
||||
|
||||
@override
|
||||
String get storeAskSubmit => 'Suchen';
|
||||
|
||||
@override
|
||||
String get storeAskAi => 'KI fragen';
|
||||
|
||||
@override
|
||||
String get storeAskClear => 'Frage zurücksetzen';
|
||||
|
||||
@override
|
||||
String get storeAskAiThinking => 'Module werden durchsucht…';
|
||||
|
||||
@override
|
||||
String get storeAskAiUnavailable =>
|
||||
'Konfiguriere eine System-AI in den Einstellungen, um Fragen in normaler Sprache zu stellen.';
|
||||
|
||||
@override
|
||||
String get storeAskNoMatches =>
|
||||
'Keine Treffer — Frage verfeinern oder im Grid unten stöbern.';
|
||||
|
||||
@override
|
||||
String get storeAskAnswerLabel => 'KI-Vorschlag';
|
||||
|
||||
@override
|
||||
String get storeAskAnswerWhy => 'Warum es passt';
|
||||
|
||||
@override
|
||||
String get storeAskMatchPill => 'Treffer';
|
||||
|
||||
@override
|
||||
String get storeFilterLabel => 'Filter';
|
||||
|
||||
@override
|
||||
String storeFilterActiveCount(int n) {
|
||||
return '$n aktiv';
|
||||
}
|
||||
|
||||
@override
|
||||
String get storeFilterReset => 'Filter zurücksetzen';
|
||||
|
||||
@override
|
||||
String get storeFilterApply => 'Fertig';
|
||||
|
||||
@override
|
||||
String get storeFilterStatusGroup => 'Status';
|
||||
|
||||
@override
|
||||
String get storeFilterSourceGroup => 'Quelle';
|
||||
|
||||
@override
|
||||
String get storeFilterInstalledGroup => 'Nur installierte zeigen';
|
||||
|
||||
@override
|
||||
String get storeFeatured => 'EMPFOHLEN';
|
||||
|
||||
|
|
|
|||
|
|
@ -318,6 +318,62 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get storeSearchHint =>
|
||||
'Search modules — name, tagline, tag, capability…';
|
||||
|
||||
@override
|
||||
String get storeAskHint =>
|
||||
'What do you need? Try \"a module that reads tabular data\" or just type a keyword.';
|
||||
|
||||
@override
|
||||
String get storeAskSubmit => 'Search';
|
||||
|
||||
@override
|
||||
String get storeAskAi => 'Ask the AI';
|
||||
|
||||
@override
|
||||
String get storeAskClear => 'Clear question';
|
||||
|
||||
@override
|
||||
String get storeAskAiThinking => 'Looking through modules…';
|
||||
|
||||
@override
|
||||
String get storeAskAiUnavailable =>
|
||||
'Configure a System AI in Settings to ask questions in plain language.';
|
||||
|
||||
@override
|
||||
String get storeAskNoMatches =>
|
||||
'No matches yet — refine the question or browse the grid below.';
|
||||
|
||||
@override
|
||||
String get storeAskAnswerLabel => 'AI suggestion';
|
||||
|
||||
@override
|
||||
String get storeAskAnswerWhy => 'Why this matches';
|
||||
|
||||
@override
|
||||
String get storeAskMatchPill => 'match';
|
||||
|
||||
@override
|
||||
String get storeFilterLabel => 'Filter';
|
||||
|
||||
@override
|
||||
String storeFilterActiveCount(int n) {
|
||||
return '$n active';
|
||||
}
|
||||
|
||||
@override
|
||||
String get storeFilterReset => 'Reset filters';
|
||||
|
||||
@override
|
||||
String get storeFilterApply => 'Done';
|
||||
|
||||
@override
|
||||
String get storeFilterStatusGroup => 'Status';
|
||||
|
||||
@override
|
||||
String get storeFilterSourceGroup => 'Source';
|
||||
|
||||
@override
|
||||
String get storeFilterInstalledGroup => 'Show only installed';
|
||||
|
||||
@override
|
||||
String get storeFeatured => 'FEATURED';
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue