pi-bridge 0.2.6 → 0.2.8
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.
- package/README.md +6 -2
- package/package.json +9 -1
- package/src/local/child-process-patch.js +1 -1
- package/src/local/fake-dir.js +25 -8
- package/src/local/preload.js +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ pii (bin/pii.js)
|
|
|
52
52
|
│ → prints PORT:TOKEN:PID to stdout
|
|
53
53
|
├─ SSH port forward localhost:PORT
|
|
54
54
|
├─ create fake local dir:
|
|
55
|
-
│
|
|
55
|
+
│ <home>/.pi-bridge/myserver/root/projects/my-app
|
|
56
56
|
├─ process.chdir(fakeLocalCwd)
|
|
57
57
|
├─ strip --ssh from process.argv
|
|
58
58
|
├─ patch fs.* (sync + promises) remote/index.js
|
|
@@ -67,6 +67,8 @@ pi loads — unaware of bridge restricts to remoteCwd
|
|
|
67
67
|
→ git branch in footer ✓
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
The fake local directory lives under `<home>/.pi-bridge/<remote>/` (not the OS temp directory) so it survives reboots and pi can always resume sessions correctly. On Windows this is `%USERPROFILE%\.pi-bridge\`; on macOS/Linux it is `~/.pi-bridge/`.
|
|
71
|
+
|
|
70
72
|
## What Gets Patched
|
|
71
73
|
|
|
72
74
|
| API | Covered |
|
|
@@ -77,6 +79,8 @@ pi loads — unaware of bridge restricts to remoteCwd
|
|
|
77
79
|
| `child_process.spawn` / `spawnSync` — runs in remote cwd via SSH | ✓ |
|
|
78
80
|
| `fs.watch` / `fs.watchFile` — polls remote via HTTP (git branch updates) | ✓ |
|
|
79
81
|
|
|
82
|
+
`node`, `pi`, and `pii` spawns are always kept local — they need internet access and must never be redirected over SSH.
|
|
83
|
+
|
|
80
84
|
## Security
|
|
81
85
|
|
|
82
86
|
| Layer | Protection |
|
|
@@ -117,7 +121,7 @@ Host myserver
|
|
|
117
121
|
```
|
|
118
122
|
|
|
119
123
|
**Files show as empty / ENOENT**
|
|
120
|
-
The fake local directory (
|
|
124
|
+
The fake local directory (`<home>/.pi-bridge/<remote>/…`) is intentionally empty — all reads go to the remote. If you see ENOENT, the bridge may not have started correctly. Check that Node.js is available on the remote (`node --version`).
|
|
121
125
|
|
|
122
126
|
**Branch name not updating**
|
|
123
127
|
The footer polls `.git` every second. Switching branches from outside a pi session is reflected within ~1s. If the branch is stuck, restart `pii`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-bridge",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Transparent filesystem bridge that makes pi run natively on a remote machine over SSH",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
"filesystem"
|
|
28
28
|
],
|
|
29
29
|
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/zeflq/pi-bridge.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/zeflq/pi-bridge#readme",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/zeflq/pi-bridge/issues"
|
|
37
|
+
},
|
|
30
38
|
"devDependencies": {
|
|
31
39
|
"vitest": "^2.0.0"
|
|
32
40
|
}
|
package/src/local/fake-dir.js
CHANGED
|
@@ -4,21 +4,37 @@ const fs = require('fs');
|
|
|
4
4
|
const os = require('os');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
|
+
// Capture rmSync before any monkey-patching so cleanup always hits the local
|
|
8
|
+
// filesystem rather than being redirected through the SSH bridge.
|
|
9
|
+
const origRmSync = fs.rmSync.bind(fs);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sanitise an SSH target string (user@host or alias) into a safe dir name.
|
|
13
|
+
*/
|
|
14
|
+
function sanitizeRemote(remote) {
|
|
15
|
+
return remote.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
/**
|
|
8
19
|
* Create the fake local directory skeleton for the given remote path.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
20
|
+
*
|
|
21
|
+
* The directory lives under ~/.pi-bridge/<remote>/ rather than the OS temp
|
|
22
|
+
* directory so it survives reboots — this prevents pi's session-cwd check
|
|
23
|
+
* from failing when it tries to resume a previous session whose cwd points
|
|
24
|
+
* at a directory that was cleaned up between runs.
|
|
11
25
|
*
|
|
12
26
|
* Example:
|
|
27
|
+
* remote = 'myserver'
|
|
13
28
|
* remoteCwd = '/root/project-x'
|
|
14
|
-
* fakeRoot = '
|
|
15
|
-
* fakeLocalCwd = '
|
|
29
|
+
* fakeRoot = '~/.pi-bridge/myserver'
|
|
30
|
+
* fakeLocalCwd = '~/.pi-bridge/myserver/root/project-x'
|
|
16
31
|
*
|
|
32
|
+
* @param {string} remote - SSH target, e.g. 'user@host' or alias
|
|
17
33
|
* @param {string} remoteCwd - Absolute remote path, e.g. '/root/project-x'
|
|
18
34
|
* @returns {{ fakeRoot: string, fakeLocalCwd: string }}
|
|
19
35
|
*/
|
|
20
|
-
function createFakeDir(remoteCwd) {
|
|
21
|
-
const fakeRootRaw = path.join(os.
|
|
36
|
+
function createFakeDir(remote, remoteCwd) {
|
|
37
|
+
const fakeRootRaw = path.join(os.homedir(), '.pi-bridge', sanitizeRemote(remote));
|
|
22
38
|
|
|
23
39
|
// Build the local mirror path from the remote path segments
|
|
24
40
|
const segments = remoteCwd.split('/').filter(Boolean);
|
|
@@ -36,13 +52,14 @@ function createFakeDir(remoteCwd) {
|
|
|
36
52
|
|
|
37
53
|
/**
|
|
38
54
|
* Remove the fake root directory and all its contents.
|
|
39
|
-
*
|
|
55
|
+
* Uses the captured original rmSync to ensure the local directory is removed
|
|
56
|
+
* even when this is called after fs has been monkey-patched by the bridge.
|
|
40
57
|
*
|
|
41
58
|
* @param {string} fakeRoot - Path returned by createFakeDir
|
|
42
59
|
*/
|
|
43
60
|
function removeFakeDir(fakeRoot) {
|
|
44
61
|
try {
|
|
45
|
-
|
|
62
|
+
origRmSync(fakeRoot, { recursive: true, force: true });
|
|
46
63
|
} catch (_) {
|
|
47
64
|
// Best-effort removal — do not throw during cleanup
|
|
48
65
|
}
|
package/src/local/preload.js
CHANGED
|
@@ -57,7 +57,7 @@ try {
|
|
|
57
57
|
const { port, token, sessionId, remotePid } = config;
|
|
58
58
|
|
|
59
59
|
// --- Step 3: Create fake local directory ---
|
|
60
|
-
const { fakeRoot, fakeLocalCwd } = createFakeDir(remoteCwd);
|
|
60
|
+
const { fakeRoot, fakeLocalCwd } = createFakeDir(remote, remoteCwd);
|
|
61
61
|
|
|
62
62
|
// --- Step 4: Change working directory to fake local cwd ---
|
|
63
63
|
process.chdir(fakeLocalCwd);
|