pi-bridge 0.2.9 → 0.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-bridge",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "description": "Transparent filesystem bridge that makes pi run natively on a remote machine over SSH",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -5,19 +5,18 @@ const path = require('path');
5
5
  const { isFakePath, toRemotePath } = require('./path-mapper');
6
6
 
7
7
  /**
8
- * Patch child_process.spawn and child_process.spawnSync so that commands
8
+ * Patch child_process spawn/spawnSync/execSync/execFileSync so that commands
9
9
  * whose cwd lands inside fakeRoot are transparently redirected to run on
10
10
  * the remote machine via SSH.
11
11
  *
12
- * Pi's bash tool uses spawn/spawnSync exclusively, so this covers all shell
13
- * command execution (ls, cat, grep, npm run, etc.).
14
- *
15
12
  * @param {string} fakeRoot - Local fake root directory (real path, no symlinks)
16
13
  * @param {string} remote - SSH target, e.g. 'user@host'
17
14
  */
18
15
  function patchChildProcess(fakeRoot, remote) {
19
- const origSpawn = cp.spawn.bind(cp);
20
- const origSpawnSync = cp.spawnSync.bind(cp);
16
+ const origSpawn = cp.spawn.bind(cp);
17
+ const origSpawnSync = cp.spawnSync.bind(cp);
18
+ const origExecSync = cp.execSync.bind(cp);
19
+ const origExecFileSync = cp.execFileSync.bind(cp);
21
20
 
22
21
  /**
23
22
  * Resolve the effective cwd from spawn options.
@@ -44,6 +43,7 @@ function patchChildProcess(fakeRoot, remote) {
44
43
  * - node / node.exe: pi's internal tooling (session export, compaction, …)
45
44
  * spawns Node with large payloads as args; redirecting those over SSH would
46
45
  * produce an ENAMETOOLONG error on Windows and is never correct anyway.
46
+ * - pi / pii: need local internet access for the Claude API and auth.
47
47
  */
48
48
  function isLocalOnly(file) {
49
49
  const name = normalizeCmd(file).toLowerCase();
@@ -51,15 +51,14 @@ function patchChildProcess(fakeRoot, remote) {
51
51
  }
52
52
 
53
53
  /**
54
- * Build the SSH-redirected command: cd to remote cwd, then run the
55
- * original command with its arguments, all shell-quoted.
54
+ * Build SSH args for a file + args invocation:
55
+ * cd to remote cwd, then run the command with shell-quoted arguments.
56
56
  */
57
57
  function buildSshArgs(file, args, opts) {
58
58
  file = normalizeCmd(file);
59
- const fakeCwd = effectiveCwd(opts);
60
- const remoteCwd = toRemotePath(fakeCwd, fakeRoot);
59
+ const fakeCwd = effectiveCwd(opts);
60
+ const remoteCwd = toRemotePath(fakeCwd, fakeRoot);
61
61
 
62
- // Reconstruct the command string with shell-safe quoting
63
62
  const argStr = (args || [])
64
63
  .map(function(a) { return "'" + String(a).replace(/'/g, "'\\''") + "'"; })
65
64
  .join(' ');
@@ -68,10 +67,19 @@ function patchChildProcess(fakeRoot, remote) {
68
67
  return ['-o', 'BatchMode=yes', remote, remoteCmd];
69
68
  }
70
69
 
70
+ /**
71
+ * Build SSH args for a raw shell command string (used by execSync).
72
+ */
73
+ function buildSshArgsForShell(command, opts) {
74
+ const fakeCwd = effectiveCwd(opts);
75
+ const remoteCwd = toRemotePath(fakeCwd, fakeRoot);
76
+ const remoteCmd = 'cd ' + JSON.stringify(remoteCwd) + ' && ' + command;
77
+ return ['-o', 'BatchMode=yes', remote, remoteCmd];
78
+ }
79
+
71
80
  // ── spawn ────────────────────────────────────────────────────────────────────
72
81
 
73
82
  cp.spawn = function patchedSpawn(file, args, opts) {
74
- // Normalise overloaded signature: spawn(file) / spawn(file, opts) / spawn(file, args, opts)
75
83
  if (!Array.isArray(args)) { opts = args; args = []; }
76
84
  opts = opts || {};
77
85
 
@@ -92,6 +100,29 @@ function patchChildProcess(fakeRoot, remote) {
92
100
 
93
101
  return origSpawnSync('ssh', buildSshArgs(file, args, opts), Object.assign({}, opts, { cwd: undefined }));
94
102
  };
103
+
104
+ // ── execSync ─────────────────────────────────────────────────────────────────
105
+
106
+ cp.execSync = function patchedExecSync(command, opts) {
107
+ opts = opts || {};
108
+
109
+ const cwd = effectiveCwd(opts);
110
+ if (!isFakePath(cwd, fakeRoot)) return origExecSync(command, opts);
111
+
112
+ return origExecFileSync('ssh', buildSshArgsForShell(command, opts), Object.assign({}, opts, { cwd: undefined }));
113
+ };
114
+
115
+ // ── execFileSync ─────────────────────────────────────────────────────────────
116
+
117
+ cp.execFileSync = function patchedExecFileSync(file, args, opts) {
118
+ if (!Array.isArray(args)) { opts = args; args = []; }
119
+ opts = opts || {};
120
+
121
+ const cwd = effectiveCwd(opts);
122
+ if (!isFakePath(cwd, fakeRoot) || isLocalOnly(file)) return origExecFileSync(file, args, opts);
123
+
124
+ return origExecFileSync('ssh', buildSshArgs(file, args, opts), Object.assign({}, opts, { cwd: undefined }));
125
+ };
95
126
  }
96
127
 
97
128
  module.exports = { patchChildProcess };