pi-bridge 0.3.1 → 0.3.2

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/bin/pii.js +49 -29
  2. package/package.json +1 -1
package/bin/pii.js CHANGED
@@ -14,37 +14,56 @@ if (process.argv.includes('--version') || process.argv.includes('-v') || process
14
14
  process.exit(0);
15
15
  }
16
16
 
17
- function findPi() {
18
- // 1. Standard npm global: both packages share the same node_modules prefix
19
- const shared = path.resolve(__dirname, '..', '..', '@mariozechner', 'pi-coding-agent', 'dist', 'cli.js');
20
- if (fs.existsSync(shared)) {
21
- return { cli: shared, nodeExe: process.execPath };
17
+ // List every `pi` on the PATH that pii inherited from its launching shell.
18
+ // We resolve against that PATH (not a fresh `-NoProfile` shell) so that bundled
19
+ // installs added to PATH via the user's profile are actually visible.
20
+ function locateOnPath(cmd) {
21
+ const finder = os.platform() === 'win32' ? 'where.exe' : 'which';
22
+ try {
23
+ const out = execFileSync(finder, [cmd], { encoding: 'utf8' });
24
+ return out.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
25
+ } catch (_) {
26
+ return [];
22
27
  }
28
+ }
23
29
 
24
- // 2. Unix GitHub clone: which pi returns the JS file directly
25
- if (os.platform() !== 'win32') {
26
- try {
27
- const wrapper = execFileSync('which', ['pi'], { encoding: 'utf8' }).trim();
28
- if (fs.existsSync(wrapper)) return { cli: wrapper, nodeExe: process.execPath };
29
- } catch (_) {}
30
+ function findPi() {
31
+ // 1. Standard npm global: pii and pi share the same node_modules prefix.
32
+ // Prefer the current @earendil-works scope; keep @mariozechner as a legacy
33
+ // fallback for machines that installed pi before it moved off that scope.
34
+ const sharedCandidates = [
35
+ path.resolve(__dirname, '..', '..', '@earendil-works', 'pi-coding-agent', 'dist', 'cli.js'),
36
+ path.resolve(__dirname, '..', '..', '@mariozechner', 'pi-coding-agent', 'dist', 'cli.js'),
37
+ ];
38
+ for (const cli of sharedCandidates) {
39
+ if (fs.existsSync(cli)) return { cli, nodeExe: process.execPath };
30
40
  }
31
41
 
32
- // 3. Fallback: PowerShell Get-Command — handles custom/bundled Windows installs
33
- // where pi lives outside the standard npm prefix. Also picks up the bundled
34
- // node.exe that shipped alongside pi (required for version-matched execution).
35
- if (os.platform() === 'win32') {
36
- try {
37
- const wrapper = execFileSync(
38
- 'powershell',
39
- ['-NoProfile', '-Command', '(Get-Command pi -ErrorAction Stop).Source'],
40
- { encoding: 'utf8' }
41
- ).trim();
42
- const basedir = path.dirname(wrapper);
43
- const cli = wrapper.replace(/\.(ps1|cmd)$/i, '.js');
44
- const localNode = path.join(basedir, 'node.exe');
45
- const nodeExe = fs.existsSync(localNode) ? localNode : process.execPath;
46
- if (fs.existsSync(cli)) return { cli, nodeExe };
47
- } catch (_) {}
42
+ // 2. Resolve `pi` from PATH and follow it to its real JS entrypoint. The
43
+ // pi.dev installer (curl https://pi.dev/install.sh | sh) drops a bundled
44
+ // Node plus a bare `bin/pi` symlink that points straight at the package's
45
+ // cli.js — often outside any npm prefix — so we realpath the symlink rather
46
+ // than guessing filenames. Also covers npm shims and dev clones (which
47
+ // expose pi as a symlink to cli.js too), and a bundled node next to pi is
48
+ // preferred for version-matched execution.
49
+ const exe = os.platform() === 'win32' ? '.exe' : '';
50
+ for (const cmd of locateOnPath('pi')) {
51
+ let real;
52
+ try { real = fs.realpathSync(cmd); } catch (_) { real = cmd; }
53
+
54
+ let cli = null;
55
+ if (/\.[cm]?js$/i.test(real) && fs.existsSync(real)) {
56
+ cli = real; // symlink/shim -> cli.js
57
+ } else if (fs.existsSync(path.join(path.dirname(cmd), 'pi.js'))) {
58
+ cli = path.join(path.dirname(cmd), 'pi.js'); // bundled wrapper + sibling
59
+ } else if (!/\.(cmd|ps1|bat|exe)$/i.test(real)) {
60
+ cli = real; // shebang JS with no extension
61
+ }
62
+ if (!cli) continue;
63
+
64
+ const localNode = path.join(path.dirname(cmd), 'node' + exe);
65
+ const nodeExe = fs.existsSync(localNode) ? localNode : process.execPath;
66
+ return { cli, nodeExe };
48
67
  }
49
68
 
50
69
  return null;
@@ -57,8 +76,9 @@ try {
57
76
 
58
77
  if (!pi) {
59
78
  process.stderr.write(
60
- 'pii: Could not find pi.\n' +
61
- 'Install it with: npm install -g @mariozechner/pi-coding-agent\n'
79
+ 'pii: Could not find pi on your PATH.\n' +
80
+ 'If pi is already installed, re-open your shell so the install is on PATH, then retry.\n' +
81
+ 'Otherwise install pi: curl -fsSL https://pi.dev/install.sh | sh\n'
62
82
  );
63
83
  process.exit(1);
64
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-bridge",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Transparent filesystem bridge that makes pi run natively on a remote machine over SSH",
5
5
  "type": "commonjs",
6
6
  "bin": {