@openagents-org/agent-connector 0.3.2 → 0.3.4

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/package.json +1 -1
  2. package/src/installer.js +47 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-connector",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Agent management CLI and library for OpenAgents — install, configure, and run AI coding agents",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/installer.js CHANGED
@@ -353,7 +353,18 @@ class Installer {
353
353
  const sep = process.platform === 'win32' ? ';' : ':';
354
354
  const extraDirs = [];
355
355
  try { extraDirs.push(path.dirname(process.execPath)); } catch {}
356
+
357
+ // Check for bundled Node.js in ~/.openagents/nodejs/
356
358
  if (process.platform === 'win32') {
359
+ try {
360
+ const bundledDir = path.join(this.configDir, 'nodejs');
361
+ if (fs.existsSync(bundledDir)) {
362
+ const entries = fs.readdirSync(bundledDir).filter(e => e.startsWith('node-'));
363
+ if (entries.length > 0) {
364
+ extraDirs.push(path.join(bundledDir, entries[0]));
365
+ }
366
+ }
367
+ } catch {}
357
368
  const appData = env.APPDATA || '';
358
369
  if (appData) extraDirs.push(path.join(appData, 'npm'));
359
370
  extraDirs.push(env.ProgramFiles ? path.join(env.ProgramFiles, 'nodejs') : 'C:\\Program Files\\nodejs');
@@ -374,7 +385,21 @@ class Installer {
374
385
  * Check if Node.js/npm is available on the system.
375
386
  */
376
387
  hasNodejs() {
377
- return !!whichBinary('node') && !!whichBinary('npm');
388
+ if (whichBinary('node') && whichBinary('npm')) return true;
389
+ // Check bundled Node.js in ~/.openagents/nodejs/
390
+ if (process.platform === 'win32') {
391
+ try {
392
+ const bundledDir = path.join(this.configDir, 'nodejs');
393
+ if (fs.existsSync(bundledDir)) {
394
+ const entries = fs.readdirSync(bundledDir).filter(e => e.startsWith('node-'));
395
+ if (entries.length > 0) {
396
+ const nodeExe = path.join(bundledDir, entries[0], 'node.exe');
397
+ return fs.existsSync(nodeExe);
398
+ }
399
+ }
400
+ } catch {}
401
+ }
402
+ return false;
378
403
  }
379
404
 
380
405
  /**
@@ -393,34 +418,42 @@ class Installer {
393
418
  if (onData) onData(`Node.js not found. Installing Node.js ${nodeVersion}...\n\n`);
394
419
 
395
420
  if (plat === 'windows') {
396
- // Download MSI installer and run silently
421
+ // Download portable zip no admin required
397
422
  const arch = os.arch() === 'x64' ? 'x64' : 'x86';
398
- const url = `https://nodejs.org/dist/${nodeVersion}/node-${nodeVersion}-${arch}.msi`;
399
- const msiPath = path.join(os.tmpdir(), `node-${nodeVersion}.msi`);
423
+ const url = `https://nodejs.org/dist/${nodeVersion}/node-${nodeVersion}-win-${arch}.zip`;
424
+ const zipPath = path.join(os.tmpdir(), `node-${nodeVersion}.zip`);
400
425
 
401
426
  if (onData) onData(`Downloading ${url}...\n`);
402
- await this._downloadFile(url, msiPath, onData);
427
+ await this._downloadFile(url, zipPath, onData);
428
+
429
+ // Extract to ~/.openagents/nodejs/
430
+ const nodejsDir = path.join(this.configDir, 'nodejs');
431
+ fs.mkdirSync(nodejsDir, { recursive: true });
403
432
 
404
- if (onData) onData(`\nInstalling Node.js (this may take a minute)...\n`);
433
+ if (onData) onData(`\nExtracting Node.js to ${nodejsDir}...\n`);
405
434
  await new Promise((resolve, reject) => {
406
- const proc = spawnProc('msiexec', ['/i', msiPath, '/quiet', '/norestart'], {
407
- stdio: ['ignore', 'pipe', 'pipe'],
408
- });
435
+ const proc = spawnProc('powershell', [
436
+ '-NoProfile', '-Command',
437
+ `Expand-Archive -Path '${zipPath}' -DestinationPath '${nodejsDir}' -Force`
438
+ ], { stdio: ['ignore', 'pipe', 'pipe'] });
409
439
  if (proc.stdout) proc.stdout.on('data', (d) => { if (onData) onData(d.toString()); });
410
440
  if (proc.stderr) proc.stderr.on('data', (d) => { if (onData) onData(d.toString()); });
411
441
  proc.on('error', reject);
412
442
  proc.on('close', (code) => {
413
443
  if (code === 0) resolve();
414
- else reject(new Error(`MSI installer exited with code ${code}`));
444
+ else reject(new Error(`Extraction failed with code ${code}`));
415
445
  });
416
446
  });
417
447
 
418
- // Add to PATH for this session
419
- const nodejsDir = path.join(process.env.ProgramFiles || 'C:\\Program Files', 'nodejs');
448
+ // The zip extracts to node-vX.X.X-win-x64/ subfolder
449
+ const extractedDir = path.join(nodejsDir, `node-${nodeVersion}-win-${arch}`);
420
450
  const sep = ';';
421
- if (!(process.env.PATH || '').includes(nodejsDir)) {
422
- process.env.PATH = nodejsDir + sep + (process.env.PATH || '');
451
+
452
+ // Add extracted node dir to PATH for this session
453
+ if (!(process.env.PATH || '').includes(extractedDir)) {
454
+ process.env.PATH = extractedDir + sep + (process.env.PATH || '');
423
455
  }
456
+ // npm global installs go to %APPDATA%\npm
424
457
  const npmGlobal = path.join(process.env.APPDATA || '', 'npm');
425
458
  if (npmGlobal && !(process.env.PATH || '').includes(npmGlobal)) {
426
459
  process.env.PATH = npmGlobal + sep + process.env.PATH;