Handle powershell fail better

This commit is contained in:
crschnick
2025-07-21 06:16:54 +00:00
parent cf231f461b
commit 08dafc1d70
14 changed files with 261 additions and 17 deletions

View File

@@ -374,7 +374,7 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
startIfNeeded();
var fs = getFileSystem();
var stream = fs.listFiles(dir);
var stream = fs.listFiles(fs, dir);
consumer.accept(stream);
} else {
consumer.accept(Stream.of());
@@ -387,7 +387,7 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
startIfNeeded();
var fs = getFileSystem();
if (dir != null) {
var stream = fs.listFiles(dir);
var stream = fs.listFiles(fs, dir);
fileList.setAll(stream);
} else {
fileList.setAll(Stream.of());

View File

@@ -187,8 +187,9 @@ public class BrowserFileTransferOperation {
}
private void handleSingleOnSameFileSystem(FileEntry source) throws Exception {
// Prevent dropping directory into itself
if (source.getPath().equals(target.getPath())) {
// Prevent dropping files into itself
if ((source.getKind() == FileKind.DIRECTORY && source.getPath().equals(target.getPath()))
|| (source.getKind() != FileKind.DIRECTORY && source.getPath().getParent().equals(target.getPath()))) {
return;
}
@@ -278,7 +279,7 @@ public class BrowserFileTransferOperation {
flatFiles.put(source, directoryName);
var baseRelative = source.getPath().getParent().toDirectory();
List<FileEntry> list = source.getFileSystem().listFilesRecursively(source.getPath());
List<FileEntry> list = source.getFileSystem().listFilesRecursively(source.getFileSystem(), source.getPath());
for (FileEntry fileEntry : list) {
if (cancelled()) {
return;

View File

@@ -94,6 +94,12 @@ public abstract class OperationMode {
return;
}
// There are some accessibility exceptions on macOS, nothing we can do about that
if (Platform.isFxApplicationThread() && ex instanceof NullPointerException && ex.getMessage() != null && ex.getMessage().contains("Accessible")) {
ErrorEventFactory.fromThrowable(ex).expected().omit().build().handle();
return;
}
// Handle any startup uncaught errors
if (OperationMode.isInStartup() && thread.threadId() == 1) {
ex.printStackTrace();

View File

@@ -219,8 +219,8 @@ public class ConnectionFileSystem implements FileSystem {
}
@Override
public Stream<FileEntry> listFiles(FilePath file) throws Exception {
return shellControl.getShellDialect().listFiles(this, shellControl, file.toString(), true);
public Stream<FileEntry> listFiles(FileSystem system, FilePath file) throws Exception {
return shellControl.getShellDialect().listFiles(system, shellControl, file.toString(), true);
}
@Override

View File

@@ -48,11 +48,11 @@ public interface FileSystem extends Closeable, AutoCloseable {
Optional<FileEntry> getFileInfo(FilePath file) throws Exception;
Stream<FileEntry> listFiles(FilePath file) throws Exception;
Stream<FileEntry> listFiles(FileSystem system, FilePath file) throws Exception;
default List<FileEntry> listFilesRecursively(FilePath file) throws Exception {
default List<FileEntry> listFilesRecursively(FileSystem system, FilePath file) throws Exception {
List<FileEntry> base;
try (var filesStream = listFiles(file)) {
try (var filesStream = listFiles(system, file)) {
base = filesStream.toList();
}
return base.stream()
@@ -64,7 +64,7 @@ public interface FileSystem extends Closeable, AutoCloseable {
try {
var list = new ArrayList<FileEntry>();
list.add(fileEntry);
list.addAll(listFilesRecursively(fileEntry.getPath()));
list.addAll(listFilesRecursively(system, fileEntry.getPath()));
return list.stream();
} catch (Exception e) {
throw new RuntimeException(e);

View File

@@ -166,12 +166,12 @@ public class WrapperFileSystem implements FileSystem {
}
@Override
public Stream<FileEntry> listFiles(FilePath file) throws Exception {
public Stream<FileEntry> listFiles(FileSystem system, FilePath file) throws Exception {
if (!check.get()) {
return Stream.empty();
}
return fs.listFiles(file);
return fs.listFiles(system, file);
}
@Override

View File

@@ -154,6 +154,34 @@ public interface ExternalEditorType extends PrefsChoiceValue {
}
};
WindowsType KIRO_WINDOWS = new WindowsType() {
@Override
public String getId() {
return "app.kiro";
}
@Override
public boolean detach() {
return false;
}
@Override
public String getExecutable() {
return "kiro.cmd";
}
@Override
public Optional<Path> determineInstallation() {
return Optional.of(Path.of(System.getenv("LOCALAPPDATA"))
.resolve("Programs")
.resolve("Kiro")
.resolve("bin")
.resolve("kiro.cmd"))
.filter(path -> Files.exists(path));
}
};
// Cli is broken, keep inactive
WindowsType THEIAIDE_WINDOWS = new WindowsType() {
@@ -311,6 +339,10 @@ public interface ExternalEditorType extends PrefsChoiceValue {
LinuxPathType WINDSURF_LINUX = new LinuxPathType("app.windsurf", "windsurf");
LinuxPathType CURSOR_LINUX = new LinuxPathType("app.cursor", "cursor");
LinuxPathType KIRO_LINUX = new LinuxPathType("app.kiro", "kiro");
LinuxPathType ZED_LINUX = new LinuxPathType("app.zed", "zed");
ExternalEditorType ZED_MACOS = new MacOsEditor("app.zed", "Zed");
@@ -336,6 +368,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
ExternalEditorType CURSOR_MACOS = new MacOsEditor("app.cursor", "Cursor");
ExternalEditorType VOID_MACOS = new MacOsEditor("app.void", "Void");
ExternalEditorType WINDSURF_MACOS = new MacOsEditor("app.windsurf", "Windsurf");
ExternalEditorType KIRO_MACOS = new MacOsEditor("app.kiro", "Kiro");
ExternalEditorType TRAE_MACOS = new MacOsEditor("app.trae", "Trae");
ExternalEditorType CUSTOM = new ExternalEditorType() {
@@ -384,6 +417,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
CURSOR_WINDOWS,
WINDSURF_WINDOWS,
TRAE_WINDOWS,
KIRO_WINDOWS,
VSCODIUM_WINDOWS,
VSCODE_INSIDERS_WINDOWS,
VSCODE_WINDOWS,
@@ -391,6 +425,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
NOTEPAD);
List<LinuxPathType> LINUX_EDITORS = List.of(
ExternalEditorType.WINDSURF_LINUX,
ExternalEditorType.KIRO_LINUX,
VSCODIUM_LINUX,
VSCODE_LINUX,
ZED_LINUX,
@@ -399,11 +434,13 @@ public interface ExternalEditorType extends PrefsChoiceValue {
PLUMA,
LEAFPAD,
MOUSEPAD,
GNOME);
GNOME,
ExternalEditorType.CURSOR_LINUX);
List<ExternalEditorType> MACOS_EDITORS = List.of(
VOID_MACOS,
CURSOR_MACOS,
WINDSURF_MACOS,
KIRO_MACOS,
TRAE_MACOS,
BBEDIT,
VSCODIUM_MACOS,

View File

@@ -5,6 +5,8 @@ import io.xpipe.core.OsType;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
public interface OsFileSystem {
@@ -30,14 +32,21 @@ public interface OsFileSystem {
default FilePath makeFileSystemCompatible(FilePath name) {
var split = name.split();
var needsReplacement = split.stream().anyMatch(s -> !s.equals(makeFileSystemCompatible(s)));
var needsReplacement = split.stream().skip(hasMultipleRoots() ? 1 : 0).anyMatch(s -> !s.equals(makeFileSystemCompatible(s)));
if (!needsReplacement) {
return name;
}
var p = Pattern.compile("[^/\\\\]+");
var m = p.matcher(name.toString());
var replaced = m.replaceAll(matchResult -> makeFileSystemCompatible(matchResult.group()));
var first = new AtomicBoolean(true);
var replaced = m.replaceAll(matchResult -> {
if (first.getAndSet(false) && hasMultipleRoots()) {
return matchResult.group();
}
return makeFileSystemCompatible(matchResult.group());
});
return FilePath.of(replaced);
}
@@ -49,6 +58,8 @@ public interface OsFileSystem {
String getFileSystemSeparator();
boolean hasMultipleRoots();
final class Windows implements OsFileSystem {
@Override
@@ -83,6 +94,11 @@ public interface OsFileSystem {
public String getFileSystemSeparator() {
return "\\";
}
@Override
public boolean hasMultipleRoots() {
return true;
}
}
class Unix implements OsFileSystem {
@@ -134,6 +150,11 @@ public interface OsFileSystem {
public String getFileSystemSeparator() {
return "/";
}
@Override
public boolean hasMultipleRoots() {
return false;
}
}
final class MacOs implements OsFileSystem {
@@ -169,5 +190,10 @@ public interface OsFileSystem {
public String getFileSystemSeparator() {
return "/";
}
@Override
public boolean hasMultipleRoots() {
return false;
}
}
}

154
dist/changelogs/17.2.md vendored Normal file
View File

@@ -0,0 +1,154 @@
XPipe 17 is a large-scale rework of many existing parts of XPipe. It focuses on fixing many longstanding issues and limitations, so that future updates can easily bring new integrations without having to deal with that baggage.
The documentation for all the new features is already available at http://docs.xpipe.io/
## Actions
There is now a new action system, which maps most UI actions to fixed schemas. This means that you can now automate almost any action that you can perform from the UI via desktop shortcuts, URLs, HTTP API calls, and more. You can configure action shortcuts with the new action configuration dialog and control how to call the action from it.
Furthermore, it is also now possible to control how all of these actions are run. For production systems, for example, you can configure that all actions that perform some kind of modification, like deleting a file or running a script, have to be confirmed first. This gives you an added layer of protection to double-check any operation before actually executing it.
![Actions screenshot](https://xpipe.io/assets/images/BlogPage/actions.png)
[Action Documentation](https://docs.xpipe.io/guide/actions)
## SSH
There is now proper support for jump servers. While gateways worked similar to jump servers, they were a different concept and did not work for cases where the ProxyJump functionality was required. You can now configure an SSH connection in its advanced settings to be treated as a jump server. This will result in XPipe using the ProxyJump syntax when this connection is used as a gateway for other SSH connections. This works for all kinds of connections, including config connections.
Furthermore, the SSH implementation for devices that don't provide a full shell, e.g. embedded devices and other limited systems, has been completely reworked. This fixes many issues where connections to such systems were not possible or failed. You can now designate an SSH connection as a limited system in its advanced settings, without the previous homelab plan requirement. This will then allow you to directly launch the connection, without any issues.
![SSH configuration screenshot](https://xpipe.io/assets/images/BlogPage/ssh-jump.png)
Services also now support opening them for limited/embedded systems with system interaction being disabled. Instead of locally tunneling the remote service to localhost, XPipe will try to open the host URL directly. This allows you to open the web interface of embedded devices for example, which previously was not possible.
Other changes:
- The option to open a connection in VSCode remote has been expanded to also support Cursor and Windsurf
- Active tunnels are now periodically refreshed to check if the underlying tunnel was closed
- Fix SSH agent variables being wrong on macOS when using homebrew ssh
- Fix automatic x11 display server forward to WSL not working on Windows
- Fix various gpg agent configuration issues
[SSH Documentation](https://docs.xpipe.io/guide/ssh)
## VNC
Up until now, the internal VNC implementation of XPipe did a somewhat acceptable job for most connections. However, it is not able to match dedicated VNC clients when it comes to more advanced features and authentication methods. There's simply not the development capacity to maintain all of these additional VNC features. For this reason, there is now support to also use an external VNC client with XPipe, just as with any other tool integrations.
![VNC settings screenshot](https://xpipe.io/assets/images/BlogPage/vnc-list.png)
[VNC Documentation](https://docs.xpipe.io/guide/vnc)
## macOS 26 Tahoe
XPipe adopts many of the new features of macOS 26 right away. if you are using the macOS beta, you have access to these right away.
The application window now uses the new Liquid Glass theming. The application icon has also been reworked with Liquid Glass in mind.
There's also support for the new apple containers framework, which has just been released. Searching for available connections on the local machine will make apple containers show up if you have installed the package.
![macOS Tahoe screenshot](https://xpipe.io/assets/images/BlogPage/tahoe.png)
## Windows ARM
There are now native Windows ARM builds. These releases are also available in choco and winget.
Note that you will have to uninstall any old x64 XPipe installation for the upgrade.
## File browser
The file browser has been improved in many areas:
- Operations which modify a single file, e.g. a file edit, will now automatically refresh the file list to show updated changes
- Add new file browser action to compute directory sizes
- The transfer speed in the file browser on Windows for multiple files has been improved
- Renaming a file now moves the caret to the end of the base file name
- The file browser now works much better in small windows sizes
- Fix terminal sometimes not being launched with the correct working directory of the current path
- Fix file deletion not showing errors when the operation failed in cmd
- Fix file renaming not working if previous rename operation was cancelled
- Fix file transfer kill button sometimes not working when transfer was frozen
- Fix file browser listing not working for older PowerShell systems
[File Browser Documentation](https://docs.xpipe.io/guide/file-browser)
## Connection hub
Proper functionality to organize a collection of hundreds of connections was always somewhat limited until now. There is now an additional index-based organization mechanism where you can assign and move indices of connections to have them listed at a certain place in relation to other connections. This can also be combined with the existing sorting methods like time and alphabetical sorting.
![Order settings screenshot](https://xpipe.io/assets/images/BlogPage/order-menu.png)
To move a set of children connections to the top-level, you can also use the new so-called breakout categories to create subviews of nested connections.
![Breakout category screenshot](https://xpipe.io/assets/images/BlogPage/category-breakout.png)
Furthermore, there are also more improvements in the connection hub:
- Renaming connection entries can now be done quickly from the context menu without having to open the configuration dialog
- You can now set connection configurations to be frozen, meaning that the connection entry can't be modified or deleted. This is helpful for templating and team vault setups
- When editing an incomplete connection configuration, the focus will automatically jump to the first incomplete/invalid value. This makes keyboard usage easier
[Connection Hub Documentation](https://docs.xpipe.io/guide/hub)
## Git vault
The git vault can now automatically resolve merge conflicts without restarts when multiple systems share the git repository. Any externally pushed commits are integrated into the connection hub instantly.
Furthermore, you can now specify a git username and password in the settings menu if your local system does not have a git client with configured credentials.
![Git auth screenshot](https://xpipe.io/assets/images/BlogPage/sync-auth.png)
[Sync Documentation](https://docs.xpipe.io/guide/sync)
## Serial
The serial connection support is no longer be considered experimental. It has been reworked, and the following issues have been fixed:
- Fix serial configuration parameter names being cut off in the dialog
- Connections to serial devices requiring root access are now automatically elevated
![Git auth screenshot](https://xpipe.io/assets/images/BlogPage/serial.png)
[Serial Documentation](https://docs.xpipe.io/guide/serial)
## HTTP API
The HTTP API has been improved in various areas. The action system is integrated in it, meaning that you can call any action from the API. Furthermore, there are now more API endpoints for categories so that you have proper control over them as well. There is also now a way to encrypt and decrypt secrets via the API, allowing you to create connections with integrated secrets with it as well.
[API Documentation](https://docs.xpipe.io/api)
## Other
- Various performance improvements
- Password managers now support retrieving both username and password of an entry. For that, you can now create password manager identities that automatically provide the username and password
- You can now specify an alternative user for shell environments to switch to via sudo
- Add support for nushell
- Add support for xonsh
- Add support for LXTerminal, the default on Raspberry Pi OS
- Add support to open a WinSCP session for an SSH connection
- Teleport connections now support reusable identities
- Changes made to /etc/sudoers files are now automatically checked with visudo and reverted if necessary
- Terminal logging on Windows can now use a WSL terminal environment to improve logging quality
- Terminal logs now strip any terminal escape codes
- Add a new loading icon
- Add note on how to fix potential blurriness on Gnome Wayland systems with high display scaling
- You can now disable icon sources without having to remove them
- Terminal connections now enable truecolor mode if possible
- Add notification when a password is copied to the clipboard
- Add support for Ghostty on macOS
- There is now a subreddit at https://www.reddit.com/r/xpipe/
- Update kasm workspaces image to support 1.17
- Filter mullvad exit nodes from tailscale list
## Fixes
- Fix local to synced identity conversion not updating existing connections
- Fix local to synced identity conversion not automatically adding key file to git
- Fix local identities category being able to be synced
- Fix pwsh connections on Linux/macOS freezing on sudo elevation
- Fix sudo elevation not working on WSL if WSLInterop for executables was disabled
- Fix clipboard data of other formats, e.g. files, being cleared after expiration of a copied password
- Fix text color on hover having low contrast in some themes
- Fix freeze after waking up the local system from a long hibernation
- Fix application not starting up if some antivirus interfered with local socket connections
- Fix kubectl apply changes functionality for pods not working
- Fix custom workspaces not working on Linux
- Fix KeePassXC snap installations not being detected

10
dist/changelogs/17.2_incremental.md vendored Normal file
View File

@@ -0,0 +1,10 @@
- Add support for the Kiro editor
- Fix file browser copy and move operations on same system manually
transferring files instead of just using tools like cp and mv
- Fix errors when reading local files with invalid encoded characters
- Fix error for script refresh context menu entry
- Fix errors when SSH config includes contain unsupported characters
- Fix error when %TEMP% variable was not set on Windows
- Fix error when git ssh key file was left empty
- Fix git sync being disabled if interval merge check failed once
- Fix winget build pipeline still being broken

View File

@@ -393,6 +393,14 @@ public class RunScriptActionProviderMenu implements HubBranchProvider<ShellStore
return new LabelGraphic.IconGraphic("mdi2i-image-filter-none");
}
@Override
public StoreAction<ShellStore> createAction(DataStoreEntryRef<ShellStore> ref) {
return RefreshActionProvider.Action.builder()
.ref(ref.asNeeded())
.build()
.asNeeded();
}
@Override
public StoreAction<ShellStore> createBatchAction(DataStoreEntryRef<ShellStore> ref) {
return RefreshActionProvider.Action.builder()

View File

@@ -115,6 +115,7 @@ xfreeRdp=xfreerdp
cosmicTerm=Cosmic Terminal
cursor=Cursor
windsurf=Windsurf
kiro=Kiro
trae=Trae
theiaide=TheiaIDE
keePassXc=KeePassXC

View File

@@ -881,6 +881,7 @@ attachContainer=Attach
openInVsCode=Open in VSCode
openInCursor=Open in Cursor
openInWindsurf=Open in Windsurf
openInKiro=Open in Kiro
containerLogs=Show logs
openSftpClient=Open in external SFTP client
openTermius=Open in Termius

View File

@@ -1 +1 @@
17.1
17.2