@vibesdotdev/bin 1.0.0 → 1.0.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.
package/bin/vibes CHANGED
@@ -17,24 +17,94 @@
17
17
 
18
18
  const { spawnSync } = require('child_process');
19
19
  const fs = require('fs');
20
+ const os = require('os');
20
21
  const path = require('path');
21
22
 
22
23
  const binDir = __dirname;
24
+ const installerPath = path.join(binDir, '..', 'scripts', 'postinstall.js');
23
25
  const exePath = path.join(binDir, 'vibes.exe');
24
26
 
27
+ function getPersistentBinDir() {
28
+ if (process.env.VIBES_INSTALL_DIR) return process.env.VIBES_INSTALL_DIR;
29
+
30
+ const bunGlobalBin = readCommandOutput('bun', ['pm', 'bin', '-g']);
31
+ if (bunGlobalBin) return bunGlobalBin;
32
+
33
+ if (process.env.BUN_INSTALL) return path.join(process.env.BUN_INSTALL, 'bin');
34
+
35
+ if (process.platform === 'win32') {
36
+ const base = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
37
+ return path.join(base, 'Programs', 'vibes', 'bin');
38
+ }
39
+
40
+ if (process.env.XDG_BIN_HOME) return process.env.XDG_BIN_HOME;
41
+ return path.join(os.homedir(), '.local', 'bin');
42
+ }
43
+
44
+ function readCommandOutput(command, args) {
45
+ const result = spawnSync(command, args, {
46
+ encoding: 'utf8',
47
+ stdio: ['ignore', 'pipe', 'ignore'],
48
+ windowsHide: true
49
+ });
50
+ if (result.error || result.status !== 0) return undefined;
51
+ const value = result.stdout.trim();
52
+ return value.length > 0 ? value : undefined;
53
+ }
54
+
55
+ function getPersistentBinaryPath() {
56
+ return path.join(getPersistentBinDir(), process.platform === 'win32' ? 'vibes.exe' : 'vibes');
57
+ }
58
+
59
+ function runInstaller() {
60
+ const result = spawnSync(process.execPath, [installerPath], {
61
+ stdio: 'inherit',
62
+ windowsHide: false,
63
+ env: { ...process.env, VIBES_INSTALL_PERSISTENT: '1' }
64
+ });
65
+ if (result.error) {
66
+ process.stderr.write(`Failed to run installer: ${result.error.message}\n`);
67
+ process.exit(1);
68
+ }
69
+ if (result.status !== 0) {
70
+ process.exit(result.status === null ? 1 : result.status);
71
+ }
72
+ }
73
+
25
74
  function reportMissingBinary() {
26
75
  process.stderr.write('Error: vibes binary not installed.\n');
27
76
  process.stderr.write('\n');
28
- process.stderr.write('The postinstall script did not complete. To fix, re-run install:\n');
29
- process.stderr.write(' npm rebuild -g @vibesdotdev/bin\n');
30
- process.stderr.write(' or\n');
31
- process.stderr.write(' bun pm trust @vibesdotdev/bin && bun install -g @vibesdotdev/bin\n');
77
+ process.stderr.write('The installer could not place the platform binary.\n');
32
78
  process.stderr.write('\n');
33
79
  process.stderr.write('If the problem persists, see https://github.com/vibesdotdev/monorepo/issues\n');
34
80
  process.exit(1);
35
81
  }
36
82
 
83
+ function isStillNodeShim(filePath) {
84
+ try {
85
+ const content = fs.readFileSync(filePath, 'utf8');
86
+ return content.includes('Cross-platform launcher for the vibes CLI binary');
87
+ } catch {
88
+ return false;
89
+ }
90
+ }
91
+
37
92
  if (process.platform === 'win32') {
93
+ const persistentPath = getPersistentBinaryPath();
94
+ if (fs.existsSync(persistentPath)) {
95
+ const result = spawnSync(persistentPath, process.argv.slice(2), {
96
+ stdio: 'inherit',
97
+ windowsHide: false
98
+ });
99
+ if (result.error) {
100
+ process.stderr.write(`Failed to spawn ${persistentPath}: ${result.error.message}\n`);
101
+ process.exit(1);
102
+ }
103
+ process.exit(result.status === null ? 1 : result.status);
104
+ }
105
+ if (!fs.existsSync(exePath)) {
106
+ runInstaller();
107
+ }
38
108
  if (!fs.existsSync(exePath)) {
39
109
  reportMissingBinary();
40
110
  }
@@ -49,6 +119,31 @@ if (process.platform === 'win32') {
49
119
  process.exit(result.status === null ? 1 : result.status);
50
120
  }
51
121
 
52
- // On macOS/Linux, postinstall is expected to have replaced this file with the
53
- // actual binary. If we get here, the replacement never happened.
54
- reportMissingBinary();
122
+ const persistentPath = getPersistentBinaryPath();
123
+ if (fs.existsSync(persistentPath) && !isStillNodeShim(persistentPath)) {
124
+ const result = spawnSync(persistentPath, process.argv.slice(2), {
125
+ stdio: 'inherit',
126
+ windowsHide: false
127
+ });
128
+ if (result.error) {
129
+ process.stderr.write(`Failed to spawn ${persistentPath}: ${result.error.message}\n`);
130
+ process.exit(1);
131
+ }
132
+ process.exit(result.status === null ? 1 : result.status);
133
+ }
134
+
135
+ runInstaller();
136
+
137
+ if (!fs.existsSync(persistentPath) || isStillNodeShim(persistentPath)) {
138
+ reportMissingBinary();
139
+ }
140
+
141
+ const result = spawnSync(persistentPath, process.argv.slice(2), {
142
+ stdio: 'inherit',
143
+ windowsHide: false
144
+ });
145
+ if (result.error) {
146
+ process.stderr.write(`Failed to spawn vibes: ${result.error.message}\n`);
147
+ process.exit(1);
148
+ }
149
+ process.exit(result.status === null ? 1 : result.status);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibesdotdev/bin",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Vibes CLI - the command-line interface for the Vibes platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -3,6 +3,7 @@
3
3
  const https = require('https');
4
4
  const http = require('http');
5
5
  const crypto = require('crypto');
6
+ const { spawnSync } = require('child_process');
6
7
  const fs = require('fs');
7
8
  const path = require('path');
8
9
  const os = require('os');
@@ -33,11 +34,56 @@ function getBinaryName() {
33
34
 
34
35
  function getOutputPath() {
35
36
  const platform = getPlatform();
37
+ if (process.env.VIBES_INSTALL_PERSISTENT === '1') {
38
+ const dir = getPersistentBinDir();
39
+ const outputName = platform === 'win32' ? 'vibes.exe' : 'vibes';
40
+ return path.join(dir, outputName);
41
+ }
36
42
  const dir = path.join(__dirname, '..', 'bin');
37
43
  const outputName = platform === 'win32' ? 'vibes.exe' : 'vibes';
38
44
  return path.join(dir, outputName);
39
45
  }
40
46
 
47
+ function getPersistentBinDir() {
48
+ if (process.env.VIBES_INSTALL_DIR) return process.env.VIBES_INSTALL_DIR;
49
+
50
+ const bunGlobalBin = readCommandOutput('bun', ['pm', 'bin', '-g']);
51
+ if (bunGlobalBin) return bunGlobalBin;
52
+
53
+ if (process.env.BUN_INSTALL) return path.join(process.env.BUN_INSTALL, 'bin');
54
+
55
+ if (process.platform === 'win32') {
56
+ const base = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
57
+ return path.join(base, 'Programs', 'vibes', 'bin');
58
+ }
59
+
60
+ if (process.env.XDG_BIN_HOME) return process.env.XDG_BIN_HOME;
61
+
62
+ // POSIX fallback used by Linux distributions and many shell setups. If it is
63
+ // not on PATH, the installer prints a warning with the exact directory.
64
+ return path.join(os.homedir(), '.local', 'bin');
65
+ }
66
+
67
+ function readCommandOutput(command, args) {
68
+ const result = spawnSync(command, args, {
69
+ encoding: 'utf8',
70
+ stdio: ['ignore', 'pipe', 'ignore'],
71
+ windowsHide: true
72
+ });
73
+ if (result.error || result.status !== 0) return undefined;
74
+ const value = result.stdout.trim();
75
+ return value.length > 0 ? value : undefined;
76
+ }
77
+
78
+ function pathHasDir(dir) {
79
+ const pathValue = process.env.PATH || '';
80
+ const resolvedDir = path.resolve(dir);
81
+ return pathValue
82
+ .split(path.delimiter)
83
+ .filter(Boolean)
84
+ .some((entry) => path.resolve(entry) === resolvedDir);
85
+ }
86
+
41
87
  function showProgress(total, current) {
42
88
  if (total > 0) {
43
89
  const percent = Math.round((current / total) * 100);
@@ -244,6 +290,10 @@ async function main() {
244
290
  .then(() => {
245
291
  makeExecutable(outputPath);
246
292
  console.log(`Installed to ${outputPath}`);
293
+ const outputDir = path.dirname(outputPath);
294
+ if (process.env.VIBES_INSTALL_PERSISTENT === '1' && !pathHasDir(outputDir)) {
295
+ console.warn(`Warning: ${outputDir} is not on PATH. Add it to run \`vibes\` directly.`);
296
+ }
247
297
  resolve();
248
298
  })
249
299
  .catch(reject);