@hahahhh/sshx 0.0.4-rc.0 → 0.0.4-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +67 -6
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  **sshx** is a drop-in wrapper around OpenSSH. Wrap it as `alias ssh=sshx` and your existing SSH workflow works exactly as before — every flag, config, and connection passes through verbatim. But when you connect to a host (or Docker container) with sshx-aware features enabled, you unlock a persistent, shared remote server that gives you:
6
6
 
7
7
  - 🔄 **Reverse command bridge** — run `sshx local <cmd>` *on the remote* to execute commands on your local machine, with stdout, stderr, exit code, and stdin all propagated.
8
- - 📁 **Bidirectional workspace mount** — opt in to make the command initiator's current directory available to commands running on the other side.
8
+ - 📁 **Bidirectional home mount** — opt in to mount the command initiator's home while preserving the source path hierarchy and working directory.
9
9
  - 🔌 **Automatic port forwarding** — remote local listeners (loopback `127.0.0.1` and wildcard `0.0.0.0`; e.g., a dev server on `0.0.0.0:8080` or `localhost:8080`) are automatically detected and forwarded to your local machine.
10
10
  - 🌐 **Local domain binding** — access forwarded ports as `<host>.<your-user>.sshx:<port>` in your local browser, no manual `-L` flags needed.
11
11
  - 🐳 **Docker container support** — target running containers by name or ID: `sshx my-container`. Command bridge support works inside containers via `docker exec`.
@@ -62,16 +62,77 @@ sshx local --timeout=30 npm test
62
62
 
63
63
  ### 📁 Bidirectional Workspace Mount (opt-in, beta)
64
64
 
65
- Set `features.remoteFs: true` to expose the command initiator's current directory through a read-write FUSE mount:
65
+ Set `features.remoteFs: true` to expose the command initiator's home directory through a read-write FUSE mount. Its absolute hierarchy is preserved below the managed session directory (for example, `/Users/xiaot` becomes `<session>/Users/xiaot`):
66
66
 
67
- - `sshx remote <cmd>` starts the remote command in a mounted view of the local current directory.
68
- - An interactive `sshx remote` shell still starts in the remote home. `SSHX_WORKSPACE` points to the mounted local workspace.
69
- - From that shell, `sshx local <cmd>` mounts the remote current directory locally and starts the local command there.
67
+ - `sshx remote <cmd>` starts the remote command at the corresponding path inside the mounted local home.
68
+ - An interactive `sshx remote` shell still starts in the remote home. `SSHX_MOUNT_ROOT` points to the mounted source root and `SSHX_WORKSPACE` points to the mapped source working directory.
69
+ - From that shell, `sshx local <cmd>` mounts the remote home locally and starts the local command at the corresponding mapped path.
70
+ - If the source working directory is outside its home, sshx exports that directory as a safe fallback and still preserves its absolute hierarchy below the session directory.
70
71
  - Writes and `fsync` are sent to the source immediately. Metadata and directory entries use short TTLs and are revalidated when files are reopened.
71
72
 
73
+ The mounted home permits reads, writes, and creation, but blocks file/directory deletion and rename in both directions. It can still include sensitive files such as shell configuration and SSH credentials, so enable `remoteFs` only for targets you trust. sshx excludes its managed mount tree from reverse exports to avoid recursive mounts.
74
+
75
+ Set `FS_READ_ONLY=1` on the client when starting sshx to make the session mounts read-only:
76
+
77
+ ```sh
78
+ FS_READ_ONLY=1 sshx debian@orb pwd
79
+ ```
80
+
81
+ The client value is exported into the remote session. A later `sshx local <cmd>` inherits it, so the reverse mount is read-only as well.
82
+
72
83
  FUSE is a hard dependency when this feature is enabled: a mount failure aborts the command even when `strict` is false. Linux needs `/dev/fuse` plus `fusermount`/`fusermount3`; macOS needs a current macFUSE installation and is currently beta. The remote target must be Linux with FUSE available.
73
84
 
74
- The first version guarantees workspace-relative paths only. It does not rewrite absolute command arguments, add extra mount roots, expose special files/xattrs/ACLs, or support Docker targets, FUSE-T, or FSKit. It is optimized for source trees and small files rather than large-file throughput.
85
+ #### FUSE setup
86
+
87
+ The machine receiving the mounted view needs a working FUSE runtime. The Linux target therefore always needs FUSE for `sshx remote`; a macOS client also needs macFUSE when a remote shell runs `sshx local` and mounts the remote working directory back on the Mac.
88
+
89
+ **Linux target/client**
90
+
91
+ Install the FUSE 3 userspace tools (the kernel normally already includes the FUSE driver):
92
+
93
+ ```sh
94
+ # Debian / Ubuntu
95
+ sudo apt-get update && sudo apt-get install -y fuse3
96
+
97
+ # Fedora / RHEL-family
98
+ sudo dnf install -y fuse3
99
+
100
+ # Arch Linux
101
+ sudo pacman -S fuse3
102
+ ```
103
+
104
+ Verify both the device and unmount helper:
105
+
106
+ ```sh
107
+ test -r /dev/fuse && test -w /dev/fuse
108
+ command -v fusermount3 || command -v fusermount
109
+ ```
110
+
111
+ If `/dev/fuse` is missing on a normal Linux host, load the kernel module with `sudo modprobe fuse`. Containers and restricted VMs must also expose `/dev/fuse` and permit FUSE mounts; installing `fuse3` alone is not sufficient. Docker targets are not supported by `remoteFs` yet.
112
+
113
+ **macOS client (current sshx backend)**
114
+
115
+ Install the latest macFUSE release from [macfuse.io](https://macfuse.io/) (recommended by the macFUSE project) or with `brew install --cask macfuse`. The current sshx implementation uses macFUSE's kernel/VFS backend.
116
+
117
+ On Apple Silicon, first-time kernel-backend setup requires:
118
+
119
+ 1. Shut down, then hold the power/Touch ID button to enter macOS Recovery.
120
+ 2. Open Startup Security Utility, select the system volume, and choose **Reduced Security**.
121
+ 3. Enable **Allow user management of kernel extensions from identified developers**, then restart.
122
+ 4. In **System Settings → Privacy & Security**, allow the macFUSE system software when prompted, then restart again.
123
+
124
+ Intel Macs do not need the Startup Security Utility change, but may still require approving macFUSE in Privacy & Security and restarting. macFUSE does not require disabling SIP or Gatekeeper.
125
+
126
+ After approval, trigger a mount once and verify that macFUSE loaded:
127
+
128
+ ```sh
129
+ ls /Library/Filesystems/macfuse.fs
130
+ ls /dev/macfuse*
131
+ ```
132
+
133
+ **macOS 15.4+ FSKit note:** macFUSE 5 provides a userspace FSKit backend that does not require a kernel extension, Recovery-mode security changes, or a restart. It is not transparent to the current sshx mount implementation and is not enabled yet: macFUSE requires the explicit `-o backend=fskit` option, FSKit only supports mount points below `/Volumes`, and several traditional mount options are unavailable. sshx currently creates private mounts below the runtime temporary directory and supplies VFS-oriented options. Supporting FSKit therefore requires a dedicated mount-path/options adapter, although the RemoteFS wire protocol and file-operation backend can remain unchanged.
134
+
135
+ Absolute source paths are preserved as a hierarchy below sshx's private session directory, but absolute command arguments are not rewritten. RemoteFS does not expose special files/xattrs/ACLs or support Docker targets, FUSE-T, or FSKit. It is optimized for source trees and small files rather than large-file throughput.
75
136
 
76
137
  ### 🔌 Automatic Port Detection & Forwarding
77
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hahahhh/sshx",
3
- "version": "0.0.4-rc.0",
3
+ "version": "0.0.4-rc.3",
4
4
  "type": "module",
5
5
  "description": "Transparent SSH enhancement wrapper for OpenSSH",
6
6
  "repository": {