feat(studio): store-side source filter, provenance pills, one-click recommended sources (v0.29.0)

The Store is now the centre of capability discovery — provider
configuration moves out of Settings into the Store itself.
Three changes work together:

1. Source filter chips next to the existing status chips:
   All sources / Native / MCP / n8n. Applied client-side after
   the hub returns results so toggling is instant. The result
   count and the "Clear filters" reset both account for the
   source filter too.

2. Per-card provenance pill (`_ProvenancePill`): shows whether
   each entry is native, mcp · <provider>, or n8n · <provider>
   so the operator can triage the source at a glance — same
   role the "verified" badge plays in commercial app stores.

3. `_RecommendedSourcesStrip` replaces the older
   `_FederationNudge`. Renders curated public MCP servers
   (DeepWiki, Semgrep) as one-click cards with an inline
   `[+ Add]` button — no Settings detour, no form. Both servers
   are HTTPS Streamable-HTTP, no API key, no subprocess.
   Useful AI was considered but its 340+ tools would drown the
   index — kept out of the curated list. The strip auto-hides
   the moment any federated entry exists.

Removed the now-orphaned storeFederationNudge* ARB keys.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-05-08 12:25:59 +02:00
parent b5a4c74c4b
commit 581ebbeaf7
8 changed files with 603 additions and 79 deletions

View file

@ -177,9 +177,36 @@
"@storeDocsErrorNetwork": { "placeholders": { "detail": { "type": "String" } } },
"storeDocsErrorParse": "README ist kein gültiges UTF-8.",
"storeDocsErrorGeneric": "README konnte nicht geladen werden.",
"storeFederationNudgeTitle": "Mehr Capabilities?",
"storeFederationNudgeBody": "MCP-Server oder n8n-Endpunkt unter Einstellungen → MCP-Clients / N8N-Endpunkte konfigurieren. Entdeckte Tools und Workflows tauchen hier als `mcp.<server>.<tool>`- und `n8n.<endpoint>.<workflow>`-Capabilities auf — jeder Anthropic-/Community-MCP-Server bringt mehrere auf einmal.",
"storeFederationNudgeButton": "Einstellungen öffnen",
"storeSourceLabel": "Quelle",
"storeSourceAll": "Alle Quellen",
"storeSourceNative": "Nativ",
"storeSourceMcp": "MCP",
"storeSourceN8n": "n8n",
"storeProvenanceNative": "nativ",
"storeProvenanceMcp": "mcp · {provider}",
"@storeProvenanceMcp": { "placeholders": { "provider": { "type": "String" } } },
"storeProvenanceN8n": "n8n · {provider}",
"@storeProvenanceN8n": { "placeholders": { "provider": { "type": "String" } } },
"storeRecommendedTitle": "Öffentliche Quelle hinzufügen — ein Klick",
"storeRecommendedBody": "Kuratierte MCP-Server über HTTPS erreichbar. Kein Subprozess, kein API-Key, kein Node. Föderierte Capabilities erscheinen sofort im Store.",
"storeRecommendedAddTooltip": "Hinzufügen und entdecken",
"storeRecommendedAdding": "Wird hinzugefügt…",
"storeRecommendedDeepWikiTagline": "GitHub-Repo-Doku-Suche (KI-gestützt)",
"storeRecommendedSemgrepTagline": "Security-Scanning für Code-Schwachstellen",
"storeProviderAddedToast": "{name} hinzugefügt — {n} {n, plural, =1{föderierte Capability} other{föderierte Capabilities}}.",
"@storeProviderAddedToast": {
"placeholders": {
"name": { "type": "String" },
"n": { "type": "int" }
}
},
"storeProviderAddFailed": "{name} konnte nicht hinzugefügt werden: {error}",
"@storeProviderAddFailed": {
"placeholders": {
"name": { "type": "String" },
"error": { "type": "String" }
}
},
"auditTitle": "Protokoll",
"auditNoEvents": "Noch keine Ereignisse",

View file

@ -178,9 +178,36 @@
"@storeDocsErrorNetwork": { "placeholders": { "detail": { "type": "String" } } },
"storeDocsErrorParse": "README is not valid UTF-8.",
"storeDocsErrorGeneric": "Could not load README.",
"storeFederationNudgeTitle": "Want more capabilities?",
"storeFederationNudgeBody": "Configure an MCP server or n8n endpoint in Settings → MCP Clients / N8N Endpoints. Discovered tools and workflows surface here as `mcp.<server>.<tool>` and `n8n.<endpoint>.<workflow>` capabilities — every Anthropic / community MCP server adds a handful at once.",
"storeFederationNudgeButton": "Open Settings",
"storeSourceLabel": "Source",
"storeSourceAll": "All sources",
"storeSourceNative": "Native",
"storeSourceMcp": "MCP",
"storeSourceN8n": "n8n",
"storeProvenanceNative": "native",
"storeProvenanceMcp": "mcp · {provider}",
"@storeProvenanceMcp": { "placeholders": { "provider": { "type": "String" } } },
"storeProvenanceN8n": "n8n · {provider}",
"@storeProvenanceN8n": { "placeholders": { "provider": { "type": "String" } } },
"storeRecommendedTitle": "Add a public source — one click",
"storeRecommendedBody": "Curated MCP servers reachable over HTTPS. No subprocess, no API key, no Node. Federated capabilities appear in the store immediately.",
"storeRecommendedAddTooltip": "Add and discover",
"storeRecommendedAdding": "Adding…",
"storeRecommendedDeepWikiTagline": "GitHub repo documentation search (AI-powered)",
"storeRecommendedSemgrepTagline": "Security scanning for code vulnerabilities",
"storeProviderAddedToast": "Added {name} — {n} federated {n, plural, =1{capability} other{capabilities}}.",
"@storeProviderAddedToast": {
"placeholders": {
"name": { "type": "String" },
"n": { "type": "int" }
}
},
"storeProviderAddFailed": "Could not add {name}: {error}",
"@storeProviderAddFailed": {
"placeholders": {
"name": { "type": "String" },
"error": { "type": "String" }
}
},
"auditTitle": "Audit",
"auditNoEvents": "No events yet",

View file

@ -890,23 +890,101 @@ abstract class AppLocalizations {
/// **'Could not load README.'**
String get storeDocsErrorGeneric;
/// No description provided for @storeFederationNudgeTitle.
/// No description provided for @storeSourceLabel.
///
/// In en, this message translates to:
/// **'Want more capabilities?'**
String get storeFederationNudgeTitle;
/// **'Source'**
String get storeSourceLabel;
/// No description provided for @storeFederationNudgeBody.
/// No description provided for @storeSourceAll.
///
/// In en, this message translates to:
/// **'Configure an MCP server or n8n endpoint in Settings → MCP Clients / N8N Endpoints. Discovered tools and workflows surface here as `mcp.<server>.<tool>` and `n8n.<endpoint>.<workflow>` capabilities — every Anthropic / community MCP server adds a handful at once.'**
String get storeFederationNudgeBody;
/// **'All sources'**
String get storeSourceAll;
/// No description provided for @storeFederationNudgeButton.
/// No description provided for @storeSourceNative.
///
/// In en, this message translates to:
/// **'Open Settings'**
String get storeFederationNudgeButton;
/// **'Native'**
String get storeSourceNative;
/// No description provided for @storeSourceMcp.
///
/// In en, this message translates to:
/// **'MCP'**
String get storeSourceMcp;
/// No description provided for @storeSourceN8n.
///
/// In en, this message translates to:
/// **'n8n'**
String get storeSourceN8n;
/// No description provided for @storeProvenanceNative.
///
/// In en, this message translates to:
/// **'native'**
String get storeProvenanceNative;
/// No description provided for @storeProvenanceMcp.
///
/// In en, this message translates to:
/// **'mcp · {provider}'**
String storeProvenanceMcp(String provider);
/// No description provided for @storeProvenanceN8n.
///
/// In en, this message translates to:
/// **'n8n · {provider}'**
String storeProvenanceN8n(String provider);
/// No description provided for @storeRecommendedTitle.
///
/// In en, this message translates to:
/// **'Add a public source — one click'**
String get storeRecommendedTitle;
/// No description provided for @storeRecommendedBody.
///
/// In en, this message translates to:
/// **'Curated MCP servers reachable over HTTPS. No subprocess, no API key, no Node. Federated capabilities appear in the store immediately.'**
String get storeRecommendedBody;
/// No description provided for @storeRecommendedAddTooltip.
///
/// In en, this message translates to:
/// **'Add and discover'**
String get storeRecommendedAddTooltip;
/// No description provided for @storeRecommendedAdding.
///
/// In en, this message translates to:
/// **'Adding…'**
String get storeRecommendedAdding;
/// No description provided for @storeRecommendedDeepWikiTagline.
///
/// In en, this message translates to:
/// **'GitHub repo documentation search (AI-powered)'**
String get storeRecommendedDeepWikiTagline;
/// No description provided for @storeRecommendedSemgrepTagline.
///
/// In en, this message translates to:
/// **'Security scanning for code vulnerabilities'**
String get storeRecommendedSemgrepTagline;
/// No description provided for @storeProviderAddedToast.
///
/// In en, this message translates to:
/// **'Added {name} — {n} federated {n, plural, =1{capability} other{capabilities}}.'**
String storeProviderAddedToast(String name, int n);
/// No description provided for @storeProviderAddFailed.
///
/// In en, this message translates to:
/// **'Could not add {name}: {error}'**
String storeProviderAddFailed(String name, String error);
/// No description provided for @auditTitle.
///

View file

@ -471,14 +471,70 @@ class AppLocalizationsDe extends AppLocalizations {
String get storeDocsErrorGeneric => 'README konnte nicht geladen werden.';
@override
String get storeFederationNudgeTitle => 'Mehr Capabilities?';
String get storeSourceLabel => 'Quelle';
@override
String get storeFederationNudgeBody =>
'MCP-Server oder n8n-Endpunkt unter Einstellungen → MCP-Clients / N8N-Endpunkte konfigurieren. Entdeckte Tools und Workflows tauchen hier als `mcp.<server>.<tool>`- und `n8n.<endpoint>.<workflow>`-Capabilities auf — jeder Anthropic-/Community-MCP-Server bringt mehrere auf einmal.';
String get storeSourceAll => 'Alle Quellen';
@override
String get storeFederationNudgeButton => 'Einstellungen öffnen';
String get storeSourceNative => 'Nativ';
@override
String get storeSourceMcp => 'MCP';
@override
String get storeSourceN8n => 'n8n';
@override
String get storeProvenanceNative => 'nativ';
@override
String storeProvenanceMcp(String provider) {
return 'mcp · $provider';
}
@override
String storeProvenanceN8n(String provider) {
return 'n8n · $provider';
}
@override
String get storeRecommendedTitle =>
'Öffentliche Quelle hinzufügen — ein Klick';
@override
String get storeRecommendedBody =>
'Kuratierte MCP-Server über HTTPS erreichbar. Kein Subprozess, kein API-Key, kein Node. Föderierte Capabilities erscheinen sofort im Store.';
@override
String get storeRecommendedAddTooltip => 'Hinzufügen und entdecken';
@override
String get storeRecommendedAdding => 'Wird hinzugefügt…';
@override
String get storeRecommendedDeepWikiTagline =>
'GitHub-Repo-Doku-Suche (KI-gestützt)';
@override
String get storeRecommendedSemgrepTagline =>
'Security-Scanning für Code-Schwachstellen';
@override
String storeProviderAddedToast(String name, int n) {
String _temp0 = intl.Intl.pluralLogic(
n,
locale: localeName,
other: 'föderierte Capabilities',
one: 'föderierte Capability',
);
return '$name hinzugefügt — $n $_temp0.';
}
@override
String storeProviderAddFailed(String name, String error) {
return '$name konnte nicht hinzugefügt werden: $error';
}
@override
String get auditTitle => 'Protokoll';

View file

@ -489,14 +489,69 @@ class AppLocalizationsEn extends AppLocalizations {
String get storeDocsErrorGeneric => 'Could not load README.';
@override
String get storeFederationNudgeTitle => 'Want more capabilities?';
String get storeSourceLabel => 'Source';
@override
String get storeFederationNudgeBody =>
'Configure an MCP server or n8n endpoint in Settings → MCP Clients / N8N Endpoints. Discovered tools and workflows surface here as `mcp.<server>.<tool>` and `n8n.<endpoint>.<workflow>` capabilities — every Anthropic / community MCP server adds a handful at once.';
String get storeSourceAll => 'All sources';
@override
String get storeFederationNudgeButton => 'Open Settings';
String get storeSourceNative => 'Native';
@override
String get storeSourceMcp => 'MCP';
@override
String get storeSourceN8n => 'n8n';
@override
String get storeProvenanceNative => 'native';
@override
String storeProvenanceMcp(String provider) {
return 'mcp · $provider';
}
@override
String storeProvenanceN8n(String provider) {
return 'n8n · $provider';
}
@override
String get storeRecommendedTitle => 'Add a public source — one click';
@override
String get storeRecommendedBody =>
'Curated MCP servers reachable over HTTPS. No subprocess, no API key, no Node. Federated capabilities appear in the store immediately.';
@override
String get storeRecommendedAddTooltip => 'Add and discover';
@override
String get storeRecommendedAdding => 'Adding…';
@override
String get storeRecommendedDeepWikiTagline =>
'GitHub repo documentation search (AI-powered)';
@override
String get storeRecommendedSemgrepTagline =>
'Security scanning for code vulnerabilities';
@override
String storeProviderAddedToast(String name, int n) {
String _temp0 = intl.Intl.pluralLogic(
n,
locale: localeName,
other: 'capabilities',
one: 'capability',
);
return 'Added $name$n federated $_temp0.';
}
@override
String storeProviderAddFailed(String name, String error) {
return 'Could not add $name: $error';
}
@override
String get auditTitle => 'Audit';