chain-studio/lib/data/store_caps.dart
flemming-it 08227410e6
Some checks are pending
Security / Security check (push) Waiting to run
fix(flows): only offer install for capabilities the store resolves
The capability set behind the flow editor's Install quick-fix and
the flow list's install badge ingested every store entry's
requiresCapabilities (dependencies, not provided capabilities) and
ignored entry status/kind. Clicking Install on such a capability
ended in the hub's "no store entry for '<name>'" error.

The set now mirrors the hub's install resolver (entry names only,
no planned or federated entries) via installableStoreCapabilities()
with unit tests for both classification states. Unresolvable
capabilities render the editor's 'not in store' state, which
explains the three recovery paths before any click; the editor pin
moves to 0.25.0 (commit-pinned until its tag exists) and the dialog
harness captures the badge states light+dark. Studio 0.78.0.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
2026-07-22 13:46:08 +02:00

30 lines
1.2 KiB
Dart

// Store-resolvability: which capabilities can the store actually
// install? This is the data source behind the flow editor's
// "Install" quick-fix and the flow list's install badge — it must
// mirror the hub's install resolver (exact entry name, an
// installable version, native bundle), or the UI offers installs
// that end in "no store entry for '<name>'".
import 'hub.dart';
/// Bare capability names a store entry can install right now.
///
/// Mirrors the hub's `resolve_install_plan` acceptance rules:
/// - only the entry's own `name` counts — `requiresCapabilities`
/// are the entry's DEPENDENCIES, not things it provides, and
/// must never be offered as installable;
/// - `planned` entries have no downloadable version yet;
/// - `federated` entries route through a bridge (MCP/n8n), not
/// the bundle-install path.
/// An empty `status` (older hub without the field) keeps the
/// entry installable — the classified install error is the net
/// underneath that skew.
Set<String> installableStoreCapabilities(Iterable<StoreItem> items) {
final caps = <String>{};
for (final item in items) {
if (item.isFederated) continue;
if (item.status == 'planned') continue;
caps.add(item.name);
}
return caps;
}