@factadev/cli 0.2.11 → 0.2.13

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/nest.cjs +108 -69
  2. package/package.json +6 -6
package/bin/nest.cjs CHANGED
@@ -1,99 +1,138 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * NEST CLI launcher resolves and runs the platform-specific binary.
4
- * npm install @factadev/cli installs one optional dependency matching this machine
5
- * (os/cpu); this script finds that binary and execs it. No runtime npm install.
6
- */
7
- const { execFileSync } = require('child_process');
2
+
3
+ const { execFileSync, execSync } = require('child_process');
8
4
  const path = require('path');
9
5
  const fs = require('fs');
10
6
 
11
7
  const platform = process.platform;
12
8
  const arch = process.arch;
13
-
14
9
  const RELEASE_URL = 'https://github.com/Facta-Dev/ctx0_nest/releases';
15
-
16
- // Map Node platform/arch to our package suffix (must match @factadev/cli-<name>)
17
- const PLATFORM_MAP = [
18
- { os: 'darwin', cpu: 'arm64', key: 'darwin-arm64' },
19
- { os: 'darwin', cpu: 'x64', key: 'darwin-x64' },
20
- { os: 'linux', cpu: 'arm64', key: 'linux-arm64' },
21
- { os: 'linux', cpu: 'x64', key: 'linux-x64' },
22
- { os: 'win32', cpu: 'x64', key: 'win32-x64' },
10
+ const SUPPORTED_PLATFORMS = [
11
+ { key: 'darwin-arm64', label: 'darwin-arm64 (macOS Apple Silicon)' },
12
+ { key: 'darwin-x64', label: 'darwin-x64 (macOS Intel)' },
13
+ { key: 'linux-arm64', label: 'linux-arm64' },
14
+ { key: 'linux-x64', label: 'linux-x64' },
15
+ { key: 'win32-x64', label: 'win32-x64' },
23
16
  ];
24
17
 
25
- function getPlatformKey() {
26
- const entry = PLATFORM_MAP.find(
27
- (e) => e.os === platform && e.cpu === arch
28
- );
29
- return entry ? entry.key : null;
18
+ function getPlatformKey(p = platform, a = arch) {
19
+ return `${p}-${a}`;
30
20
  }
31
21
 
32
- function getBinaryPath() {
33
- const platformKey = getPlatformKey();
34
- if (!platformKey) return null;
35
-
36
- const pkgName = `@factadev/cli-${platformKey}`;
37
- const binName = platform === 'win32' ? 'nest.exe' : 'nest';
38
-
39
- // Main package root (where this script lives: .../bin/nest.cjs)
40
- const mainRoot = path.resolve(__dirname, '..');
22
+ function isSupportedPlatform(p = platform, a = arch) {
23
+ return SUPPORTED_PLATFORMS.some(item => item.key === getPlatformKey(p, a));
24
+ }
41
25
 
42
- const candidates = [
43
- // 1. Optional dep nested under main package (npm/yarn typical)
44
- path.join(mainRoot, 'node_modules', pkgName, 'bin', binName),
45
- // 2. Sibling under same scope (global npm: .../node_modules/@factadev/cli, .../cli-*)
46
- path.join(mainRoot, '..', `cli-${platformKey}`, 'bin', binName),
47
- // 3. Unix global: PREFIX/lib/node_modules/@factadev/cli-*
48
- path.join(
49
- process.env.npm_config_prefix || process.env.PREFIX || '/usr/local',
50
- 'lib',
51
- 'node_modules',
52
- pkgName,
53
- 'bin',
54
- binName
55
- ),
56
- // 4. Windows global (prefix often = npm dir with node_modules)
57
- path.join(
58
- process.env.npm_config_prefix ||
59
- path.join(process.env.APPDATA || '', 'npm'),
60
- 'node_modules',
61
- pkgName,
62
- 'bin',
63
- binName
64
- ),
26
+ function getBinaryPath(platformName = platform, archName = arch) {
27
+ const pkgName = `@factadev/cli-${platformName}-${archName}`;
28
+ const binName = platformName === 'win32' ? 'nest.exe' : 'nest';
29
+
30
+ // Try multiple locations where the package might be installed
31
+ const possiblePaths = [
32
+ // 1. Top-level node_modules (if installed separately)
33
+ path.join(__dirname, '..', '..', pkgName, 'bin', binName),
34
+ // 2. Inside @factadev/cli/node_modules (if installed as optional dep)
35
+ path.join(__dirname, '..', 'node_modules', pkgName, 'bin', binName),
36
+ // 3. Global node_modules
37
+ path.join(process.env.PREFIX || '/usr/local', 'lib', 'node_modules', pkgName, 'bin', binName),
65
38
  ];
39
+
40
+ for (const binPath of possiblePaths) {
41
+ if (fs.existsSync(binPath)) {
42
+ return binPath;
43
+ }
44
+ }
45
+
46
+ return null;
47
+ }
66
48
 
67
- for (const binPath of candidates) {
68
- if (fs.existsSync(binPath)) return binPath;
49
+ function installPlatformPackage(platformName = platform, archName = arch) {
50
+ const pkgName = `@factadev/cli-${platformName}-${archName}`;
51
+ console.log(`Installing ${pkgName}...`);
52
+ try {
53
+ execSync(`npm install -g ${pkgName}`, { stdio: 'inherit' });
54
+ return true;
55
+ } catch (e) {
56
+ return false;
57
+ }
58
+ }
59
+
60
+ function getInstalledVersion(platformName = platform, archName = arch) {
61
+ const binPath = getBinaryPath(platformName, archName);
62
+ if (binPath) {
63
+ return 'installed';
69
64
  }
70
65
  return null;
71
66
  }
72
67
 
68
+ function getLatestVersion(platformName = platform, archName = arch) {
69
+ const pkgName = `@factadev/cli-${platformName}-${archName}`;
70
+ try {
71
+ const result = execSync(`npm view ${pkgName} version`, { encoding: 'utf8' });
72
+ return result.trim();
73
+ } catch (e) {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ function getBunPath() {
79
+ const bunPaths = [
80
+ path.join(__dirname, '..', 'node_modules', '.bin', 'bun'),
81
+ path.join(process.env.HOME || '', '.bun', 'bin', 'bun'),
82
+ path.join(process.env.APPDATA || '', 'bun', 'bin', 'bun.exe'),
83
+ '/usr/local/bin/bun',
84
+ '/opt/homebrew/bin/bun',
85
+ ];
86
+ for (const p of bunPaths) {
87
+ try { fs.accessSync(p, fs.constants.X_OK); return p; } catch {}
88
+ }
89
+ return 'bun';
90
+ }
91
+
73
92
  function main() {
74
- const platformKey = getPlatformKey();
75
- if (!platformKey) {
76
- console.error(
77
- `Unsupported platform: ${platform}-${arch}. Supported: darwin-arm64, darwin-x64, linux-arm64, linux-x64, win32-x64.`
78
- );
79
- console.error(`See ${RELEASE_URL}`);
93
+ if (!isSupportedPlatform()) {
94
+ console.error(`Unsupported platform: ${platform}-${arch}`);
80
95
  process.exit(1);
81
96
  }
82
97
 
83
- const binPath = getBinaryPath();
98
+ const platformKey = getPlatformKey();
99
+ let binPath = getBinaryPath();
100
+
101
+ // Check if platform package needs update or install
84
102
  if (!binPath) {
85
- console.error(
86
- `Platform binary not found for ${platformKey}. Reinstall so npm can fetch the matching optional dependency:`
87
- );
88
- console.error(' npm install -g @factadev/cli');
89
- console.error('Or download the binary manually from:', RELEASE_URL);
90
- process.exit(1);
103
+ console.log('No platform binary found. Installing...');
104
+ installPlatformPackage();
105
+ binPath = getBinaryPath();
106
+ } else {
107
+ // Check version and update if needed (optional)
108
+ const currentVer = getInstalledVersion();
109
+ const latestVer = getLatestVersion();
110
+ if (currentVer && latestVer && currentVer !== latestVer) {
111
+ console.log(`Updating to v${latestVer}...`);
112
+ installPlatformPackage();
113
+ binPath = getBinaryPath();
114
+ }
115
+ }
116
+
117
+ // Fallback to bun if no binary
118
+ if (!binPath) {
119
+ const bunPath = getBunPath();
120
+ const cliPath = path.join(__dirname, '..', 'src', 'index.ts');
121
+ console.log('No pre-built binary. Using bun...\n');
122
+ try {
123
+ execFileSync(bunPath, [cliPath, ...process.argv.slice(2)], { stdio: 'inherit' });
124
+ return;
125
+ } catch (error) {
126
+ console.error(`Failed to run with bun: ${error.message}`);
127
+ process.exit(1);
128
+ }
91
129
  }
92
130
 
131
+ // Run the binary
93
132
  try {
94
133
  execFileSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
95
- } catch (err) {
96
- process.exit(typeof err.status === 'number' ? err.status : 1);
134
+ } catch (error) {
135
+ process.exit(error.status || 1);
97
136
  }
98
137
  }
99
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factadev/cli",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "NEST CLI - Enterprise AI coding agent control center. Run Claude Code, Codex, Cursor, Gemini, OpenCode locally and control remotely via web.",
5
5
  "author": "Carlos Matias Baglieri",
6
6
  "license": "AGPL-3.0-only",
@@ -20,10 +20,10 @@
20
20
  "NOTICE"
21
21
  ],
22
22
  "optionalDependencies": {
23
- "@factadev/cli-darwin-arm64": "0.2.11",
24
- "@factadev/cli-darwin-x64": "0.2.11",
25
- "@factadev/cli-linux-arm64": "0.2.11",
26
- "@factadev/cli-linux-x64": "0.2.11",
27
- "@factadev/cli-win32-x64": "0.2.11"
23
+ "@factadev/cli-darwin-arm64": "0.2.10",
24
+ "@factadev/cli-darwin-x64": "0.2.10",
25
+ "@factadev/cli-linux-arm64": "0.2.10",
26
+ "@factadev/cli-linux-x64": "0.2.10",
27
+ "@factadev/cli-win32-x64": "0.2.10"
28
28
  }
29
29
  }