diff --git a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java index 21e0c07f0..2a84e3f59 100644 --- a/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java +++ b/app/src/main/java/io/xpipe/app/ext/DataStoreProvider.java @@ -58,10 +58,6 @@ public interface DataStoreProvider { return new SimpleBooleanProperty(false); } - default boolean alwaysShowSummary() { - return false; - } - default void validate() { if (getUsageCategory() == null) { throw ExtensionException.corrupt("Provider %s does not have the usage category".formatted(getId())); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/DenseStoreEntryComp.java b/app/src/main/java/io/xpipe/app/hub/comp/DenseStoreEntryComp.java index af8d67e12..09cd3ddc5 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/DenseStoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/DenseStoreEntryComp.java @@ -3,6 +3,7 @@ package io.xpipe.app.hub.comp; import io.xpipe.app.comp.Comp; import io.xpipe.app.comp.augment.GrowAugment; import io.xpipe.app.core.AppFontSizes; +import io.xpipe.app.core.AppI18n; import io.xpipe.core.process.OsType; import javafx.beans.binding.Bindings; @@ -35,14 +36,16 @@ public class DenseStoreEntryComp extends StoreEntryComp { .textProperty() .bind(Bindings.createStringBinding( () -> { - var val = summary.getValue(); - var p = getWrapper().getEntry().getProvider(); - if (val != null && grid.isHover() && p.alwaysShowSummary()) { - return val; - } else if (info.getValue() == null && p.alwaysShowSummary()) { - return val; + var summaryValue = summary.getValue(); + var infoValue = info.getValue(); + if (summaryValue != null && infoValue != null && grid.isHover()) { + return summaryValue; + } else if (infoValue == null && summaryValue != null) { + return summaryValue; + } else if (summaryValue == null && infoValue != null) { + return infoValue; } else { - return info.getValue(); + return null; } }, grid.hoverProperty(), @@ -60,7 +63,7 @@ public class DenseStoreEntryComp extends StoreEntryComp { @Override public int getHeight() { - return OsType.getLocal() == OsType.WINDOWS ? 38 : 37; + return 37; } protected Region createContent() { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StandardStoreEntryComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StandardStoreEntryComp.java index b01a2cd8d..f3c81ce41 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StandardStoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StandardStoreEntryComp.java @@ -2,8 +2,10 @@ package io.xpipe.app.hub.comp; import io.xpipe.app.comp.Comp; import io.xpipe.app.core.AppFontSizes; +import io.xpipe.app.core.AppI18n; import io.xpipe.core.process.OsType; +import javafx.beans.binding.Bindings; import javafx.geometry.HPos; import javafx.geometry.Insets; import javafx.geometry.Pos; @@ -28,7 +30,15 @@ public class StandardStoreEntryComp extends StoreEntryComp { private Label createSummary() { var summary = new Label(); - summary.textProperty().bind(getWrapper().getShownSummary()); + summary.textProperty().bind(Bindings.createStringBinding(() -> { + var summaryValue = getWrapper().getShownSummary().getValue(); + if (summaryValue != null) { + return summaryValue; + } else { + var provider = getWrapper().getEntry().getProvider(); + return AppI18n.get(provider.getId() + ".displayName"); + } + })); summary.getStyleClass().add("summary"); AppFontSizes.xs(summary); return summary; diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationMenu.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationMenu.java index 381231687..fdc015c74 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationMenu.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationMenu.java @@ -50,26 +50,26 @@ public class StoreCreationMenu { automatically.disableProperty().bind(disableSearch); } - menu.getItems().add(category("addHost", "mdi2h-home-plus", DataStoreCreationCategory.HOST, "ssh")); + menu.getItems().add(categoryMenu("addHost", "mdi2h-home-plus", DataStoreCreationCategory.HOST, "ssh")); - menu.getItems().add(category("addDesktop", "mdi2c-camera-plus", DataStoreCreationCategory.DESKTOP, null)); + menu.getItems().add(categoryMenu("addDesktop", "mdi2c-camera-plus", DataStoreCreationCategory.DESKTOP, null)); menu.getItems() - .add(category("addScript", "mdi2s-script-text-outline", DataStoreCreationCategory.SCRIPT, "script")); + .add(categoryMenu("addScript", "mdi2s-script-text-outline", DataStoreCreationCategory.SCRIPT, "script")); - menu.getItems().add(category("addCommand", "mdi2c-code-greater-than", DataStoreCreationCategory.COMMAND, null)); + menu.getItems().add(categoryMenu("addCommand", "mdi2c-code-greater-than", DataStoreCreationCategory.COMMAND, null)); menu.getItems() - .add(category("addService", "mdi2l-link-plus", DataStoreCreationCategory.SERVICE, "customService")); + .add(categoryMenu("addService", "mdi2l-link-plus", DataStoreCreationCategory.SERVICE, "customService")); menu.getItems() - .add(category( + .add(categoryMenu( "addTunnel", "mdi2v-vector-polyline-plus", DataStoreCreationCategory.TUNNEL, "sshLocalTunnel")); - menu.getItems().add(category("addSerial", "mdi2s-serial-port", DataStoreCreationCategory.SERIAL, "serial")); + menu.getItems().add(categoryMenu("addSerial", "mdi2s-serial-port", DataStoreCreationCategory.SERIAL, "serial")); menu.getItems() - .add(category( + .add(categoryMenu( "addIdentity", "mdi2a-account-multiple-plus", DataStoreCreationCategory.IDENTITY, @@ -93,29 +93,6 @@ public class StoreCreationMenu { menu.getItems().add(actionMenu); } - private static MenuItem category( - String name, String graphic, DataStoreCreationCategory category, String defaultProvider) { - var sub = DataStoreProviders.getAll().stream() - .filter(dataStoreProvider -> category.equals(dataStoreProvider.getCreationCategory())) - .toList(); - if (sub.size() < 2) { - var item = new MenuItem(); - item.setGraphic(new FontIcon(graphic)); - item.textProperty().bind(AppI18n.observable(name)); - item.setOnAction(event -> { - StoreCreationDialog.showCreation( - defaultProvider != null - ? DataStoreProviders.byId(defaultProvider).orElseThrow() - : null, - category); - event.consume(); - }); - return item; - } - - return categoryMenu(name, graphic, category, defaultProvider); - } - private static Menu categoryMenu( String name, String graphic, DataStoreCreationCategory category, String defaultProvider) { var sub = DataStoreProviders.getAll().stream() diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java index 0ad199ffa..1d1bec0c1 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java @@ -8,9 +8,11 @@ import io.xpipe.app.comp.base.VerticalComp; import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppLayoutModel; +import io.xpipe.app.prefs.AppPrefs; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableValue; +import javafx.css.PseudoClass; import javafx.geometry.Insets; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; @@ -53,6 +55,10 @@ public class StoreEntryListComp extends SimpleComp { StoreViewState.get().getFilterString().addListener((observable, oldValue, newValue) -> { struc.get().setVvalue(0); }); + + AppPrefs.get().condenseConnectionDisplay().subscribe(dense -> { + struc.get().pseudoClassStateChanged(PseudoClass.getPseudoClass("dense"), dense); + }); }); content.styleClass("store-list-comp"); content.vgrow(); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryWrapper.java index ac67ac5b6..8fc926db2 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryWrapper.java @@ -233,8 +233,7 @@ public class StoreEntryWrapper { summary.setValue(null); } else { try { - summary.setValue( - entry.getProvider() != null ? entry.getProvider().summaryString(this) : null); + summary.setValue(entry.getProvider() != null ? entry.getProvider().summaryString(this) : null); } catch (Exception ex) { // Summary creation might fail or have a bug ErrorEventFactory.fromThrowable(ex).handle(); diff --git a/app/src/main/java/io/xpipe/app/prefs/AppPrefsSidebarComp.java b/app/src/main/java/io/xpipe/app/prefs/AppPrefsSidebarComp.java index fceca547e..6eb91183e 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefsSidebarComp.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefsSidebarComp.java @@ -36,7 +36,7 @@ public class AppPrefsSidebarComp extends SimpleComp { AppPrefs.get().getSelectedCategory().setValue(appPrefsCategory); }) .apply(struc -> { - struc.get().setGraphicTextGap(7); + struc.get().setGraphicTextGap(9); struc.get().setTextAlignment(TextAlignment.LEFT); struc.get().setAlignment(Pos.CENTER_LEFT); AppPrefs.get().getSelectedCategory().subscribe(val -> { diff --git a/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java b/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java index 88ce203c7..5bb00356f 100644 --- a/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java +++ b/app/src/main/java/io/xpipe/app/util/DataStoreFormatter.java @@ -41,18 +41,6 @@ public class DataStoreFormatter { return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); } - public static String toApostropheName(DataStoreEntry input) { - return toName(input, Integer.MAX_VALUE) + "'s"; - } - - public static String toName(DataStoreEntry input, int length) { - if (input == null) { - return "?"; - } - - return cut(input.getName(), length); - } - public static String split(String left, String separator, String right, int length) { var half = (length / 2) - separator.length(); return cut(left, half) + separator + cut(right, length - half); diff --git a/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css index 6ff8d4415..2ccf96cd7 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/store-entry-comp.css @@ -30,6 +30,10 @@ -fx-padding: 4 0 4 0; } +.store-list-comp.scroll-pane:dense > .viewport .list-box-content { + -fx-spacing: 2; +} + .store-list-comp.scroll-pane { -fx-padding: 0 0 0 2; } @@ -178,7 +182,7 @@ } .store-entry-section-comp:last:sub { - -fx-padding: 0 0 3 0; + -fx-padding: 0 0 1 0; } .store-entry-section-comp:last:sub:expanded { diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java index f85719fe4..575debecb 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java @@ -98,11 +98,6 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider { .buildDialog(); } - public String summaryString(StoreEntryWrapper wrapper) { - DesktopApplicationStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName(s.getDesktop().get()) + " config"; - } - @Override public String getDisplayIconFileName(DataStore store) { return "base:desktopApplication_icon.svg"; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStoreProvider.java index 33ee01fd3..17ed59d05 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/LocalIdentityStoreProvider.java @@ -67,12 +67,6 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider { .buildDialog(); } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - var st = (LocalIdentityStore) wrapper.getStore().getValue(); - return AppI18n.get("localIdentity"); - } - @Override public String getId() { return "localIdentity"; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStoreProvider.java index e1683a496..66e7c33dc 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/PasswordManagerIdentityStoreProvider.java @@ -44,11 +44,6 @@ public class PasswordManagerIdentityStoreProvider extends IdentityStoreProvider .buildDialog(); } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - return AppI18n.get("passwordManagerIdentity"); - } - @Override public String getId() { return "passwordManagerIdentity"; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java index 83f2a42f0..69d980ac1 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java @@ -86,11 +86,6 @@ public class ScriptGroupStoreProvider implements EnabledParentStoreProvider, Dat return new SimpleStringProperty(scriptStore.getDescription()); } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - return "Script group"; - } - @Override public String getDisplayIconFileName(DataStore store) { return "proc:shellEnvironment_icon.svg"; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index dceeb0493..286d5423b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -202,11 +202,6 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da .buildDialog(); } - @Override - public boolean alwaysShowSummary() { - return true; - } - @Override public String summaryString(StoreEntryWrapper wrapper) { SimpleScriptStore st = wrapper.getEntry().getStore().asNeeded(); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java index 39a100ca0..dc3178b9d 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStoreProvider.java @@ -108,12 +108,6 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt : List.of("" + s.getRemotePort()); } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - AbstractServiceStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName(s.getHost().get()) + " service"; - } - @Override public ObservableValue informationString(StoreSection section) { return Bindings.createStringBinding( diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStoreProvider.java index cf649fcb8..ea24e47fb 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceControlStoreProvider.java @@ -47,12 +47,6 @@ public class ServiceControlStoreProvider implements SingletonSessionStoreProvide CustomServiceGroupStore.builder().parent(s.getHost()).build()); } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - ServiceControlStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName(s.getHost().get()) + " service control"; - } - @Override public ObservableValue informationString(StoreSection section) { ServiceControlStore s = section.getWrapper().getEntry().getStore().asNeeded(); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java index e905dd9af..12058c22d 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java @@ -90,13 +90,6 @@ public class IncusContainerStoreProvider implements ShellStoreProvider { return q; } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - IncusContainerStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName( - s.getInstall().getStore().getHost().get()) + " container"; - } - @Override public ObservableValue informationString(StoreSection section) { var c = (ContainerStoreState) section.getWrapper().getPersistentState().getValue(); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java index 230abccc9..cfffafc5f 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusInstallStoreProvider.java @@ -56,11 +56,6 @@ public class IncusInstallStoreProvider implements DataStoreProvider { return s.getHost().get(); } - public String summaryString(StoreEntryWrapper wrapper) { - IncusInstallStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName(s.getHost().get()) + " containers"; - } - @Override public ObservableValue informationString(StoreSection section) { return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> { diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java index 066f05991..0d8f63ba1 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdCmdStoreProvider.java @@ -56,11 +56,6 @@ public class LxdCmdStoreProvider implements DataStoreProvider { return s.getHost().get(); } - public String summaryString(StoreEntryWrapper wrapper) { - LxdCmdStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName(s.getHost().get()) + " containers"; - } - @Override public ObservableValue informationString(StoreSection section) { return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> { diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java index dc7cb0afe..55e38a8ff 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java @@ -85,13 +85,6 @@ public class LxdContainerStoreProvider implements ShellStoreProvider { return q; } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - LxdContainerStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName( - s.getCmd().getStore().getHost().get()) + " container"; - } - @Override public ObservableValue informationString(StoreSection section) { var c = (ContainerStoreState) section.getWrapper().getPersistentState().getValue(); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java index dfd385566..727ea3584 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanCmdStoreProvider.java @@ -56,11 +56,6 @@ public class PodmanCmdStoreProvider implements DataStoreProvider { return s.getHost().get(); } - public String summaryString(StoreEntryWrapper wrapper) { - PodmanCmdStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName(s.getHost().get()) + " containers"; - } - @Override public ObservableValue informationString(StoreSection section) { return BindingsHelper.map(section.getWrapper().getPersistentState(), o -> { diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java index 8d0606b69..db1c25a9c 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java @@ -85,13 +85,6 @@ public class PodmanContainerStoreProvider implements ShellStoreProvider { return new GuiDialog(q, val); } - @Override - public String summaryString(StoreEntryWrapper wrapper) { - PodmanContainerStore s = wrapper.getEntry().getStore().asNeeded(); - return DataStoreFormatter.toApostropheName( - s.getCmd().getStore().getHost().get()) + " container"; - } - @Override public ObservableValue informationString(StoreSection section) { var c = (ContainerStoreState) section.getWrapper().getPersistentState().getValue(); diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index 67a3ff918..181f485d0 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -960,7 +960,8 @@ gitVaultIdentityStrategyDescription=If you chose to use an SSH git URL as the re dockerContainers=Docker containers dockerCmd.displayName=docker CLI client dockerCmd.displayDescription=Access Docker containers via the docker CLI client -wslCmd.displayName=wsl client +#force +wslCmd.displayName=WSL install wslCmd.displayDescription=Access WSL instances via the wsl CLI client k8sCmd.displayName=kubectl client k8sCmd.displayDescription=Access Kubernetes clusters via kubectl